diff options
author | Joshua Colp <jcolp@digium.com> | 2018-04-04 15:12:50 -0300 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2018-04-17 11:25:17 -0600 |
commit | 8de3fa2b56cc954836a13e7d77079754d26fb990 (patch) | |
tree | d751852e79f8fd46f2e3307c488b0f2356aff443 /apps | |
parent | 3255a286b34a15d5bdaa93663d8654c0568ab14d (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.c | 7 | ||||
-rw-r--r-- | apps/confbridge/conf_config_parser.c | 63 | ||||
-rw-r--r-- | apps/confbridge/include/confbridge.h | 3 |
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 { |