Merge "confbridge: Add support for specifying maximum sample rate." into 13

This commit is contained in:
Friendly Automation
2019-12-19 09:55:22 -06:00
committed by Gerrit Code Review
8 changed files with 74 additions and 1 deletions

View File

@@ -1689,6 +1689,8 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
/* Set the internal sample rate on the bridge from the bridge profile */
ast_bridge_set_internal_sample_rate(conference->bridge, conference->b_profile.internal_sample_rate);
/* Set the maximum sample rate on the bridge from the bridge profile */
ast_bridge_set_maximum_sample_rate(conference->bridge, conference->b_profile.maximum_sample_rate);
/* Set the internal mixing interval on the bridge from the bridge profile */
ast_bridge_set_mixing_interval(conference->bridge, conference->b_profile.mix_interval);

View File

@@ -258,6 +258,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
will be used.
</para></description>
</configOption>
<configOption name="maximum_sample_rate">
<synopsis>Set the maximum native sample rate for mixing the conference</synopsis>
<description><para>
Sets the maximum native sample rate the
conference is mixed at. This is set to not have a
maximum by default. If a sample rate is specified,
though, the native sample rate will never exceed it.
</para></description>
</configOption>
<configOption name="language" default="en">
<synopsis>The language used for announcements to the conference.</synopsis>
<description><para>
@@ -1549,6 +1558,13 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e,
}
ast_cli(a->fd,"Internal Sample Rate: %s\n", tmp);
if (b_profile.maximum_sample_rate) {
snprintf(tmp, sizeof(tmp), "%u", b_profile.maximum_sample_rate);
} else {
ast_copy_string(tmp, "none", sizeof(tmp));
}
ast_cli(a->fd,"Maximum Sample Rate: %s\n", tmp);
if (b_profile.mix_interval) {
ast_cli(a->fd,"Mixing Interval: %u\n", b_profile.mix_interval);
} else {
@@ -2141,6 +2157,7 @@ int conf_load_config(void)
aco_option_register(&cfg_info, "jitterbuffer", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), USER_OPT_JITTERBUFFER);
/* "auto" will fail to parse as a uint, but we use PARSE_DEFAULT to set the value to 0 in that case, which is the value that auto resolves to */
aco_option_register(&cfg_info, "internal_sample_rate", ACO_EXACT, bridge_types, "0", OPT_UINT_T, PARSE_DEFAULT, FLDSET(struct bridge_profile, internal_sample_rate), 0);
aco_option_register(&cfg_info, "maximum_sample_rate", ACO_EXACT, bridge_types, "0", OPT_UINT_T, PARSE_DEFAULT, FLDSET(struct bridge_profile, maximum_sample_rate), 0);
aco_option_register_custom(&cfg_info, "mixing_interval", ACO_EXACT, bridge_types, "20", mix_interval_handler, 0);
aco_option_register(&cfg_info, "record_conference", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_RECORD_CONFERENCE);
aco_option_register_custom(&cfg_info, "video_mode", ACO_EXACT, bridge_types, NULL, video_mode_handler, 0);

View File

