<p>Joshua C. Colp <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13429">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
  Joshua C. Colp: 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 33cfbb3..9020411 100644</span><br><span>--- a/apps/app_confbridge.c</span><br><span>+++ b/apps/app_confbridge.c</span><br><span>@@ -1549,6 +1549,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>                ast_bridge_set_binaural_active(conference->bridge, ast_test_flag(&conference->b_profile, BRIDGE_OPT_BINAURAL_ACTIVE));</span><br><span>diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c</span><br><span>index 53061ba..ba562a8 100644</span><br><span>--- a/apps/confbridge/conf_config_parser.c</span><br><span>+++ b/apps/confbridge/conf_config_parser.c</span><br><span>@@ -274,6 +274,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>@@ -1670,6 +1679,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>@@ -2345,6 +2361,7 @@</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>     aco_option_register(&cfg_info, "binaural_active", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_BINAURAL_ACTIVE);</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 4b8249f..053db61 100644</span><br><span>--- a/apps/confbridge/include/confbridge.h</span><br><span>+++ b/apps/confbridge/include/confbridge.h</span><br><span>@@ -224,6 +224,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 290ea2b..afb8376 100644</span><br><span>--- a/bridges/bridge_softmix.c</span><br><span>+++ b/bridges/bridge_softmix.c</span><br><span>@@ -86,12 +86,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_translate_helper_entry {</span><br><span>@@ -1447,7 +1451,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>@@ -1499,6 +1505,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>@@ -1681,6 +1696,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 a214f34..877d15d 100644</span><br><span>--- a/configs/samples/confbridge.conf.sample</span><br><span>+++ b/configs/samples/confbridge.conf.sample</span><br><span>@@ -203,6 +203,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 dc8ebe5..6e7b1bc 100644</span><br><span>--- a/include/asterisk/bridge.h</span><br><span>+++ b/include/asterisk/bridge.h</span><br><span>@@ -295,6 +295,12 @@</span><br><span>   * the channel uniqueid.  Used for participant info correlation.</span><br><span>      */</span><br><span>  unsigned int send_sdp_label;</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> AST_LIST_HEAD_NOLOCK(ast_bridge_channels_list, ast_bridge_channel);</span><br><span>@@ -897,6 +903,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 f3c34d1..28867b1 100644</span><br><span>--- a/main/bridge.c</span><br><span>+++ b/main/bridge.c</span><br><span>@@ -3791,6 +3791,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/+/13429">change 13429</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/+/13429"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: certified/16.3 </div>
<div style="display:none"> Gerrit-Change-Id: Idff80896ccfb8a58a816e4ce9ac4ebde785963ee </div>
<div style="display:none"> Gerrit-Change-Number: 13429 </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: Joshua C. Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>