<p>Friendly Automation <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11322">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_confbridge: Add "all" variants of REMB behavior.<br><br>When producing a combined REMB value the normal behavior<br>is to have a REMB value which is unique for each sender<br>based on all of their receivers. This can result in one<br>sender having low bitrate while all the rest are high.<br><br>This change adds "all" variants which produces a bridge<br>level REMB value instead. All REMB reports are combined<br>together into a single REMB value that is the same for<br>each sender.<br><br>ASTERISK-28401<br><br>Change-Id: I883e6cc26003b497c8180b346111c79a131ba88c<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 bridges/bridge_softmix/include/bridge_softmix_internal.h<br>M configs/samples/confbridge.conf.sample<br>A doc/CHANGES-staging/app_confbridge_remb_behavior_all.txt<br>M include/asterisk/bridge.h<br>8 files changed, 122 insertions(+), 9 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 33cfbb3..6d141bd 100644</span><br><span>--- a/apps/app_confbridge.c</span><br><span>+++ b/apps/app_confbridge.c</span><br><span>@@ -1565,6 +1565,12 @@</span><br><span>                           ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST);</span><br><span>                        } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {</span><br><span>                                 ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST);</span><br><span style="color: hsl(120, 100%, 40%);">+                        } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+                    } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+                     } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL);</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 53061ba..f732c45 100644</span><br><span>--- a/apps/confbridge/conf_config_parser.c</span><br><span>+++ b/apps/confbridge/conf_config_parser.c</span><br><span>@@ -505,6 +505,18 @@</span><br><span>                                                    <enum name="highest"></span><br><span>                                                                <para>The highest estimated maximum bitrate is forwarded to the sender.</para></span><br><span>                                                   </enum></span><br><span style="color: hsl(120, 100%, 40%);">+                                                 <enum name="average_all"></span><br><span style="color: hsl(120, 100%, 40%);">+                                                             <para>The average of all estimated maximum bitrates is taken from all</span><br><span style="color: hsl(120, 100%, 40%);">+                                                           receivers in the bridge and a single value is sent to each sender.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                                                       </enum></span><br><span style="color: hsl(120, 100%, 40%);">+                                                 <enum name="lowest_all"></span><br><span style="color: hsl(120, 100%, 40%);">+                                                              <para>The lowest estimated maximum bitrate of all receivers in the bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               is taken and sent to each sender.</para></span><br><span style="color: hsl(120, 100%, 40%);">+                                                        </enum></span><br><span style="color: hsl(120, 100%, 40%);">+                                                 <enum name="highest_all"></span><br><span style="color: hsl(120, 100%, 40%);">+                                                             <para>The highest estimated maximum bitrate of all receivers in the bridge</span><br><span style="color: hsl(120, 100%, 40%);">+                                                              is taken and 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>                                 </configOption></span><br><span>@@ -1737,7 +1749,8 @@</span><br><span> </span><br><span>    switch (b_profile.flags</span><br><span>              & (BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE | BRIDGE_OPT_REMB_BEHAVIOR_LOWEST</span><br><span style="color: hsl(0, 100%, 40%);">-                       | BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        | BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST | BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL</span><br><span style="color: hsl(120, 100%, 40%);">+                     | BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL | BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL)) {</span><br><span>      case BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE:</span><br><span>               ast_cli(a->fd, "REMB Behavior:           average\n");</span><br><span>           break;</span><br><span>@@ -1747,6 +1760,15 @@</span><br><span>      case BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST:</span><br><span>               ast_cli(a->fd, "REMB Behavior:           highest\n");</span><br><span>           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_cli(a->fd, "REMB Behavior:           average_all\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(a->fd, "REMB Behavior:           lowest_all\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_cli(a->fd, "REMB Behavior:           highest_all\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span>       default:</span><br><span>             ast_assert(0);</span><br><span>               break;</span><br><span>@@ -2108,7 +2130,10 @@</span><br><span> </span><br><span>  ast_clear_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE |</span><br><span>                 BRIDGE_OPT_REMB_BEHAVIOR_LOWEST |</span><br><span style="color: hsl(0, 100%, 40%);">-               BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST);</span><br><span style="color: hsl(120, 100%, 40%);">+            BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST |</span><br><span style="color: hsl(120, 100%, 40%);">+            BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL |</span><br><span style="color: hsl(120, 100%, 40%);">+                BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL |</span><br><span style="color: hsl(120, 100%, 40%);">+         BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL);</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>@@ -2116,6 +2141,12 @@</span><br><span>          ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST);</span><br><span>    } else if (!strcasecmp(var->value, "highest")) {</span><br><span>                ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST);</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (!strcasecmp(var->value, "average_all")) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (!strcasecmp(var->value, "lowest_all")) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(var->value, "highest_all")) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL);</span><br><span>       } else {</span><br><span>             return -1;</span><br><span>   }</span><br><span>diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h</span><br><span>index 4b8249f..237431e 100644</span><br><span>--- a/apps/confbridge/include/confbridge.h</span><br><span>+++ b/apps/confbridge/include/confbridge.h</span><br><span>@@ -82,6 +82,9 @@</span><br><span>   BRIDGE_OPT_REMB_BEHAVIOR_LOWEST = (1 << 9), /*!< The lowest estimated maximum bitrate is sent to the sender */</span><br><span>      BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST = (1 << 10), /*!< The highest estimated maximum bitrate is sent to the sender */</span><br><span>   BRIDGE_OPT_ENABLE_EVENTS = (1 << 11), /*!< Enable sending events to participants */</span><br><span style="color: hsl(120, 100%, 40%);">+  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 style="color: hsl(120, 100%, 40%);">+        BRIDGE_OPT_REMB_BEHAVIOR_LOWEST_ALL = (1 << 13), /*!< The lowest estimated maximum bitrate from all receivers is sent to each sender */</span><br><span style="color: hsl(120, 100%, 40%);">+      BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST_ALL = (1 << 14), /*!< The highest estimated maximum bitrate from all receivers is sent to each sender */</span><br><span> };</span><br><span> </span><br><span> enum conf_menu_action_id {</span><br><span>diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c</span><br><span>index f9f8520..a90c716 100644</span><br><span>--- a/bridges/bridge_softmix.c</span><br><span>+++ b/bridges/bridge_softmix.c</span><br><span>@@ -1332,6 +1332,36 @@</span><br><span>     return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void remb_collect_report_all(struct ast_bridge *bridge, struct softmix_bridge_data *softmix_data,</span><br><span style="color: hsl(120, 100%, 40%);">+        float bitrate)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!softmix_data->bitrate) {</span><br><span style="color: hsl(120, 100%, 40%);">+              softmix_data->bitrate = 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 style="color: hsl(120, 100%, 40%);">+   switch (bridge->softmix.video_mode.mode_data.sfu_data.remb_behavior) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+           softmix_data->bitrate = (softmix_data->bitrate + bitrate) / 2;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+            if (bitrate < softmix_data->bitrate) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  softmix_data->bitrate = bitrate;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+           if (bitrate > softmix_data->bitrate) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  softmix_data->bitrate = bitrate;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE:</span><br><span style="color: hsl(120, 100%, 40%);">+       case AST_BRIDGE_VIDEO_SFU_REMB_LOWEST:</span><br><span style="color: hsl(120, 100%, 40%);">+        case AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* These will never actually get hit due to being handled by remb_collect_report below */</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</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%);">+</span><br><span> static void remb_collect_report(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel,</span><br><span>      struct softmix_bridge_data *softmix_data, struct softmix_channel *sc)</span><br><span> {</span><br><span>@@ -1355,6 +1385,14 @@</span><br><span>          return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* If we are using the "all" variants then we should use the bridge bitrate to store information */</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_AVERAGE_ALL ||</span><br><span style="color: hsl(120, 100%, 40%);">+                bridge->softmix.video_mode.mode_data.sfu_data.remb_behavior == AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL ||</span><br><span style="color: hsl(120, 100%, 40%);">+             bridge->softmix.video_mode.mode_data.sfu_data.remb_behavior == AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL) {</span><br><span style="color: hsl(120, 100%, 40%);">+            remb_collect_report_all(bridge, softmix_data, 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>  for (i = 0; i < AST_VECTOR_SIZE(&sc->video_sources); ++i) {</span><br><span>                struct softmix_remb_collector *collector;</span><br><span> </span><br><span>@@ -1380,6 +1418,11 @@</span><br><span>                               collector->bitrate = bitrate;</span><br><span>                     }</span><br><span>                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+           case AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+            case AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL:</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* These will never actually get hit due to being handled by remb_collect_report_all above */</span><br><span style="color: hsl(120, 100%, 40%);">+                 break;</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span>@@ -1390,8 +1433,10 @@</span><br><span>       sc->remb.br_exp = 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct softmix_channel *sc)</span><br><span style="color: hsl(120, 100%, 40%);">+static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct softmix_bridge_data *softmix_data,</span><br><span style="color: hsl(120, 100%, 40%);">+        struct softmix_channel *sc)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      float bitrate = softmix_data->bitrate;</span><br><span>    int i;</span><br><span>       int exp;</span><br><span> </span><br><span>@@ -1399,6 +1444,12 @@</span><br><span>                return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* If there is no bridge level bitrate fall back to collector level */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!bitrate) {</span><br><span style="color: hsl(120, 100%, 40%);">+               bitrate = sc->remb_collector->bitrate;</span><br><span style="color: hsl(120, 100%, 40%);">+          sc->remb_collector->bitrate = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* We always do this calculation as even when the bitrate is zero the browser</span><br><span>         * still prefers it to be accurate instead of lying.</span><br><span>          *</span><br><span>@@ -1442,10 +1493,10 @@</span><br><span>          * Precision on the "lower" end is lost due to zeros being shifted in. This loss is</span><br><span>         * both expected and acceptable.</span><br><span>      */</span><br><span style="color: hsl(0, 100%, 40%);">-     frexp(sc->remb_collector->bitrate, &exp);</span><br><span style="color: hsl(120, 100%, 40%);">+   frexp(bitrate, &exp);</span><br><span>    exp = exp > 18 ? exp - 18 : 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->bitrate / (1 << exp);</span><br><span style="color: hsl(120, 100%, 40%);">+   sc->remb_collector->feedback.remb.br_mantissa = bitrate / (1 << exp);</span><br><span>    sc->remb_collector->feedback.remb.br_exp = exp;</span><br><span> </span><br><span>    for (i = 0; i < AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge); ++i) {</span><br><span>@@ -1466,8 +1517,6 @@</span><br><span>             sc->remb_collector->frame.stream_num = bridge_num;</span><br><span>             ast_bridge_channel_queue_frame(bridge_channel, &sc->remb_collector->frame);</span><br><span>        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       sc->remb_collector->bitrate = 0;</span><br><span> }</span><br><span> </span><br><span> static void gather_softmix_stats(struct softmix_stats *stats,</span><br><span>@@ -1827,10 +1876,15 @@</span><br><span>                   ast_bridge_channel_queue_frame(bridge_channel, &sc->write_frame);</span><br><span> </span><br><span>                         if (remb_update) {</span><br><span style="color: hsl(0, 100%, 40%);">-                              remb_send_report(bridge_channel, sc);</span><br><span style="color: hsl(120, 100%, 40%);">+                         remb_send_report(bridge_channel, softmix_data, sc);</span><br><span>                  }</span><br><span>            }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         if (remb_update) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* In case we are doing bridge level REMB reset the bitrate so we start fresh */</span><br><span style="color: hsl(120, 100%, 40%);">+                      softmix_data->bitrate = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          update_all_rates = 0;</span><br><span>                if (!stat_iteration_counter) {</span><br><span>                       update_all_rates = analyse_softmix_stats(&stats, softmix_data,</span><br><span>diff --git a/bridges/bridge_softmix/include/bridge_softmix_internal.h b/bridges/bridge_softmix/include/bridge_softmix_internal.h</span><br><span>index 15856b3..ca70c3c 100644</span><br><span>--- a/bridges/bridge_softmix/include/bridge_softmix_internal.h</span><br><span>+++ b/bridges/bridge_softmix/include/bridge_softmix_internal.h</span><br><span>@@ -216,6 +216,8 @@</span><br><span>        struct timeval last_remb_update;</span><br><span>     /*! Per-bridge stream REMB collectors, which flow back to video source */</span><br><span>    AST_VECTOR(, struct softmix_remb_collector *) remb_collectors;</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! Per-bridge REMB bitrate */</span><br><span style="color: hsl(120, 100%, 40%);">+        float bitrate;</span><br><span> };</span><br><span> </span><br><span> struct softmix_mixing_array {</span><br><span>diff --git a/configs/samples/confbridge.conf.sample b/configs/samples/confbridge.conf.sample</span><br><span>index a214f34..e148181 100644</span><br><span>--- a/configs/samples/confbridge.conf.sample</span><br><span>+++ b/configs/samples/confbridge.conf.sample</span><br><span>@@ -254,7 +254,11 @@</span><br><span> ;remb_behavior=average     ; How the combined REMB report for an SFU video bridge is constructed. If set to "average" then</span><br><span>                            ; the estimated maximum bitrate of each receiver is used to construct an average bitrate. If</span><br><span>                            ; set to "lowest" the lowest maximum bitrate is forwarded to the sender. If set to "highest"</span><br><span style="color: hsl(0, 100%, 40%);">-                           ; the highest maximum bitrate is forwarded to the sender. This defaults to "average".</span><br><span style="color: hsl(120, 100%, 40%);">+                           ; the highest maximum bitrate is forwarded to the sender. If set to "average_all" a single average</span><br><span style="color: hsl(120, 100%, 40%);">+                           ; is generated from every receiver and the same value is sent to every sender. If set to</span><br><span style="color: hsl(120, 100%, 40%);">+                           ; "lowest_all" the lowest maximum bitrate of all receivers is sent to every sender. If set to</span><br><span style="color: hsl(120, 100%, 40%);">+                           ; "highest_all" the highest maximum bitrate of all receivers is sent to every sender. This</span><br><span style="color: hsl(120, 100%, 40%);">+                           ; defaults to "average".</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_remb_behavior_all.txt b/doc/CHANGES-staging/app_confbridge_remb_behavior_all.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..6110a6f</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/app_confbridge_remb_behavior_all.txt</span><br><span>@@ -0,0 +1,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: ConfBridge</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Add "average_all", "highest_all", and "lowest_all" values for</span><br><span style="color: hsl(120, 100%, 40%);">+the remb_behavior option. These values operate on a bridge</span><br><span style="color: hsl(120, 100%, 40%);">+level instead of a per-source level. This means that a single</span><br><span style="color: hsl(120, 100%, 40%);">+REMB value is calculated and sent to every sender, instead of</span><br><span style="color: hsl(120, 100%, 40%);">+a REMB value that is unique for the specific sender..</span><br><span>diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h</span><br><span>index 621ed0d..9be38a8 100644</span><br><span>--- a/include/asterisk/bridge.h</span><br><span>+++ b/include/asterisk/bridge.h</span><br><span>@@ -135,6 +135,12 @@</span><br><span>       AST_BRIDGE_VIDEO_SFU_REMB_LOWEST,</span><br><span>    /*! The highest reported bitrate is forwarded to the sender */</span><br><span>       AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST,</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! The average of all reports WITHIN the bridge is sent to each sender */</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE_ALL,</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! The lowest reported bitrate from all channels in the bridge is forwarded to each sender */</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_BRIDGE_VIDEO_SFU_REMB_LOWEST_ALL,</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! The highest reported bitrate from all channels in the bridge is forwarded to each sender */</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST_ALL,</span><br><span> };</span><br><span> </span><br><span> /*! \brief This is used for selective forwarding unit configuration */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11322">change 11322</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/+/11322"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I883e6cc26003b497c8180b346111c79a131ba88c </div>
<div style="display:none"> Gerrit-Change-Number: 11322 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@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: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>