summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2018-04-04 15:12:50 -0300
committerJoshua Colp <jcolp@digium.com>2018-04-17 11:25:17 -0600
commit8de3fa2b56cc954836a13e7d77079754d26fb990 (patch)
treed751852e79f8fd46f2e3307c488b0f2356aff443 /apps
parent3255a286b34a15d5bdaa93663d8654c0568ab14d (diff)
bridge_softmix / app_confbridge: Add support for REMB combining.
This change adds the ability for multiple REMB reports in bridge_softmix to be combined according to a configured behavior into a single report. This single report is sent back to the sender of video, which adjusts the encoding bitrate to be at or below the bitrate of the report. The available behaviors are: lowest, highest, and average. Lowest uses the lowest received bitrate. Highest uses the highest received bitrate. Average goes through the received bitrates adding them to the previous average and creates a new average. Other behaviors can be added in the future and the existing average one may be adjusted, but this provides the foundation to do so. Support for configuring which behavior to use has been added to app_confbridge. ASTERISK-27804 Change-Id: I9eafe4e7c1f72d67074a8d6acb26bfcf19322b66
Diffstat (limited to 'apps')
-rw-r--r--apps/app_confbridge.c7
-rw-r--r--apps/confbridge/conf_config_parser.c63
-rw-r--r--apps/confbridge/include/confbridge.h3
3 files changed, 73 insertions, 0 deletions
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index d8407d857..25cf2758f 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -1544,6 +1544,13 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
ast_bridge_set_sfu_video_mode(conference->bridge);
ast_bridge_set_video_update_discard(conference->bridge, conference->b_profile.video_update_discard);
ast_bridge_set_remb_send_interval(conference->bridge, conference->b_profile.remb_send_interval);
+ if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE)) {
+ ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_AVERAGE);
+ } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST)) {
+ ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_LOWEST);
+ } else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
+ ast_brige_set_remb_behavior(conference->bridge, AST_BRIDGE_VIDEO_SFU_REMB_HIGHEST);
+ }
}
/* Link it into the conference bridges container */
diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c
index f9d74831c..c143e39e2 100644
--- a/apps/confbridge/conf_config_parser.c
+++ b/apps/confbridge/conf_config_parser.c
@@ -470,6 +470,27 @@
better quality for all receivers.
</para></description>
</configOption>
+ <configOption name="remb_behavior" default="average">
+ <synopsis>Sets how REMB reports are generated from multiple sources</synopsis>
+ <description><para>
+ Sets how REMB reports are combined from multiple sources to form one. A REMB report
+ consists of information about the receiver estimated maximum bitrate. As a source
+ stream may be forwarded to multiple receivers the reports must be combined into
+ a single one which is sent to the sender.</para>
+ <enumlist>
+ <enum name="average">
+ <para>The average of all estimated maximum bitrates is taken and sent
+ to the sender.</para>
+ </enum>
+ <enum name="lowest">
+ <para>The lowest estimated maximum bitrate is forwarded to the sender.</para>
+ </enum>
+ <enum name="highest">
+ <para>The highest estimated maximum bitrate is forwarded to the sender.</para>
+ </enum>
+ </enumlist>
+ </description>
+ </configOption>
<configOption name="template">
<synopsis>When using the CONFBRIDGE dialplan function, use a bridge profile as a template for creating a new temporary profile</synopsis>
</configOption>
@@ -1675,6 +1696,23 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e,
ast_cli(a->fd,"Video Update Discard: %u\n", b_profile.video_update_discard);
ast_cli(a->fd,"REMB Send Interval: %u\n", b_profile.remb_send_interval);
+ switch (b_profile.flags
+ & (BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE | BRIDGE_OPT_REMB_BEHAVIOR_LOWEST
+ | BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST)) {
+ case BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE:
+ ast_cli(a->fd, "REMB Behavior: average\n");
+ break;
+ case BRIDGE_OPT_REMB_BEHAVIOR_LOWEST:
+ ast_cli(a->fd, "REMB Behavior: lowest\n");
+ break;
+ case BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST:
+ ast_cli(a->fd, "REMB Behavior: highest\n");
+ break;
+ default:
+ ast_assert(0);
+ break;
+ }
+
ast_cli(a->fd,"sound_only_person: %s\n", conf_get_sound(CONF_SOUND_ONLY_PERSON, b_profile.sounds));
ast_cli(a->fd,"sound_only_one: %s\n", conf_get_sound(CONF_SOUND_ONLY_ONE, b_profile.sounds));
ast_cli(a->fd,"sound_has_joined: %s\n", conf_get_sound(CONF_SOUND_HAS_JOINED, b_profile.sounds));
@@ -2011,6 +2049,30 @@ static int video_mode_handler(const struct aco_option *opt, struct ast_variable
return 0;
}
+static int remb_behavior_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+ struct bridge_profile *b_profile = obj;
+
+ if (strcasecmp(var->name, "remb_behavior")) {
+ return -1;
+ }
+
+ ast_clear_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE |
+ BRIDGE_OPT_REMB_BEHAVIOR_LOWEST |
+ BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST);
+
+ if (!strcasecmp(var->value, "average")) {
+ ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE);
+ } else if (!strcasecmp(var->value, "lowest")) {
+ ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_LOWEST);
+ } else if (!strcasecmp(var->value, "highest")) {
+ ast_set_flag(b_profile, BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST);
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
static int user_template_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
struct user_profile *u_profile = obj;
@@ -2245,6 +2307,7 @@ int conf_load_config(void)
aco_option_register_custom(&cfg_info, "sound_", ACO_PREFIX, bridge_types, NULL, sound_option_handler, 0);
aco_option_register(&cfg_info, "video_update_discard", ACO_EXACT, bridge_types, "2000", OPT_UINT_T, 0, FLDSET(struct bridge_profile, video_update_discard));
aco_option_register(&cfg_info, "remb_send_interval", ACO_EXACT, bridge_types, "0", OPT_UINT_T, 0, FLDSET(struct bridge_profile, remb_send_interval));
+ aco_option_register_custom(&cfg_info, "remb_behavior", ACO_EXACT, bridge_types, "average", remb_behavior_handler, 0);
/* This option should only be used with the CONFBRIDGE dialplan function */
aco_option_register_custom(&cfg_info, "template", ACO_EXACT, bridge_types, NULL, bridge_template_handler, 0);
diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h
index c2f8f9a58..0a0a5713f 100644
--- a/apps/confbridge/include/confbridge.h
+++ b/apps/confbridge/include/confbridge.h
@@ -76,6 +76,9 @@ enum bridge_profile_flags {
BRIDGE_OPT_RECORD_FILE_TIMESTAMP = (1 << 5), /*!< Set if the record file should have a timestamp appended */
BRIDGE_OPT_BINAURAL_ACTIVE = (1 << 6), /*!< Set if binaural convolution is activated */
BRIDGE_OPT_VIDEO_SRC_SFU = (1 << 7), /*!< Selective forwarding unit */
+ BRIDGE_OPT_REMB_BEHAVIOR_AVERAGE = (1 << 8), /*!< The average of all REMB reports is sent to the sender */
+ BRIDGE_OPT_REMB_BEHAVIOR_LOWEST = (1 << 9), /*!< The lowest estimated maximum bitrate is sent to the sender */
+ BRIDGE_OPT_REMB_BEHAVIOR_HIGHEST = (1 << 10), /*!< The highest estimated maximum bitrate is sent to the sender */
};
enum conf_menu_action_id {