From 13a482440f5d38d42a3442e821cf6865d55d9b75 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Thu, 7 Nov 2024 15:09:06 +0000 Subject: [PATCH] gstreamer: Include additional patches Out of the list only 0009-rtpfunnel-Ensure-segment-events-are-forwarded-after-.patch is going to ship in 1.24(.10). The others will ship in 1.26. --- ...-and-associate-transceivers-earlier-.patch | 16 +- ...-reverse-direction-from-remote-media.patch | 8 +- ...t-output-stream-on-recv-transceivers.patch | 28 +- ...-matching-pads-to-unassociated-trans.patch | 46 +++ ...5-webrtcbin-Fix-renegotiation-checks.patch | 275 ++++++++++++++++++ ...SRC-attributes-getting-CAPS-for-a-PT.patch | 144 +++++++++ ...allback-to-pad-default-handling-for-.patch | 192 ++++++++++++ ...le-forward-unknown-ssrc-on-rtpfunnel.patch | 30 ++ ...-segment-events-are-forwarded-after-.patch | 112 +++++++ .../wkdev_sdk/jhbuild/webkit-sdk-deps.modules | 14 +- 10 files changed, 834 insertions(+), 31 deletions(-) create mode 100644 images/wkdev_sdk/jhbuild/patches/0004-webrtc-Fixes-for-matching-pads-to-unassociated-trans.patch create mode 100644 images/wkdev_sdk/jhbuild/patches/0005-webrtcbin-Fix-renegotiation-checks.patch create mode 100644 images/wkdev_sdk/jhbuild/patches/0006-webrtc-add-all-SSRC-attributes-getting-CAPS-for-a-PT.patch create mode 100644 images/wkdev_sdk/jhbuild/patches/0007-rtpfunnel-also-fallback-to-pad-default-handling-for-.patch create mode 100644 images/wkdev_sdk/jhbuild/patches/0008-webrtcbin-enable-forward-unknown-ssrc-on-rtpfunnel.patch create mode 100644 images/wkdev_sdk/jhbuild/patches/0009-rtpfunnel-Ensure-segment-events-are-forwarded-after-.patch diff --git a/images/wkdev_sdk/jhbuild/patches/0001-webrtcbin-create-and-associate-transceivers-earlier-.patch b/images/wkdev_sdk/jhbuild/patches/0001-webrtcbin-create-and-associate-transceivers-earlier-.patch index 978423e..ed87b7f 100644 --- a/images/wkdev_sdk/jhbuild/patches/0001-webrtcbin-create-and-associate-transceivers-earlier-.patch +++ b/images/wkdev_sdk/jhbuild/patches/0001-webrtcbin-create-and-associate-transceivers-earlier-.patch @@ -1,7 +1,7 @@ -From 48ae40f477523bed4cd709d163f541e748356071 Mon Sep 17 00:00:00 2001 +From 8edcb3957601ba1237d3f60bbfc0f115a614aa75 Mon Sep 17 00:00:00 2001 From: Carlos Bentzen Date: Wed, 10 Jul 2024 10:34:19 +0200 -Subject: [PATCH] webrtcbin: create and associate transceivers earlier in +Subject: [PATCH 1/9] webrtcbin: create and associate transceivers earlier in negotation According to https://w3c.github.io/webrtc-pc/#set-the-session-description @@ -31,7 +31,7 @@ Part-of: webrtc1, "get-stats", NULL, p); -@@ -5905,7 +5968,7 @@ GST_START_TEST (test_sdp_session_setup_attribute) +@@ -5955,7 +6018,7 @@ GST_START_TEST (test_sdp_session_setup_attribute) fail_if (gst_element_set_state (t->webrtc2, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE); test_webrtc_create_offer (t); @@ -899,7 +899,7 @@ index 8fa8eeaf76..1dd2ddf3c2 100644 test_webrtc_wait_for_ice_gathering_complete (t); -@@ -5943,6 +6006,7 @@ webrtcbin_suite (void) +@@ -5993,6 +6056,7 @@ webrtcbin_suite (void) tcase_add_test (tc, test_media_direction); tcase_add_test (tc, test_add_transceiver); tcase_add_test (tc, test_get_transceivers); @@ -908,5 +908,5 @@ index 8fa8eeaf76..1dd2ddf3c2 100644 tcase_add_test (tc, test_recvonly_sendonly); tcase_add_test (tc, test_payload_types); -- -2.46.0 +2.47.0 diff --git a/images/wkdev_sdk/jhbuild/patches/0002-webrtcbin-reverse-direction-from-remote-media.patch b/images/wkdev_sdk/jhbuild/patches/0002-webrtcbin-reverse-direction-from-remote-media.patch index c90935d..b65e003 100644 --- a/images/wkdev_sdk/jhbuild/patches/0002-webrtcbin-reverse-direction-from-remote-media.patch +++ b/images/wkdev_sdk/jhbuild/patches/0002-webrtcbin-reverse-direction-from-remote-media.patch @@ -1,7 +1,7 @@ -From cad3e63546b17570e284b544afebb5566d75c6d7 Mon Sep 17 00:00:00 2001 +From 8615a8ac712bc173c0c3585392683053b7b8ee94 Mon Sep 17 00:00:00 2001 From: Carlos Bentzen Date: Fri, 2 Aug 2024 11:19:56 +0200 -Subject: [PATCH] webrtcbin: reverse direction from remote media +Subject: [PATCH 2/9] webrtcbin: reverse direction from remote media This had been overlooked from the spec. We need to reverse the remote media direction when setting the transceiver direction. @@ -12,7 +12,7 @@ Part-of: Date: Fri, 2 Aug 2024 11:21:13 +0200 -Subject: [PATCH] webrtcbin: connect output stream on recv transceivers +Subject: [PATCH 3/9] webrtcbin: connect output stream on recv transceivers With MR 7156, transceivers and transports are created earlier, but for sendrecv media we could get `not-linked` errors due to @@ -15,14 +15,14 @@ adds a test for this, so that this doesn't regress anymore. Part-of: --- .../gst-plugins-bad/ext/webrtc/gstwebrtcbin.c | 6 ++ - .../tests/check/elements/webrtcbin.c | 64 +++++++++++++++++++ - 2 files changed, 70 insertions(+) + .../tests/check/elements/webrtcbin.c | 62 +++++++++++++++++++ + 2 files changed, 68 insertions(+) diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c -index 8c8a6ab563..6861b50845 100644 +index 5ad6550d88..ec8fc47490 100644 --- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c -@@ -6490,6 +6490,12 @@ _create_and_associate_transceivers_from_sdp (GstWebRTCBin * webrtc, +@@ -6500,6 +6500,12 @@ _create_and_associate_transceivers_from_sdp (GstWebRTCBin * webrtc, webrtc_transceiver_set_transport (wtrans, stream); } } @@ -36,12 +36,12 @@ index 8c8a6ab563..6861b50845 100644 ret = TRUE; diff --git a/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c b/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c -index adf5014e02..bb13887422 100644 +index adf5014e02..2272943a27 100644 --- a/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c +++ b/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c -@@ -4653,6 +4653,69 @@ a=group:BUNDLE \r\n\ - - GST_END_TEST; +@@ -4651,6 +4651,67 @@ a=group:BUNDLE \r\n\ + test_webrtc_free (t); + } +GST_START_TEST (test_audio_sendrecv) +{ @@ -104,12 +104,10 @@ index adf5014e02..bb13887422 100644 + test_webrtc_free (t); +} + -+GST_END_TEST; -+ + GST_END_TEST; + static void - new_jitterbuffer_set_fast_start (GstElement * rtpbin, - GstElement * rtpjitterbuffer, guint session_id, guint ssrc, -@@ -6051,6 +6114,7 @@ webrtcbin_suite (void) +@@ -6051,6 +6112,7 @@ webrtcbin_suite (void) tcase_add_test (tc, test_session_stats); tcase_add_test (tc, test_stats_with_stream); tcase_add_test (tc, test_audio); diff --git a/images/wkdev_sdk/jhbuild/patches/0004-webrtc-Fixes-for-matching-pads-to-unassociated-trans.patch b/images/wkdev_sdk/jhbuild/patches/0004-webrtc-Fixes-for-matching-pads-to-unassociated-trans.patch new file mode 100644 index 0000000..51a5c6d --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0004-webrtc-Fixes-for-matching-pads-to-unassociated-trans.patch @@ -0,0 +1,46 @@ +From aaf06f221975d4ef771e81438da7179b4b3bdd00 Mon Sep 17 00:00:00 2001 +From: Jan Schmidt +Date: Wed, 24 Jul 2024 20:59:51 +1000 +Subject: [PATCH 4/9] webrtc: Fixes for matching pads to unassociated + transceivers + +Fix an inverted condition when checking if sink pad caps match +the codec-preference of an unassociated transceiver, and +fix a condition check for transceiver media kind to +avoid matching sinkpad requests where caps aren't provided +against unassociated transceivers where the caps might +not match later. + +Part-of: +--- + subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +index ec8fc47490..6a9484a2bc 100644 +--- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c ++++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +@@ -8355,9 +8355,9 @@ gst_webrtc_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, + GstWebRTCBinPad *pad2; + gboolean has_matching_caps; + +- /* Ignore transceivers with a non-matching kind */ ++ /* Ignore transceivers with a non-matching kind or where we don't know the kind we want */ + if (tmptrans->kind != GST_WEBRTC_KIND_UNKNOWN && +- kind != GST_WEBRTC_KIND_UNKNOWN && tmptrans->kind != kind) ++ (kind == GST_WEBRTC_KIND_UNKNOWN || tmptrans->kind != kind)) + continue; + + /* Ignore stopped transmitters */ +@@ -8379,7 +8379,7 @@ gst_webrtc_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, + + GST_OBJECT_LOCK (tmptrans); + has_matching_caps = (caps && tmptrans->codec_preferences && +- !gst_caps_can_intersect (caps, tmptrans->codec_preferences)); ++ gst_caps_can_intersect (caps, tmptrans->codec_preferences)); + GST_OBJECT_UNLOCK (tmptrans); + /* Ignore transceivers with non-matching caps */ + if (!has_matching_caps) +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/patches/0005-webrtcbin-Fix-renegotiation-checks.patch b/images/wkdev_sdk/jhbuild/patches/0005-webrtcbin-Fix-renegotiation-checks.patch new file mode 100644 index 0000000..0d9748e --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0005-webrtcbin-Fix-renegotiation-checks.patch @@ -0,0 +1,275 @@ +From 22e49d68ab4095379df2f0e3fa09ee61f3fb5624 Mon Sep 17 00:00:00 2001 +From: Jan Schmidt +Date: Thu, 1 Aug 2024 13:42:52 +1000 +Subject: [PATCH 5/9] webrtcbin: Fix renegotiation checks + +When checking for renegotiation against a local offer, +reverse the remote direction in the corresponding answer +to fix falsely not triggering on-negotiation needed when +switching (for example) from local sendrecv -> recvonly +against a peer that answered 'recvonly'. + +In the other direction, when the local was the answerer, +renegotiation might trigger when it didn't need to - +whenever the local transceiver direction differs from +the intersected direction we chose. Instead what we want +is to check if the intersected direction we would now +choose differs from what was previously chosen. + +This makes the behaviour in both cases match the +behaviour described in +https://www.w3.org/TR/webrtc/#dfn-check-if-negotiation-is-needed + +Part-of: +--- + .../gst-plugins-bad/ext/webrtc/gstwebrtcbin.c | 70 ++++++----- + .../tests/check/elements/webrtcbin.c | 113 ++++++++++++++++++ + 2 files changed, 151 insertions(+), 32 deletions(-) + +diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +index 6a9484a2bc..d8cf348f99 100644 +--- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c ++++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +@@ -1772,6 +1772,22 @@ done: + return res; + } + ++static GstWebRTCRTPTransceiverDirection ++_reverse_direction (GstWebRTCRTPTransceiverDirection direction) ++{ ++ switch (direction) { ++ case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE: ++ case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE: ++ case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV: ++ return direction; ++ case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY: ++ return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY; ++ case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY: ++ return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY; ++ } ++ return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE; ++} ++ + /* http://w3c.github.io/webrtc-pc/#dfn-check-if-negotiation-is-needed */ + static gboolean + _check_if_negotiation_is_needed (GstWebRTCBin * webrtc) +@@ -1861,33 +1877,39 @@ _check_if_negotiation_is_needed (GstWebRTCBin * webrtc) + /* If connection's currentLocalDescription if of type "offer", and + * the direction of the associated m= section in neither the offer + * nor answer matches t's direction, return "true". */ +- +- if (local_dir != trans->direction && remote_dir != trans->direction) { +- GST_LOG_OBJECT (webrtc, "transceiver direction (%s) doesn't match " +- "description (local %s remote %s)", ++ if (local_dir != trans->direction ++ && _reverse_direction (remote_dir) != trans->direction) { ++ GST_LOG_OBJECT (webrtc, ++ "transceiver direction (%s) doesn't match " ++ "description (local %s remote %s (reversed %s))", + gst_webrtc_rtp_transceiver_direction_to_string (trans->direction), + gst_webrtc_rtp_transceiver_direction_to_string (local_dir), +- gst_webrtc_rtp_transceiver_direction_to_string (remote_dir)); ++ gst_webrtc_rtp_transceiver_direction_to_string (remote_dir), ++ gst_webrtc_rtp_transceiver_direction_to_string (_reverse_direction ++ (remote_dir)) ++ ); + return TRUE; + } + } else if (webrtc->current_local_description->type == + GST_WEBRTC_SDP_TYPE_ANSWER) { +- GstWebRTCRTPTransceiverDirection intersect_dir; +- + /* If connection's currentLocalDescription if of type "answer", and +- * the direction of the associated m= section in the answer does not +- * match t's direction intersected with the offered direction (as +- * described in [JSEP] (section 5.3.1.)), return "true". */ ++ * the direction of the associated m= section in the answer we sent ++ * (local_dir) does not match t's direction intersected with the ++ * offer direction (as described in [JSEP] (section 5.3.1.)), ++ * return "true" because we want to propose a different ++ * direction now. */ + + /* remote is the offer, local is the answer */ +- intersect_dir = _intersect_answer_directions (remote_dir, local_dir); +- +- if (intersect_dir != trans->direction) { +- GST_LOG_OBJECT (webrtc, "transceiver direction (%s) doesn't match " +- "description intersected direction %s (local %s remote %s)", ++ GstWebRTCRTPTransceiverDirection now_intersect_dir = ++ _intersect_answer_directions (remote_dir, trans->direction); ++ if (now_intersect_dir != local_dir) { ++ GST_LOG_OBJECT (webrtc, ++ "transceiver direction (%s) doesn't match for the " ++ "new description intersected direction %s (prev local %s remote %s)", + gst_webrtc_rtp_transceiver_direction_to_string (trans->direction), + gst_webrtc_rtp_transceiver_direction_to_string (local_dir), +- gst_webrtc_rtp_transceiver_direction_to_string (intersect_dir), ++ gst_webrtc_rtp_transceiver_direction_to_string ++ (now_intersect_dir), + gst_webrtc_rtp_transceiver_direction_to_string (remote_dir)); + return TRUE; + } +@@ -6280,22 +6302,6 @@ get_last_generated_description (GstWebRTCBin * webrtc, SDPSource source, + return NULL; + } + +-static GstWebRTCRTPTransceiverDirection +-_reverse_direction (GstWebRTCRTPTransceiverDirection direction) +-{ +- switch (direction) { +- case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE: +- case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_INACTIVE: +- case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV: +- return direction; +- case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY: +- return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY; +- case GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY: +- return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY; +- } +- return GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_NONE; +-} +- + /* https://w3c.github.io/webrtc-pc/#set-description (steps in 4.6.10.) */ + static gboolean + _create_and_associate_transceivers_from_sdp (GstWebRTCBin * webrtc, +diff --git a/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c b/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c +index 2272943a27..e34f350ebd 100644 +--- a/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c ++++ b/subprojects/gst-plugins-bad/tests/check/elements/webrtcbin.c +@@ -719,6 +719,14 @@ test_webrtc_reset_negotiation (struct test_webrtc *t) + test_webrtc_signal_state (t, STATE_NEGOTIATION_NEEDED); + } + ++static void ++test_webrtc_clear_states (struct test_webrtc *t) ++{ ++ GST_DEBUG ("clearing states"); ++ g_array_free (t->states, TRUE); ++ t->states = g_array_new (FALSE, TRUE, sizeof (TestState)); ++} ++ + static void + test_webrtc_free (struct test_webrtc *t) + { +@@ -3789,6 +3797,110 @@ GST_START_TEST (test_renego_transceiver_set_direction) + + GST_END_TEST; + ++GST_START_TEST (test_renego_triggering) ++{ ++ ++ struct test_webrtc *t = create_audio_test (); ++ ++ VAL_SDP_INIT (no_duplicate_payloads, on_sdp_media_no_duplicate_payloads, ++ NULL, NULL); ++ ++ guint media_format_count[] = { 1 }; ++ VAL_SDP_INIT (media_formats, on_sdp_media_count_formats, ++ media_format_count, &no_duplicate_payloads); ++ VAL_SDP_INIT (count, _count_num_sdp_media, GUINT_TO_POINTER (1), ++ &media_formats); ++ ++ const gchar *expected_offer_setup[] = { "actpass" }; ++ VAL_SDP_INIT (offer_setup, on_sdp_media_setup, expected_offer_setup, &count); ++ const gchar *expected_answer_setup[] = { "active" }; ++ VAL_SDP_INIT (answer_setup, on_sdp_media_setup, expected_answer_setup, ++ &count); ++ const gchar *expected_offer_direction[] = { "sendrecv" }; ++ VAL_SDP_INIT (offer, on_sdp_media_direction, expected_offer_direction, ++ &offer_setup); ++ const gchar *expected_answer_direction[] = { "recvonly" }; ++ VAL_SDP_INIT (answer, on_sdp_media_direction, expected_answer_direction, ++ &answer_setup); ++ GstCaps *caps; ++ GArray *transceivers; ++ ++ /* Ensure sendrecv stream on webrtc1 */ ++ g_signal_emit_by_name (t->webrtc1, "get-transceivers", &transceivers); ++ fail_unless (transceivers != NULL); ++ fail_unless_equals_int (transceivers->len, 1); ++ ++ GstWebRTCRTPTransceiver *trans_local = ++ g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0); ++ g_object_set (trans_local, "direction", ++ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV, NULL); ++ ++ /* setup recvonly peer */ ++ caps = gst_caps_from_string (OPUS_RTP_CAPS (96)); ++ gst_caps_set_simple (caps, "ssrc", G_TYPE_UINT, 0xDEADBEEF, NULL); ++ ++ GstWebRTCRTPTransceiver *trans_remote = NULL; ++ GstWebRTCRTPTransceiverDirection direction = ++ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY; ++ g_signal_emit_by_name (t->webrtc2, "add-transceiver", direction, caps, ++ &trans_remote); ++ gst_caps_unref (caps); ++ fail_unless (trans_remote != NULL); ++ gst_object_unref (trans_remote); ++ ++ test_validate_sdp (t, &offer, &answer); ++ ++ GST_LOG ++ ("Finished validating sendrecv <-> recvonly nego. Triggering renego with recvonly <-> recvonly peers"); ++ ++ /* Now change the sender to recvonly and expect to renegotiate to inactive */ ++ test_webrtc_reset_negotiation (t); ++ test_webrtc_clear_states (t); ++ ++ GST_LOG ("Setting local transceiver to RECVONLY"); ++ g_object_set (trans_local, "direction", ++ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY, NULL); ++ ++ GST_LOG ("Waiting for on-negotiation-needed"); ++ test_webrtc_wait_for_state_mask (t, 1 << STATE_NEGOTIATION_NEEDED); ++ ++ const gchar *new_expected_offer_direction[] = { "recvonly" }; ++ VAL_SDP_INIT (new_offer, on_sdp_media_direction, new_expected_offer_direction, ++ NULL); ++ const gchar *new_expected_answer_direction[] = { "inactive" }; ++ VAL_SDP_INIT (new_answer, on_sdp_media_direction, ++ new_expected_answer_direction, NULL); ++ ++ test_validate_sdp (t, &new_offer, &new_answer); ++ ++ g_array_unref (transceivers); ++ ++ /* At this point webrtc2 is the answerer. Check that it also triggers nego ++ * if we change the direction to sendonly */ ++ test_webrtc_reset_negotiation (t); ++ test_webrtc_clear_states (t); ++ ++ GST_LOG ("Setting remote transceiver to SENDONLY"); ++ g_signal_emit_by_name (t->webrtc2, "get-transceivers", &transceivers); ++ fail_unless (transceivers != NULL); ++ fail_unless_equals_int (transceivers->len, 1); ++ ++ trans_remote = g_array_index (transceivers, GstWebRTCRTPTransceiver *, 0); ++ ++ g_object_set (trans_remote, "direction", ++ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY, NULL); ++ ++ g_array_unref (transceivers); ++ ++ GST_LOG ("Waiting for on-negotiation-needed"); ++ test_webrtc_wait_for_state_mask (t, 1 << STATE_NEGOTIATION_NEEDED); ++ ++ test_webrtc_free (t); ++} ++ ++GST_END_TEST; ++ ++ + static void + offer_remove_last_media (struct test_webrtc *t, GstElement * element, + GstPromise * promise, gpointer user_data) +@@ -6131,6 +6243,7 @@ webrtcbin_suite (void) + tcase_add_test (tc, test_bundle_renego_add_stream); + tcase_add_test (tc, test_bundle_max_compat_max_bundle_renego_add_stream); + tcase_add_test (tc, test_renego_transceiver_set_direction); ++ tcase_add_test (tc, test_renego_triggering); + tcase_add_test (tc, test_renego_lose_media_fails); + tcase_add_test (tc, + test_bundle_codec_preferences_rtx_no_duplicate_payloads); +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/patches/0006-webrtc-add-all-SSRC-attributes-getting-CAPS-for-a-PT.patch b/images/wkdev_sdk/jhbuild/patches/0006-webrtc-add-all-SSRC-attributes-getting-CAPS-for-a-PT.patch new file mode 100644 index 0000000..b28949e --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0006-webrtc-add-all-SSRC-attributes-getting-CAPS-for-a-PT.patch @@ -0,0 +1,144 @@ +From e2db93c386bb133ca7e4d3641007771de573695b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= +Date: Thu, 7 Mar 2024 17:36:33 +0100 +Subject: [PATCH 6/9] webrtc: add all SSRC attributes getting CAPS for a PT + +The transport stream only returned the CAPS for the first matching PT entry +from the `ptmap`. Other SSRC with the same PT where not included. For a stream +which bundled multiple audio streams for instance, only the first SSRC was +knowed to the SSRC demux and downstream elements. + +This commit adds all the `ssrc-` attributes from the matching PT entries. + +The RTP jitter buffer can now find the CNAME corresponding its SSRC even if it +was not the first to be registered for a particular PT. + +The RTP PT demux removes `ssrc-*` attributes cooresponding to other SSRCs +before pushing SSRC specific CAPS to downstream elements. + +Part-of: +--- + .../gst-plugins-bad/ext/webrtc/gstwebrtcbin.c | 5 ++-- + .../ext/webrtc/transportstream.c | 30 ++++++++++++++++--- + .../gst/rtpmanager/gstrtpptdemux.c | 28 +++++++++++++++++ + 3 files changed, 57 insertions(+), 6 deletions(-) + +diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +index d8cf348f99..2b920313d6 100644 +--- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c ++++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +@@ -5080,6 +5080,8 @@ _set_internal_rtpbin_element_props_from_stream (GstWebRTCBin * webrtc, + + GST_LOG_OBJECT (stream, "setting rtx mapping: %s -> %u", apt, rtx_pt[i]); + gst_structure_set (pt_map, apt, G_TYPE_UINT, rtx_pt[i], NULL); ++ ++ gst_caps_unref (rtx_caps); + } + + GST_DEBUG_OBJECT (stream, "setting payload map on %" GST_PTR_FORMAT " : %" +@@ -7562,8 +7564,7 @@ on_rtpbin_request_pt_map (GstElement * rtpbin, guint session_id, guint pt, + if (!stream) + goto unknown_session; + +- if ((ret = transport_stream_get_caps_for_pt (stream, pt))) +- gst_caps_ref (ret); ++ ret = transport_stream_get_caps_for_pt (stream, pt); + + GST_DEBUG_OBJECT (webrtc, "Found caps %" GST_PTR_FORMAT " for pt %d in " + "session %d", ret, pt, session_id); +diff --git a/subprojects/gst-plugins-bad/ext/webrtc/transportstream.c b/subprojects/gst-plugins-bad/ext/webrtc/transportstream.c +index f1811a025c..7462384df0 100644 +--- a/subprojects/gst-plugins-bad/ext/webrtc/transportstream.c ++++ b/subprojects/gst-plugins-bad/ext/webrtc/transportstream.c +@@ -47,15 +47,37 @@ enum + GstCaps * + transport_stream_get_caps_for_pt (TransportStream * stream, guint pt) + { +- guint i, len; ++ GstCaps *ret = NULL; ++ GstStructure *ret_s, *item_s; ++ guint i, len, si, slen; ++ const gchar *field_name; + + len = stream->ptmap->len; + for (i = 0; i < len; i++) { + PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i); +- if (item->pt == pt) +- return item->caps; ++ if (item->pt == pt) { ++ if (item->caps) { ++ if (ret == NULL) { ++ ret = gst_caps_copy (item->caps); ++ ret_s = gst_caps_get_structure (ret, 0); ++ } else { ++ /* Append the "ssrc-*" fields for current PT entry to ret */ ++ item_s = gst_caps_get_structure (item->caps, 0); ++ slen = gst_structure_n_fields (item_s); ++ for (si = 0; si < slen; ++si) { ++ field_name = gst_structure_nth_field_name (item_s, si); ++ if (!g_str_has_prefix (field_name, "ssrc-")) ++ continue; ++ ++ gst_structure_set (ret_s, field_name, G_TYPE_STRING, ++ gst_structure_get_string (item_s, field_name), NULL); ++ } ++ } ++ } ++ } + } +- return NULL; ++ ++ return ret; + } + + int +diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpptdemux.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpptdemux.c +index 0454d97134..7be4cc8945 100644 +--- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpptdemux.c ++++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpptdemux.c +@@ -312,6 +312,29 @@ gst_rtp_pt_demux_finalize (GObject * object) + G_OBJECT_CLASS (parent_class)->finalize (object); + } + ++/* Removes "ssrc-*" attributes matching other SSRCs. */ ++static gboolean ++_filter_ssrc (GQuark field_id, GValue * value, gpointer ssrc) ++{ ++ const gchar *field_name = g_quark_to_string (field_id); ++ ++ if (!g_str_has_prefix (field_name, "ssrc-")) ++ return TRUE; ++ ++ gchar *endptr; ++ guint32 field_ssrc = g_ascii_strtoll (field_name + 5, &endptr, 10); ++ ++ if (!endptr || *endptr != '-') ++ return TRUE; ++ ++ /* Found a valid "ssrc-*" */ ++ if (field_ssrc != *(guint32 *) ssrc) ++ /* Not the expected SSRC => remove this field */ ++ return FALSE; ++ ++ return TRUE; ++} ++ + static GstCaps * + gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt) + { +@@ -349,7 +372,12 @@ gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt) + } + + if (caps != NULL) { ++ GstStructure *s; ++ + caps = gst_caps_make_writable (caps); ++ s = gst_caps_get_structure (caps, 0); ++ gst_structure_filter_and_map_in_place (s, _filter_ssrc, &ssrc); ++ + gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL); + if (have_ssrc) + gst_caps_set_simple (caps, "ssrc", G_TYPE_UINT, ssrc, NULL); +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/patches/0007-rtpfunnel-also-fallback-to-pad-default-handling-for-.patch b/images/wkdev_sdk/jhbuild/patches/0007-rtpfunnel-also-fallback-to-pad-default-handling-for-.patch new file mode 100644 index 0000000..695e961 --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0007-rtpfunnel-also-fallback-to-pad-default-handling-for-.patch @@ -0,0 +1,192 @@ +From 49ff577a13a5b0e62ad7d06efedc3a91071e80fb Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Fri, 23 Aug 2024 20:01:32 +1000 +Subject: [PATCH 7/9] rtpfunnel: also fallback to pad default handling for + unknown ssrcs + +If two (or more) rtpfunnel elements are cascaded, then only one will +realistically have information on the particular ssrc that is in use for a +particular input stream. As such, any key unit requests may never reach the +corresponding encoder. + +This has been discovered by combining simulcast and BUNDLE with webrtcbin. +simulcast uses one rtpfunnel, and BUNDLE uses another rtpfunnel. + +Part-of: +--- + .../docs/gst_plugins_cache.json | 12 +++++++ + .../gst/rtpmanager/gstrtpfunnel.c | 34 +++++++++++++++++-- + .../tests/check/elements/rtpfunnel.c | 18 +++++++--- + 3 files changed, 58 insertions(+), 6 deletions(-) + +diff --git a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +index d270728a03..d02d1436d5 100644 +--- a/subprojects/gst-plugins-good/docs/gst_plugins_cache.json ++++ b/subprojects/gst-plugins-good/docs/gst_plugins_cache.json +@@ -18376,6 +18376,18 @@ + "readable": true, + "type": "gint", + "writable": true ++ }, ++ "forward-unknown-ssrc": { ++ "blurb": "Whether to forward events or queries that reference unknown SSRCs", ++ "conditionally-available": false, ++ "construct": false, ++ "construct-only": false, ++ "controllable": false, ++ "default": "false", ++ "mutable": "null", ++ "readable": true, ++ "type": "gboolean", ++ "writable": true + } + }, + "rank": "none" +diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c +index d403015e14..0e33d05b24 100644 +--- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c ++++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c +@@ -109,9 +109,11 @@ enum + { + PROP_0, + PROP_COMMON_TS_OFFSET, ++ PROP_FORWARD_UNKNOWN_SSRC, + }; + + #define DEFAULT_COMMON_TS_OFFSET -1 ++#define DEFAULT_FORWARD_UNKNOWN_SSRC FALSE + + struct _GstRtpFunnelClass + { +@@ -136,6 +138,7 @@ struct _GstRtpFunnel + + /* properties */ + gint common_ts_offset; ++ gboolean forward_unknown_ssrcs; + }; + + #define RTP_CAPS "application/x-rtp" +@@ -529,9 +532,10 @@ gst_rtp_funnel_src_event (GstPad * pad, GstObject * parent, GstEvent * event) + GstPad *fpad; + guint ssrc; + if (s && gst_structure_get_uint (s, "ssrc", &ssrc)) { +- handled = TRUE; ++ gboolean forward_unknown = FALSE; + + GST_OBJECT_LOCK (funnel); ++ forward_unknown = funnel->forward_unknown_ssrcs; + fpad = g_hash_table_lookup (funnel->ssrc_to_pad, GUINT_TO_POINTER (ssrc)); + if (fpad) + gst_object_ref (fpad); +@@ -542,8 +546,10 @@ gst_rtp_funnel_src_event (GstPad * pad, GstObject * parent, GstEvent * event) + event, fpad); + ret = gst_pad_push_event (fpad, event); + gst_object_unref (fpad); +- } else { ++ handled = TRUE; ++ } else if (!forward_unknown) { + gst_event_unref (event); ++ handled = TRUE; + } + } + } +@@ -600,6 +606,11 @@ gst_rtp_funnel_set_property (GObject * object, guint prop_id, + case PROP_COMMON_TS_OFFSET: + funnel->common_ts_offset = g_value_get_int (value); + break; ++ case PROP_FORWARD_UNKNOWN_SSRC: ++ GST_OBJECT_LOCK (funnel); ++ funnel->forward_unknown_ssrcs = g_value_get_boolean (value); ++ GST_OBJECT_UNLOCK (funnel); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -616,6 +627,11 @@ gst_rtp_funnel_get_property (GObject * object, guint prop_id, GValue * value, + case PROP_COMMON_TS_OFFSET: + g_value_set_int (value, funnel->common_ts_offset); + break; ++ case PROP_FORWARD_UNKNOWN_SSRC: ++ GST_OBJECT_LOCK (funnel); ++ g_value_set_boolean (value, funnel->forward_unknown_ssrcs); ++ GST_OBJECT_UNLOCK (funnel); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -706,6 +722,19 @@ gst_rtp_funnel_class_init (GstRtpFunnelClass * klass) + -1, G_MAXINT32, DEFAULT_COMMON_TS_OFFSET, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + ++ /** ++ * rtpfunnel:forward-unknown-ssrc: ++ * ++ * Whether to forward events or queries that reference unknown SSRCs. ++ * ++ * Since: 1.26 ++ */ ++ g_object_class_install_property (gobject_class, PROP_FORWARD_UNKNOWN_SSRC, ++ g_param_spec_boolean ("forward-unknown-ssrc", "Forward Unknown SSRC", ++ "Whether to forward events or queries that reference unknown SSRCs", ++ DEFAULT_FORWARD_UNKNOWN_SSRC, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); ++ + GST_DEBUG_CATEGORY_INIT (gst_rtp_funnel_debug, + "gstrtpfunnel", 0, "funnel element"); + } +@@ -723,4 +752,5 @@ gst_rtp_funnel_init (GstRtpFunnel * funnel) + funnel->srccaps = gst_caps_new_empty_simple (RTP_CAPS); + funnel->ssrc_to_pad = g_hash_table_new (NULL, NULL); + funnel->current_pad = NULL; ++ funnel->forward_unknown_ssrcs = DEFAULT_FORWARD_UNKNOWN_SSRC; + } +diff --git a/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c b/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c +index 676127ca18..1bb6be2a3d 100644 +--- a/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c ++++ b/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c +@@ -55,7 +55,7 @@ GST_START_TEST (rtpfunnel_ssrc_demuxing) + fail_unless_equals_int (2, gst_harness_upstream_events_received (h0)); + fail_unless_equals_int (2, gst_harness_upstream_events_received (h1)); + +- /* unknown ssrc, we drop it */ ++ /* unknown ssrc, we drop it by default */ + gst_harness_push_upstream_event (h, + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", +@@ -63,12 +63,22 @@ GST_START_TEST (rtpfunnel_ssrc_demuxing) + fail_unless_equals_int (2, gst_harness_upstream_events_received (h0)); + fail_unless_equals_int (2, gst_harness_upstream_events_received (h1)); + +- /* no ssrc, we send to all */ ++ /* unknown ssrc, we forward if property says to */ ++ g_object_set (h->element, "forward-unknown-ssrc", TRUE, NULL); + gst_harness_push_upstream_event (h, + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, +- gst_structure_new_empty ("GstForceKeyUnit"))); ++ gst_structure_new ("GstForceKeyUnit", ++ "ssrc", G_TYPE_UINT, 666, NULL))); + fail_unless_equals_int (3, gst_harness_upstream_events_received (h0)); + fail_unless_equals_int (3, gst_harness_upstream_events_received (h1)); ++ g_object_set (h->element, "forward-unknown-ssrc", FALSE, NULL); ++ ++ /* no ssrc, we send to all */ ++ gst_harness_push_upstream_event (h, ++ gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, ++ gst_structure_new_empty ("GstForceKeyUnit"))); ++ fail_unless_equals_int (4, gst_harness_upstream_events_received (h0)); ++ fail_unless_equals_int (4, gst_harness_upstream_events_received (h1)); + + /* remove pad 0, and send an event referencing the now dead ssrc */ + gst_harness_teardown (h0); +@@ -76,7 +86,7 @@ GST_START_TEST (rtpfunnel_ssrc_demuxing) + gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, + gst_structure_new ("GstForceKeyUnit", + "ssrc", G_TYPE_UINT, 123, NULL))); +- fail_unless_equals_int (3, gst_harness_upstream_events_received (h1)); ++ fail_unless_equals_int (4, gst_harness_upstream_events_received (h1)); + + gst_harness_teardown (h); + gst_harness_teardown (h1); +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/patches/0008-webrtcbin-enable-forward-unknown-ssrc-on-rtpfunnel.patch b/images/wkdev_sdk/jhbuild/patches/0008-webrtcbin-enable-forward-unknown-ssrc-on-rtpfunnel.patch new file mode 100644 index 0000000..9b76b3b --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0008-webrtcbin-enable-forward-unknown-ssrc-on-rtpfunnel.patch @@ -0,0 +1,30 @@ +From aae237495054cd49d7183f43d694736b9d71d64c Mon Sep 17 00:00:00 2001 +From: Matthew Waters +Date: Mon, 26 Aug 2024 14:46:59 +1000 +Subject: [PATCH 8/9] webrtcbin: enable forward-unknown-ssrc on rtpfunnel + +See also: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7405 + +Part-of: +--- + subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +index 2b920313d6..7d25858318 100644 +--- a/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c ++++ b/subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c +@@ -6044,6 +6044,10 @@ _connect_rtpfunnel (GstWebRTCBin * webrtc, guint session_id) + goto done; + + webrtc->rtpfunnel = gst_element_factory_make ("rtpfunnel", NULL); ++ if (g_object_class_find_property (G_OBJECT_GET_CLASS (webrtc->rtpfunnel), ++ "forward-unknown-ssrc") != NULL) { ++ g_object_set (webrtc->rtpfunnel, "forward-unknown-ssrc", TRUE, NULL); ++ } + gst_bin_add (GST_BIN (webrtc), webrtc->rtpfunnel); + gst_element_sync_state_with_parent (webrtc->rtpfunnel); + +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/patches/0009-rtpfunnel-Ensure-segment-events-are-forwarded-after-.patch b/images/wkdev_sdk/jhbuild/patches/0009-rtpfunnel-Ensure-segment-events-are-forwarded-after-.patch new file mode 100644 index 0000000..7a0649d --- /dev/null +++ b/images/wkdev_sdk/jhbuild/patches/0009-rtpfunnel-Ensure-segment-events-are-forwarded-after-.patch @@ -0,0 +1,112 @@ +From c2ab41b878dfaf9a83e94cc3fd5fc77e86272fd7 Mon Sep 17 00:00:00 2001 +From: Philippe Normand +Date: Tue, 5 Nov 2024 11:49:32 +0000 +Subject: [PATCH 9/9] rtpfunnel: Ensure segment events are forwarded after + flushs + +gst_rtp_funnel_forward_segment() returns early when the current_pad is set. +Without clearing current_pad a critical warning would be emitted when +attempting to chain a buffer following a flush. +--- + .../gst/rtpmanager/gstrtpfunnel.c | 11 +++++ + .../tests/check/elements/rtpfunnel.c | 41 +++++++++++++++++++ + 2 files changed, 52 insertions(+) + +diff --git a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c +index 0e33d05b24..ee819676ec 100644 +--- a/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c ++++ b/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpfunnel.c +@@ -443,6 +443,13 @@ gst_rtp_funnel_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) + forward = FALSE; + break; + } ++ case GST_EVENT_FLUSH_START: ++ /* By resetting current_pad here the segment will be forwarded next time a ++ buffer is received. */ ++ GST_OBJECT_LOCK (funnel); ++ funnel->current_pad = NULL; ++ GST_OBJECT_UNLOCK (funnel); ++ break; + default: + break; + } +@@ -649,6 +656,7 @@ gst_rtp_funnel_change_state (GstElement * element, GstStateChange transition) + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + funnel->send_sticky_events = TRUE; ++ funnel->current_pad = NULL; + break; + default: + break; +@@ -673,6 +681,9 @@ gst_rtp_funnel_release_pad (GstElement * element, GstPad * pad) + + GST_DEBUG_OBJECT (funnel, "releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad)); + ++ if (pad == funnel->current_pad) ++ funnel->current_pad = NULL; ++ + g_hash_table_foreach_remove (funnel->ssrc_to_pad, _remove_pad_func, pad); + + gst_pad_set_active (pad, FALSE); +diff --git a/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c b/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c +index 1bb6be2a3d..e755ea8500 100644 +--- a/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c ++++ b/subprojects/gst-plugins-good/tests/check/elements/rtpfunnel.c +@@ -501,6 +501,45 @@ GST_START_TEST (rtpfunnel_twcc_passthrough_then_mux) + + GST_END_TEST; + ++GST_START_TEST (rtpfunnel_flush) ++{ ++ GstHarness *h = gst_harness_new_with_padnames ("rtpfunnel", NULL, "src"); ++ GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL); ++ GstEvent *event; ++ GstBuffer *buffer; ++ ++ gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)123"); ++ ++ /* Push a buffer */ ++ fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h0, ++ generate_test_buffer (0, 123, 0))); ++ ++ buffer = gst_harness_try_pull (h); ++ gst_buffer_unref (buffer); ++ ++ /* Flush */ ++ fail_unless (gst_harness_push_event (h0, gst_event_new_flush_start ())); ++ fail_unless (gst_harness_push_event (h0, gst_event_new_flush_stop (TRUE))); ++ ++ while ((event = gst_harness_try_pull_event (h))) ++ gst_event_unref (event); ++ ++ /* Reset caps and segment */ ++ gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)123"); ++ ++ /* Push another buffer, this shouldn't generate "got data flow before segment event" criticals */ ++ fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h0, ++ generate_test_buffer (1, 123, 0))); ++ ++ buffer = gst_harness_try_pull (h); ++ gst_buffer_unref (buffer); ++ ++ gst_harness_teardown (h0); ++ gst_harness_teardown (h); ++} ++ ++GST_END_TEST; ++ + static Suite * + rtpfunnel_suite (void) + { +@@ -521,6 +560,8 @@ rtpfunnel_suite (void) + tcase_add_test (tc_chain, rtpfunnel_twcc_mux); + tcase_add_test (tc_chain, rtpfunnel_twcc_passthrough_then_mux); + ++ tcase_add_test (tc_chain, rtpfunnel_flush); ++ + return s; + } + +-- +2.47.0 + diff --git a/images/wkdev_sdk/jhbuild/webkit-sdk-deps.modules b/images/wkdev_sdk/jhbuild/webkit-sdk-deps.modules index 0e7eb05..1b4cca3 100644 --- a/images/wkdev_sdk/jhbuild/webkit-sdk-deps.modules +++ b/images/wkdev_sdk/jhbuild/webkit-sdk-deps.modules @@ -110,10 +110,16 @@ checkoutdir="gstreamer" module="gstreamer.git" tag="1.24.9"> - - - - + + + + + + + + + +