<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13441">View Change</a></p><div style="white-space:pre-wrap">Approvals:
George Joseph: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">confbridge: Add support for specifying maximum sample rate.<br><br>ConfBridge has the ability to move between different sample<br>rates for mixing the conference bridge. Up until now there has<br>only been the ability to set the conference bridge to mix at<br>a specific sample rate, or to let it move between sample rates<br>as necessary. This change adds the ability to configure a<br>conference bridge with a maximum sample rate so it can move<br>between sample rates but only up to the configured maximum.<br><br>ASTERISK-28658<br><br>Change-Id: Idff80896ccfb8a58a816e4ce9ac4ebde785963ee<br>---<br>M apps/app_confbridge.c<br>M apps/confbridge/conf_config_parser.c<br>M apps/confbridge/include/confbridge.h<br>M bridges/bridge_softmix.c<br>M configs/samples/confbridge.conf.sample<br>A doc/CHANGES-staging/app_confbridge_maximum_sample_rate.txt<br>M include/asterisk/bridge.h<br>M main/bridge.c<br>8 files changed, 74 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c</span><br><span>index 21a493c..8a9005e 100644</span><br><span>--- a/apps/app_confbridge.c</span><br><span>+++ b/apps/app_confbridge.c</span><br><span>@@ -1689,6 +1689,8 @@</span><br><span> </span><br><span> /* Set the internal sample rate on the bridge from the bridge profile */</span><br><span> ast_bridge_set_internal_sample_rate(conference->bridge, conference->b_profile.internal_sample_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Set the maximum sample rate on the bridge from the bridge profile */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_bridge_set_maximum_sample_rate(conference->bridge, conference->b_profile.maximum_sample_rate);</span><br><span> /* Set the internal mixing interval on the bridge from the bridge profile */</span><br><span> ast_bridge_set_mixing_interval(conference->bridge, conference->b_profile.mix_interval);</span><br><span> </span><br><span>diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c</span><br><span>index 9486260..87011c0 100644</span><br><span>--- a/apps/confbridge/conf_config_parser.c</span><br><span>+++ b/apps/confbridge/conf_config_parser.c</span><br><span>@@ -258,6 +258,15 @@</span><br><span> will be used.</span><br><span> </para></description></span><br><span> </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+ <configOption name="maximum_sample_rate"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis>Set the maximum native sample rate for mixing the conference</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <description><para></span><br><span style="color: hsl(120, 100%, 40%);">+ Sets the maximum native sample rate the</span><br><span style="color: hsl(120, 100%, 40%);">+ conference is mixed at. This is set to not have a</span><br><span style="color: hsl(120, 100%, 40%);">+ maximum by default. If a sample rate is specified,</span><br><span style="color: hsl(120, 100%, 40%);">+ though, the native sample rate will never exceed it.</span><br><span style="color: hsl(120, 100%, 40%);">+ </para></description></span><br><span style="color: hsl(120, 100%, 40%);">+ </configOption></span><br><span> <configOption name="language" default="en"></span><br><span> <synopsis>The language used for announcements to the conference.</synopsis></span><br><span> <description><para></span><br><span>@@ -1549,6 +1558,13 @@</span><br><span> }</span><br><span> ast_cli(a->fd,"Internal Sample Rate: %s\n", tmp);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (b_profile.maximum_sample_rate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(tmp, sizeof(tmp), "%u", b_profile.maximum_sample_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_copy_string(tmp, "none", sizeof(tmp));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(a->fd,"Maximum Sample Rate: %s\n", tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (b_profile.mix_interval) {</span><br><span> ast_cli(a->fd,"Mixing Interval: %u\n", b_profile.mix_interval);</span><br><span> } else {</span><br><span>@@ -2141,6 +2157,7 @@</span><br><span> aco_option_register(&cfg_info, "jitterbuffer", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), USER_OPT_JITTERBUFFER);</span><br><span> /* "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 */</span><br><span> 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);</span><br><span style="color: hsl(120, 100%, 40%);">+ 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);</span><br><span> aco_option_register_custom(&cfg_info, "mixing_interval", ACO_EXACT, bridge_types, "20", mix_interval_handler, 0);</span><br><span> 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);</span><br><span> aco_option_register_custom(&cfg_info, "video_mode", ACO_EXACT, bridge_types, NULL, video_mode_handler, 0);</span><br><span>diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h</span><br><span>index a29b363..6cf2d70 100644</span><br><span>--- a/apps/confbridge/include/confbridge.h</span><br><span>+++ b/apps/confbridge/include/confbridge.h</span><br><span>@@ -209,6 +209,7 @@</span><br><span> unsigned int flags;</span><br><span> unsigned int max_members; /*!< The maximum number of participants allowed in the conference */</span><br><span> unsigned int internal_sample_rate; /*!< The internal sample rate of the bridge. 0 when set to auto adjust mode. */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int maximum_sample_rate; /*!< The maximum sample rate of the bridge. 0 when set to no maximum. */</span><br><span> unsigned int mix_interval; /*!< The internal mixing interval used by the bridge. When set to 0 the bridgewill use a default interval. */</span><br><span> struct bridge_profile_sounds *sounds;</span><br><span> char regcontext[AST_MAX_CONTEXT];</span><br><span>diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c</span><br><span>index 0febc46..ac4e357 100644</span><br><span>--- a/bridges/bridge_softmix.c</span><br><span>+++ b/bridges/bridge_softmix.c</span><br><span>@@ -157,12 +157,16 @@</span><br><span> unsigned int num_channels[16];</span><br><span> /*! The number of channels above the internal sample rate */</span><br><span> unsigned int num_above_internal_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! The number of channels above the maximum sample rate */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num_above_maximum_rate;</span><br><span> /*! The number of channels at the internal sample rate */</span><br><span> unsigned int num_at_internal_rate;</span><br><span> /*! The absolute highest sample rate preferred by any channel in the bridge */</span><br><span> unsigned int highest_supported_rate;</span><br><span> /*! Is the sample rate locked by the bridge, if so what is that rate.*/</span><br><span> unsigned int locked_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! The maximum sample rate the bridge may use */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int maximum_rate;</span><br><span> };</span><br><span> </span><br><span> struct softmix_mixing_array {</span><br><span>@@ -884,7 +888,9 @@</span><br><span> if (stats->highest_supported_rate < channel_native_rate) {</span><br><span> stats->highest_supported_rate = channel_native_rate;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- if (softmix_data->internal_rate < channel_native_rate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stats->maximum_rate && stats->maximum_rate < channel_native_rate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ stats->num_above_maximum_rate++;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (softmix_data->internal_rate < channel_native_rate) {</span><br><span> int i;</span><br><span> </span><br><span> for (i = 0; i < ARRAY_LEN(stats->sample_rates); i++) {</span><br><span>@@ -931,6 +937,15 @@</span><br><span> softmix_data->internal_rate = stats->locked_rate;</span><br><span> return 1;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (stats->num_above_maximum_rate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* if the bridge has a maximum rate set and channels are above it only</span><br><span style="color: hsl(120, 100%, 40%);">+ * update if it differs from the current rate we are using. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (softmix_data->internal_rate != stats->maximum_rate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_debug(1, "Locking at new maximum rate. Bridge changed from %u to %u.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ softmix_data->internal_rate, stats->maximum_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+ softmix_data->internal_rate = stats->maximum_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> } else if (stats->num_above_internal_rate >= 2) {</span><br><span> /* the highest rate is just used as a starting point */</span><br><span> unsigned int best_rate = stats->highest_supported_rate;</span><br><span>@@ -1082,6 +1097,7 @@</span><br><span> if (!stat_iteration_counter) {</span><br><span> memset(&stats, 0, sizeof(stats));</span><br><span> stats.locked_rate = bridge->softmix.internal_sample_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+ stats.maximum_rate = bridge->softmix.maximum_sample_rate;</span><br><span> }</span><br><span> </span><br><span> /* If the sample rate has changed, update the translator helper */</span><br><span>diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample</span><br><span>index 4918fef..19b6559 100644</span><br><span>--- a/configs/samples/confbridge.conf.sample</span><br><span>+++ b/configs/samples/confbridge.conf.sample</span><br><span>@@ -185,6 +185,10 @@</span><br><span> ; closest sample rate Asterisk does support to the one requested</span><br><span> ; will be used.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+;maximum_sample_rate=none ; Sets the maximum sample rate the conference</span><br><span style="color: hsl(120, 100%, 40%);">+ ; is mixed at. This is set to no maximum by default.</span><br><span style="color: hsl(120, 100%, 40%);">+ ; Values can be anything from 8000-192000.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ;mixing_interval=40 ; Sets the internal mixing interval in milliseconds for the bridge. This</span><br><span> ; number reflects how tight or loose the mixing will be for the conference.</span><br><span> ; In order to improve performance a larger mixing interval such as 40ms may</span><br><span>diff --git a/doc/CHANGES-staging/app_confbridge_maximum_sample_rate.txt b/doc/CHANGES-staging/app_confbridge_maximum_sample_rate.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..1c584fa</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_confbridge_maximum_sample_rate.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: app_confbridge</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+A new bridge profile option, maximum_sample_rate, has been added which sets</span><br><span style="color: hsl(120, 100%, 40%);">+a maximum sample rate that the bridge will be mixed at. This allows the bridge</span><br><span style="color: hsl(120, 100%, 40%);">+to move below the maximum sample rate as needed but caps it at the maximum.</span><br><span>diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h</span><br><span>index 6349a8c..8aae6c7 100644</span><br><span>--- a/include/asterisk/bridge.h</span><br><span>+++ b/include/asterisk/bridge.h</span><br><span>@@ -263,6 +263,12 @@</span><br><span> * for itself.</span><br><span> */</span><br><span> unsigned int internal_mixing_interval;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief The maximum sample rate softmix uses to mix channels.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note If this value is 0, there is no maximum sample rate.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int maximum_sample_rate;</span><br><span> };</span><br><span> </span><br><span> /*!</span><br><span>@@ -860,6 +866,21 @@</span><br><span> void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Adjust the maximum mixing sample rate of a bridge</span><br><span style="color: hsl(120, 100%, 40%);">+ * used during multimix mode.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.31.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.8.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 17.2.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param bridge Channel to change the sample rate on.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sample_rate the maximum sample rate to use. If a</span><br><span style="color: hsl(120, 100%, 40%);">+ * value of 0 is passed here, the bridge will be free to pick</span><br><span style="color: hsl(120, 100%, 40%);">+ * what ever sample rate it chooses.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span> * \brief Adjust the internal mixing interval of a bridge used</span><br><span> * during multimix mode.</span><br><span> *</span><br><span>diff --git a/main/bridge.c b/main/bridge.c</span><br><span>index fcc96ef..4798c72 100644</span><br><span>--- a/main/bridge.c</span><br><span>+++ b/main/bridge.c</span><br><span>@@ -3750,6 +3750,13 @@</span><br><span> ast_bridge_unlock(bridge);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_bridge_lock(bridge);</span><br><span style="color: hsl(120, 100%, 40%);">+ bridge->softmix.maximum_sample_rate = sample_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_bridge_unlock(bridge);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void cleanup_video_mode(struct ast_bridge *bridge)</span><br><span> {</span><br><span> switch (bridge->softmix.video_mode.mode) {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13441">change 13441</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/13441"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: Idff80896ccfb8a58a816e4ce9ac4ebde785963ee </div>
<div style="display:none"> Gerrit-Change-Number: 13441 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Joshua C. Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>