From bd92b2f7c4f28b6fac854ddbdae08b821adb55c4 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 26 Nov 2018 22:10:57 +1100 Subject: [PATCH] webrtc: fix answer creation with multiple streams and similar caps --- ext/webrtc/gstwebrtcbin.c | 13 ++++++++++++- tests/check/elements/webrtcbin.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index 6d4a49b..fa07ed4 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -2396,6 +2396,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) GString *bundled_mids = NULL; gchar *bundle_ufrag = NULL; gchar *bundle_pwd = NULL; + GList *seen_transceivers = NULL; if (!webrtc->pending_remote_description) { GST_ERROR_OBJECT (webrtc, @@ -2576,6 +2577,13 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) rtp_trans = g_array_index (webrtc->priv->transceivers, GstWebRTCRTPTransceiver *, j); + + if (g_list_find (seen_transceivers, rtp_trans)) { + /* Don't double allocate a transceiver to multiple mlines */ + rtp_trans = NULL; + continue; + } + trans_caps = _find_codec_preferences (webrtc, rtp_trans, GST_PAD_SINK, j); @@ -2590,7 +2598,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) if (answer_caps && !gst_caps_is_empty (answer_caps)) { GST_LOG_OBJECT (webrtc, "found compatible transceiver %" GST_PTR_FORMAT - " for offer media %u", trans, i); + " for offer media %u", rtp_trans, i); if (trans_caps) gst_caps_unref (trans_caps); break; @@ -2619,6 +2627,7 @@ _create_answer_task (GstWebRTCBin * webrtc, const GstStructure * options) answer_dir = GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY; answer_caps = gst_caps_ref (offer_caps); } + seen_transceivers = g_list_prepend (seen_transceivers, rtp_trans); if (!rtp_trans) { trans = _create_webrtc_transceiver (webrtc, answer_dir, i); @@ -2724,6 +2733,8 @@ out: if (bundled) g_strfreev (bundled); + g_list_free (seen_transceivers); + return ret; } diff --git a/tests/check/elements/webrtcbin.c b/tests/check/elements/webrtcbin.c index 523d3b0..7bed3e7 100644 --- a/tests/check/elements/webrtcbin.c +++ b/tests/check/elements/webrtcbin.c @@ -2213,6 +2213,47 @@ GST_START_TEST (test_duplicate_nego) GST_END_TEST; +GST_START_TEST (test_dual_audio) +{ + struct test_webrtc *t = create_audio_test (); + const gchar *expected_offer[] = { "sendrecv", "sendrecv", }; + const gchar *expected_answer[] = { "sendrecv", "recvonly" }; + struct validate_sdp offer = { on_sdp_media_direction, expected_offer, NULL }; + struct validate_sdp answer = + { on_sdp_media_direction, expected_answer, NULL }; + GstHarness *h; + GstWebRTCRTPTransceiver *trans; + GArray *transceivers; + + /* test that each mline gets a unique transceiver even with the same caps */ + + h = gst_harness_new_with_element (t->webrtc1, "sink_1", NULL); + add_fake_audio_src_harness (h, 96); + t->harnesses = g_list_prepend (t->harnesses, h); + + h = gst_harness_new_with_element (t->webrtc2, "sink_0", NULL); + add_fake_audio_src_harness (h, 96); + t->harnesses = g_list_prepend (t->harnesses, h); + + t->on_negotiation_needed = NULL; + test_validate_sdp (t, &offer, &answer); + + g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers); + fail_unless (transceivers != NULL); + fail_unless_equals_int (2, transceivers->len); + + trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0); + fail_unless (trans != NULL); + fail_unless_equals_int (trans->mline, 0); + + trans = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 1); + fail_unless (trans != NULL); + fail_unless_equals_int (trans->mline, 1); + + g_array_unref (transceivers); + test_webrtc_free (t); +} + static Suite * webrtcbin_suite (void) { @@ -2247,6 +2288,7 @@ webrtcbin_suite (void) tcase_add_test (tc, test_bundle_audio_video_max_bundle_max_bundle); tcase_add_test (tc, test_bundle_audio_video_max_bundle_none); tcase_add_test (tc, test_bundle_audio_video_max_compat_max_bundle); + tcase_add_test (tc, test_dual_audio); tcase_add_test (tc, test_duplicate_nego); if (sctpenc && sctpdec) { tcase_add_test (tc, test_data_channel_create); -- 2.7.4