From: George Joseph Date: Tue, 16 Oct 2018 12:02:19 +0000 (-0600) Subject: bridge_softmix: Add SDP "label" attribute to streams X-Git-Tag: 16.1.0-rc1~48^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fec66b8f010a760d5449f40741dede887b14650b;p=thirdparty%2Fasterisk.git bridge_softmix: Add SDP "label" attribute to streams Adding the "label" attribute used for participant info correlation was previously done in app_confbridge but it wasn't working correctly because it didn't have knowledge about which video streams belonged to which channel. Only bridge_softmix has that data so now it's set when the bridge topology is changed. ASTERISK-28107 Change-Id: Ieddeca5799d710cad083af3fcc3e677fa2a2a499 --- diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index a4e5c67a8d..8a9f24110c 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -1566,6 +1566,10 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen } } + if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_ENABLE_EVENTS)) { + ast_bridge_set_send_sdp_label(conference->bridge, 1); + } + /* Link it into the conference bridges container */ if (!ao2_link(conference_bridges, conference)) { ao2_ref(conference, -1); diff --git a/apps/confbridge/confbridge_manager.c b/apps/confbridge/confbridge_manager.c index a7f2fce014..e88bbc2b02 100644 --- a/apps/confbridge/confbridge_manager.c +++ b/apps/confbridge/confbridge_manager.c @@ -355,56 +355,6 @@ static struct ast_json *pack_snapshots( struct ast_bridge_snapshot *bridge_snaps return pack_bridge_and_channels(json_bridge, json_channel, msg); } -enum label_direction { - LABEL_DIRECTION_SRC, - LABEL_DIRECTION_DEST, -}; - -static struct ast_stream *get_stream(struct ast_stream_topology *topology, - enum ast_media_type m_type) -{ - int count; - int i; - - count = ast_stream_topology_get_count(topology); - if (count < 0) { - return NULL; - } - - for (i = 0; i < count; i++) { - struct ast_stream *s; - enum ast_stream_state s_state; - enum ast_media_type s_type; - - s = ast_stream_topology_get_stream(topology, i); - s_state = ast_stream_get_state(s); - s_type = ast_stream_get_type(s); - if (s_type == m_type - && (s_state == AST_STREAM_STATE_SENDRECV || s_state == AST_STREAM_STATE_RECVONLY)) { - return s; - } - } - - return NULL; -} - -static void set_media_labels(struct confbridge_conference *conference, - struct ast_channel *src_chan, struct ast_channel *dest_chan, enum label_direction dir) -{ - struct ast_stream_topology *topology; - struct ast_stream *stream; - struct ast_channel *chan = dir == LABEL_DIRECTION_SRC ? dest_chan : src_chan; - - if (!chan) { - return; - } - topology = ast_channel_get_stream_topology(chan); - stream = get_stream(topology, AST_MEDIA_TYPE_VIDEO); - if (stream) { - ast_stream_set_metadata(stream, "SDP:LABEL", ast_channel_uniqueid(chan)); - } -} - static void send_message(const char *msg_name, char *conf_name, struct ast_json *json_object, struct ast_channel *chan) { @@ -508,7 +458,6 @@ void conf_send_event_to_participants(struct confbridge_conference *conference, continue; } - set_media_labels(conference, chan, user->chan, LABEL_DIRECTION_SRC); target_json_channel = channel_to_json(target_snapshot, extras, NULL); ao2_ref(target_snapshot, -1); @@ -538,8 +487,6 @@ void conf_send_event_to_participants(struct confbridge_conference *conference, continue; } - set_media_labels(conference, chan, user->chan, LABEL_DIRECTION_DEST); - json_object = pack_snapshots(obj->bridge, obj->channel, extras, NULL, msg); if (!json_object) { diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c index b11fccc2e0..cf61340f25 100644 --- a/bridges/bridge_softmix.c +++ b/bridges/bridge_softmix.c @@ -498,7 +498,7 @@ static int is_video_dest(const struct ast_stream *stream, const char *source_cha } static int append_source_streams(struct ast_stream_topology *dest, - const char *channel_name, + const char *channel_name, const char *sdp_label, const struct ast_stream_topology *source) { int i; @@ -523,6 +523,12 @@ static int append_source_streams(struct ast_stream_topology *dest, if (!stream_clone) { return -1; } + + /* Sends an "a:label" attribute in the SDP for participant event correlation */ + if (!ast_strlen_zero(sdp_label)) { + ast_stream_set_metadata(stream_clone, "SDP:LABEL", sdp_label); + } + if (ast_stream_topology_append_stream(dest, stream_clone) < 0) { ast_stream_free(stream_clone); return -1; @@ -585,9 +591,11 @@ static int append_all_streams(struct ast_stream_topology *dest, * \param joiner The channel that is joining the softmix bridge * \param participants The current participants in the softmix bridge */ -static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast_bridge_channels_list *participants) +static void sfu_topologies_on_join(struct ast_bridge *bridge, + struct ast_bridge_channel *joiner) { struct ast_stream_topology *joiner_video = NULL; + struct ast_bridge_channels_list *participants = &bridge->channels; struct ast_bridge_channel *participant; int res; struct softmix_channel *sc; @@ -600,7 +608,9 @@ static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast sc = joiner->tech_pvt; ast_channel_lock(joiner->chan); - res = append_source_streams(joiner_video, ast_channel_name(joiner->chan), ast_channel_get_stream_topology(joiner->chan)); + res = append_source_streams(joiner_video, ast_channel_name(joiner->chan), + bridge->softmix.send_sdp_label ? ast_channel_uniqueid(joiner->chan) : NULL, + ast_channel_get_stream_topology(joiner->chan)); sc->topology = ast_stream_topology_clone(ast_channel_get_stream_topology(joiner->chan)); ast_channel_unlock(joiner->chan); @@ -614,7 +624,8 @@ static void sfu_topologies_on_join(struct ast_bridge_channel *joiner, struct ast } ast_channel_lock(participant->chan); res = append_source_streams(sc->topology, ast_channel_name(participant->chan), - ast_channel_get_stream_topology(participant->chan)); + bridge->softmix.send_sdp_label ? ast_channel_uniqueid(participant->chan) : NULL, + ast_channel_get_stream_topology(participant->chan)); ast_channel_unlock(participant->chan); if (res) { goto cleanup; @@ -704,7 +715,7 @@ static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_chan bridge_channel, 0, set_binaural, pos_id, is_announcement); if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) { - sfu_topologies_on_join(bridge_channel, &bridge->channels); + sfu_topologies_on_join(bridge, bridge_channel); } softmix_poke_thread(softmix_data); @@ -1063,9 +1074,11 @@ static int remove_all_original_streams(struct ast_stream_topology *dest, return 0; } -static void sfu_topologies_on_source_change(struct ast_bridge_channel *source, struct ast_bridge_channels_list *participants) +static void sfu_topologies_on_source_change(struct ast_bridge *bridge, + struct ast_bridge_channel *source) { struct ast_stream_topology *source_video = NULL; + struct ast_bridge_channels_list *participants = &bridge->channels; struct ast_bridge_channel *participant; int res; @@ -1075,7 +1088,9 @@ static void sfu_topologies_on_source_change(struct ast_bridge_channel *source, s } ast_channel_lock(source->chan); - res = append_source_streams(source_video, ast_channel_name(source->chan), ast_channel_get_stream_topology(source->chan)); + res = append_source_streams(source_video, ast_channel_name(source->chan), + bridge->softmix.send_sdp_label ? ast_channel_uniqueid(source->chan) : NULL, + ast_channel_get_stream_topology(source->chan)); ast_channel_unlock(source->chan); if (res) { goto cleanup; @@ -1198,7 +1213,7 @@ static int softmix_bridge_write_control(struct ast_bridge *bridge, struct ast_br break; case AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED: if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_SFU) { - sfu_topologies_on_source_change(bridge_channel, &bridge->channels); + sfu_topologies_on_source_change(bridge, bridge_channel); } break; default: @@ -2383,7 +2398,7 @@ AST_TEST_DEFINE(sfu_append_source_streams) goto end; } - if (append_source_streams(topology_alice, "PJSIP/Bob-00000001", topology_bob)) { + if (append_source_streams(topology_alice, "PJSIP/Bob-00000001", NULL, topology_bob)) { ast_test_status_update(test, "Failed to append Bob's streams to Alice\n"); goto end; } @@ -2402,7 +2417,7 @@ AST_TEST_DEFINE(sfu_append_source_streams) goto end; } - if (append_source_streams(topology_bob, "PJSIP/Alice-00000000", topology_alice)) { + if (append_source_streams(topology_bob, "PJSIP/Alice-00000000", NULL, topology_alice)) { ast_test_status_update(test, "Failed to append Alice's streams to Bob\n"); goto end; } diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h index 3584085aff..f4b1df8e04 100644 --- a/include/asterisk/bridge.h +++ b/include/asterisk/bridge.h @@ -290,6 +290,11 @@ struct ast_bridge_softmix { unsigned int internal_mixing_interval; /*! TRUE if binaural convolve is activated in configuration. */ unsigned int binaural_active; + /*! + * Add a "label" attribute to each stream in the SDP containing + * the channel uniqueid. Used for participant info correlation. + */ + unsigned int send_sdp_label; }; AST_LIST_HEAD_NOLOCK(ast_bridge_channels_list, ast_bridge_channel); @@ -985,6 +990,20 @@ void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel * */ const char *ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type video_mode); +/*! + * \brief Controls whether to send a "label" attribute in each stream in an SDP + * \since 16.1.0 + * + * \param bridge The bridge + * \param send_sdp_label Whether to send the labels or not + * + * \note The label will contain the uniqueid of the channel related to the stream. + * This is used to allow the recipient to correlate the stream to the participant + * information events sent by app_confbridge. + * The bridge will be locked in this function. + */ +void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label); + /*! * \brief Acquire the channel's bridge for transfer purposes. * \since 13.21.0 diff --git a/main/bridge.c b/main/bridge.c index 2b347fd3fb..9424f0f88f 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -4018,6 +4018,13 @@ const char *ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type vide } } +void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label) +{ + ast_bridge_lock(bridge); + bridge->softmix.send_sdp_label = send_sdp_label; + ast_bridge_unlock(bridge); +} + static int channel_hash(const void *obj, int flags) { const struct ast_channel *chan = obj;