@@ -209,6 +209,7 @@ struct bridge_profile {
unsigned int flags;
unsigned int max_members; /*!< The maximum number of participants allowed in the conference */
unsigned int internal_sample_rate; /*!< The internal sample rate of the bridge. 0 when set to auto adjust mode. */
unsigned int maximum_sample_rate; /*!< The maximum sample rate of the bridge. 0 when set to no maximum. */
unsigned int mix_interval; /*!< The internal mixing interval used by the bridge. When set to 0 the bridgewill use a default interval. */
struct bridge_profile_sounds *sounds;
char regcontext[AST_MAX_CONTEXT];

View File

@@ -157,12 +157,16 @@ struct softmix_stats {
unsigned int num_channels[16];
/*! The number of channels above the internal sample rate */
unsigned int num_above_internal_rate;
/*! The number of channels above the maximum sample rate */
unsigned int num_above_maximum_rate;
/*! The number of channels at the internal sample rate */
unsigned int num_at_internal_rate;
/*! The absolute highest sample rate preferred by any channel in the bridge */
unsigned int highest_supported_rate;
/*! Is the sample rate locked by the bridge, if so what is that rate.*/
unsigned int locked_rate;
/*! The maximum sample rate the bridge may use */
unsigned int maximum_rate;
};
struct softmix_mixing_array {
@@ -884,7 +888,9 @@ static void gather_softmix_stats(struct softmix_stats *stats,
if (stats->highest_supported_rate < channel_native_rate) {
stats->highest_supported_rate = channel_native_rate;
}
if (softmix_data->internal_rate < channel_native_rate) {
if (stats->maximum_rate && stats->maximum_rate < channel_native_rate) {
stats->num_above_maximum_rate++;
} else if (softmix_data->internal_rate < channel_native_rate) {
int i;
for (i = 0; i < ARRAY_LEN(stats->sample_rates); i++) {
@@ -931,6 +937,15 @@ static unsigned int analyse_softmix_stats(struct softmix_stats *stats, struct so
softmix_data->internal_rate = stats->locked_rate;
return 1;
}
} else if (stats->num_above_maximum_rate) {
/* if the bridge has a maximum rate set and channels are above it only
* update if it differs from the current rate we are using. */
if (softmix_data->internal_rate != stats->maximum_rate) {
ast_debug(1, "Locking at new maximum rate. Bridge changed from %u to %u.\n",
softmix_data->internal_rate, stats->maximum_rate);
softmix_data->internal_rate = stats->maximum_rate;
return 1;
}
} else if (stats->num_above_internal_rate >= 2) {
/* the highest rate is just used as a starting point */
unsigned int best_rate = stats->highest_supported_rate;
@@ -1082,6 +1097,7 @@ static int softmix_mixing_loop(struct ast_bridge *bridge)
if (!stat_iteration_counter) {
memset(&stats, 0, sizeof(stats));
stats.locked_rate = bridge->softmix.internal_sample_rate;
stats.maximum_rate = bridge->softmix.maximum_sample_rate;
}
/* If the sample rate has changed, update the translator helper */

View File

@@ -185,6 +185,10 @@ type=bridge
; closest sample rate Asterisk does support to the one requested
; will be used.
;maximum_sample_rate=none ; Sets the maximum sample rate the conference
; is mixed at. This is set to no maximum by default.
; Values can be anything from 8000-192000.
;mixing_interval=40 ; Sets the internal mixing interval in milliseconds for the bridge. This
; number reflects how tight or loose the mixing will be for the conference.
; In order to improve performance a larger mixing interval such as 40ms may

View File

@@ -0,0 +1,5 @@
Subject: app_confbridge
A new bridge profile option, maximum_sample_rate, has been added which sets
a maximum sample rate that the bridge will be mixed at. This allows the bridge
to move below the maximum sample rate as needed but caps it at the maximum.

View File

@@ -263,6 +263,12 @@ struct ast_bridge_softmix {
* for itself.
*/
unsigned int internal_mixing_interval;
/*!
* \brief The maximum sample rate softmix uses to mix channels.
*
* \note If this value is 0, there is no maximum sample rate.
*/
unsigned int maximum_sample_rate;
};
/*!
@@ -859,6 +865,21 @@ int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_
*/
void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate);
/*!
* \brief Adjust the maximum mixing sample rate of a bridge
* used during multimix mode.
* \since 13.31.0
* \since 16.8.0
* \since 17.2.0
*
* \param bridge Channel to change the sample rate on.
* \param sample_rate the maximum sample rate to use. If a
* value of 0 is passed here, the bridge will be free to pick
* what ever sample rate it chooses.
*
*/
void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate);
/*!
* \brief Adjust the internal mixing interval of a bridge used
* during multimix mode.

View File

@@ -3750,6 +3750,13 @@ void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int
ast_bridge_unlock(bridge);
}
void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
{
ast_bridge_lock(bridge);
bridge->softmix.maximum_sample_rate = sample_rate;
ast_bridge_unlock(bridge);
}
static void cleanup_video_mode(struct ast_bridge *bridge)
{
switch (bridge->softmix.video_mode.mode) {