<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/14995">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved; Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_confbridge/bridge_softmix: Add ability to force estimated bitrate<br><br>app_confbridge now has the ability to set the estimated bitrate on an<br>SFU bridge. To use it, set a bridge profile's remb_behavior to "force"<br>and set remb_estimated_bitrate to a rate in bits per second. The<br>remb_estimated_bitrate parameter is ignored if remb_behavior is something<br>other than "force".<br><br>Change-Id: Idce6464ff014a37ea3b82944452e56cc4d75ab0a<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.txt<br>M include/asterisk/bridge.h<br>M main/bridge.c<br>8 files changed, 70 insertions(+), 3 deletions(-)<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 fca0ed6..8ad188a 100644</span><br><span>--- a/apps/app_confbridge.c</span><br><span>+++ b/apps/app_confbridge.c</span><br><span>@@ -1730,6 +1730,9 @@</span><br><span> ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL);</span><br><span> } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL)) {</span><br><span> ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_FORCE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_FORCE);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_bridge_set_remb_estimated_bitrate(conference->bridge, conference->b_profile.remb_estimated_bitrate);</span><br><span> }</span><br><span> }</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 3814d30..656acc6 100644</span><br><span>--- a/apps/confbridge/conf_config_parser.c</span><br><span>+++ b/apps/confbridge/conf_config_parser.c</span><br><span>@@ -533,8 +533,22 @@</span><br><span> <para>The highest estimated maximum bitrate of all receivers in the bridge</span><br><span> is taken and sent to each sender.</para></span><br><span> </enum></span><br><span style="color: hsl(120, 100%, 40%);">+ <enum name="force"></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>The bitrate configured in <literal>remb_estimated_bitrate</literal></span><br><span style="color: hsl(120, 100%, 40%);">+ is sent to each sender.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </enum></span><br><span> </enumlist></span><br><span> </description></span><br><span style="color: hsl(120, 100%, 40%);">+ <see-also><ref type="configOption">remb_estimated_bitrate</ref></see-also></span><br><span style="color: hsl(120, 100%, 40%);">+ </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+ <configOption name="remb_estimated_bitrate"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis>Sets the estimated bitrate sent to each participant in REMB reports</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <description><para></span><br><span style="color: hsl(120, 100%, 40%);">+ When <literal>remb_behavior</literal> is set to <literal>force</literal>,</span><br><span style="color: hsl(120, 100%, 40%);">+ this options sets the estimated bitrate (in bits per second) sent to each participant</span><br><span style="color: hsl(120, 100%, 40%);">+ in REMB reports.</span><br><span style="color: hsl(120, 100%, 40%);">+ </para></description></span><br><span style="color: hsl(120, 100%, 40%);">+ <see-also><ref type="configOption">remb_behavior</ref></see-also></span><br><span> </configOption></span><br><span> <configOption name="enable_events" default="no"></span><br><span> <synopsis>Enables events for this bridge</synopsis></span><br><span>@@ -2159,7 +2173,9 @@</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST |</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL |</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL |</span><br><span style="color: hsl(0, 100%, 40%);">- BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+ BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL |</span><br><span style="color: hsl(120, 100%, 40%);">+ BRIDGE_OPT_REMB_BEHAVIOR_FORCE</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span> </span><br><span> if (!strcasecmp(var->value, "average")) {</span><br><span> ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE);</span><br><span>@@ -2173,6 +2189,8 @@</span><br><span> ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL);</span><br><span> } else if (!strcasecmp(var->value, "highest_all")) {</span><br><span> ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(var->value, "force")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_FORCE);</span><br><span> } else {</span><br><span> return -1;</span><br><span> }</span><br><span>@@ -2419,6 +2437,7 @@</span><br><span> aco_option_register(&cfg_info, "video_update_discard", ACO_EXACT, bridge_types, "2000", OPT_UINT_T, 0, FLDSET(struct bridge_profile, video_update_discard));</span><br><span> aco_option_register(&cfg_info, "remb_send_interval", ACO_EXACT, bridge_types, "0", OPT_UINT_T, 0, FLDSET(struct bridge_profile, remb_send_interval));</span><br><span> aco_option_register_custom(&cfg_info, "remb_behavior", ACO_EXACT, bridge_types, "average", remb_behavior_handler, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ aco_option_register(&cfg_info, "remb_estimated_bitrate", ACO_EXACT, bridge_types, "0", OPT_UINT_T, 0, FLDSET(struct bridge_profile, remb_estimated_bitrate));</span><br><span> aco_option_register(&cfg_info, "enable_events", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_ENABLE_EVENTS);</span><br><span> /* This option should only be used with the CONFBRIDGE dialplan function */</span><br><span> aco_option_register_custom(&cfg_info, "template", ACO_EXACT, bridge_types, NULL, bridge_template_handler, 0);</span><br><span>diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h</span><br><span>index e48292a..f413359 100644</span><br><span>--- a/apps/confbridge/include/confbridge.h</span><br><span>+++ b/apps/confbridge/include/confbridge.h</span><br><span>@@ -87,6 +87,7 @@</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL = (1 << 12), /*!< The average of all REMB reports in the entire bridge is sent to each sender */</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL = (1 << 13), /*!< The lowest estimated maximum bitrate from all receivers is sent to each sender */</span><br><span> BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL = (1 << 14), /*!< The highest estimated maximum bitrate from all receivers is sent to each sender */</span><br><span style="color: hsl(120, 100%, 40%);">+ BRIDGE_OPT_REMB_BEHAVIOR_FORCE = (1 << 15), /*!< Force the REMB estimated bitrate to that specifiec in remb_estimated_bitrate */</span><br><span> };</span><br><span> </span><br><span> enum conf_menu_action_id {</span><br><span>@@ -235,6 +236,7 @@</span><br><span> char regcontext[AST_MAX_CONTEXT];</span><br><span> unsigned int video_update_discard; /*!< Amount of time after sending a video update request that subsequent requests should be discarded */</span><br><span> unsigned int remb_send_interval; /*!< Interval at which a combined REMB frame is sent to video sources */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int remb_estimated_bitrate; /*!< Bitrate sent when BRIDGE_OPT_REMB_BEHAVIOR_FORCE is set */</span><br><span> };</span><br><span> </span><br><span> /*! \brief The structure that represents a conference bridge */</span><br><span>diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c</span><br><span>index 5acd794..d51a55f 100644</span><br><span>--- a/bridges/bridge_softmix.c</span><br><span>+++ b/bridges/bridge_softmix.c</span><br><span>@@ -1396,6 +1396,7 @@</span><br><span> case AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE:</span><br><span> case AST_BRIDGE_VIDEO_SFU_REMB_LOWEST:</span><br><span> case AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST:</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_BRIDGE_VIDEO_SFU_REMB_FORCE:</span><br><span> /* These will never actually get hit due to being handled by remb_collect_report below */</span><br><span> break;</span><br><span> }</span><br><span>@@ -1417,6 +1418,12 @@</span><br><span> /* We evenly divide the available maximum bitrate across the video sources</span><br><span> * to this receiver so each source gets an equal slice.</span><br><span> */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bridge->softmix.video_mode.mode_data.sfu_data.remb_behavior == AST_BRIDGE_VIDEO_SFU_REMB_FORCE) {</span><br><span style="color: hsl(120, 100%, 40%);">+ softmix_data->bitrate = bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate;</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bitrate = (sc->remb.br_mantissa << sc->remb.br_exp) / AST_VECTOR_SIZE(&sc->video_sources);</span><br><span> </span><br><span> /* If this receiver has no bitrate yet ignore it */</span><br><span>@@ -1462,6 +1469,9 @@</span><br><span> case AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL:</span><br><span> /* These will never actually get hit due to being handled by remb_collect_report_all above */</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AST_BRIDGE_VIDEO_SFU_REMB_FORCE:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Don't do anything, we've already forced it */</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> }</span><br><span> }</span><br><span> </span><br><span>diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample</span><br><span>index 02edaa5..7749c93 100644</span><br><span>--- a/configs/samples/confbridge.conf.sample</span><br><span>+++ b/configs/samples/confbridge.conf.sample</span><br><span>@@ -264,8 +264,11 @@</span><br><span> ; the highest maximum bitrate is forwarded to the sender. If set to "average_all" a single average</span><br><span> ; is generated from every receiver and the same value is sent to every sender. If set to</span><br><span> ; "lowest_all" the lowest maximum bitrate of all receivers is sent to every sender. If set to</span><br><span style="color: hsl(0, 100%, 40%);">- ; "highest_all" the highest maximum bitrate of all receivers is sent to every sender. This</span><br><span style="color: hsl(0, 100%, 40%);">- ; defaults to "average".</span><br><span style="color: hsl(120, 100%, 40%);">+ ; "highest_all" the highest maximum bitrate of all receivers is sent to every sender.</span><br><span style="color: hsl(120, 100%, 40%);">+ ; When set to "force", the value set in remb_estimated_bitrate is sent to every sender.</span><br><span style="color: hsl(120, 100%, 40%);">+ ; This defaults to "average".</span><br><span style="color: hsl(120, 100%, 40%);">+;remb_estimated_bitrate=0 ; When remb_behavior is set to 'force', this options sets the estimated bitrate</span><br><span style="color: hsl(120, 100%, 40%);">+ ; (in bits per second) sent to each participant in REMB reports.</span><br><span> </span><br><span> ;enable_events=no ; If enabled, recipients who joined the bridge via a channel driver</span><br><span> ; that supports Enhanced Messaging (currently only chan_pjsip) will</span><br><span>diff --git a/doc/CHANGES-staging/app_confbridge.txt b/doc/CHANGES-staging/app_confbridge.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..092e392</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_confbridge.txt</span><br><span>@@ -0,0 +1,7 @@</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%);">+app_confbridge now has the ability to force the estimated bitrate on an SFU</span><br><span style="color: hsl(120, 100%, 40%);">+bridge. To use it, set a bridge profile's remb_behavior to "force" and</span><br><span style="color: hsl(120, 100%, 40%);">+set remb_estimated_bitrate to a rate in bits per second. The</span><br><span style="color: hsl(120, 100%, 40%);">+remb_estimated_bitrate parameter is ignored if remb_behavior is something</span><br><span style="color: hsl(120, 100%, 40%);">+other than "force".</span><br><span>diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h</span><br><span>index a0aa4c5..6a7a3956 100644</span><br><span>--- a/include/asterisk/bridge.h</span><br><span>+++ b/include/asterisk/bridge.h</span><br><span>@@ -141,6 +141,8 @@</span><br><span> AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL,</span><br><span> /*! The highest reported bitrate from all channels in the bridge is forwarded to each sender */</span><br><span> AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL,</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Force the REMB estimated bitrate to a specified value */</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_BRIDGE_VIDEO_SFU_REMB_FORCE,</span><br><span> };</span><br><span> </span><br><span> /*! \brief This is used for selective forwarding unit configuration */</span><br><span>@@ -149,6 +151,8 @@</span><br><span> unsigned int remb_send_interval;</span><br><span> /*! How the combined REMB report is generated */</span><br><span> enum ast_bridge_video_sfu_remb_behavior remb_behavior;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! The estimated bitrate when behavior is "force" */</span><br><span style="color: hsl(120, 100%, 40%);">+ float estimated_bitrate;</span><br><span> };</span><br><span> </span><br><span> /*! \brief Data structure that defines a video source mode */</span><br><span>@@ -1040,6 +1044,16 @@</span><br><span> void ast_brige_set_remb_behavior(struct ast_bridge *bridge, enum ast_bridge_video_sfu_remb_behavior behavior);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Force the REMB report estimated bitrate to a specific max value</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param bridge Bridge to set the REMB behavior on</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param estimated_bitrate The estimated bitrate in bits per second</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note This can only be called when the bridge has been set to the SFU video mode.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_bridge_set_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span> * \brief Update information about talker energy for talker src video mode.</span><br><span> */</span><br><span> void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame);</span><br><span>diff --git a/main/bridge.c b/main/bridge.c</span><br><span>index d44f659..0538008 100644</span><br><span>--- a/main/bridge.c</span><br><span>+++ b/main/bridge.c</span><br><span>@@ -3871,6 +3871,15 @@</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_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_assert(bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU);</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.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;</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> void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe)</span><br><span> {</span><br><span> struct ast_bridge_video_talker_src_data *data;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/14995">change 14995</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/+/14995"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Idce6464ff014a37ea3b82944452e56cc4d75ab0a </div>
<div style="display:none"> Gerrit-Change-Number: 14995 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.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 Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>