From c16d4d2c33e4af301110897634414fc878b76481 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 6 Feb 2020 14:27:42 +0200 Subject: [PATCH] webrtcbin: Add a blocking pad probe for the receivebin -> sctpdec connection Without this it might happen that received data from the DTLS transport is already passed to sctpdec before its state was set to PLAYING. This would cause the data to be dropped, GST_FLOW_FLUSHING to be returned and the whole DTLS transport to shut down. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/1172 among other things. --- ext/webrtc/gstwebrtcbin.c | 41 +++++++++++++++++++++++++++++++++-------- ext/webrtc/sctptransport.h | 1 + 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/ext/webrtc/gstwebrtcbin.c b/ext/webrtc/gstwebrtcbin.c index a28d914..9a82672 100644 --- a/ext/webrtc/gstwebrtcbin.c +++ b/ext/webrtc/gstwebrtcbin.c @@ -1821,6 +1821,18 @@ _sctp_check_dtls_state_task (GstWebRTCBin * webrtc, gpointer unused) gst_element_sync_state_with_parent (GST_ELEMENT (sctp_transport->sctpdec)); gst_element_sync_state_with_parent (GST_ELEMENT (sctp_transport->sctpenc)); + if (sctp_transport->sctpdec_block_id) { + GstPad *receive_srcpad; + + receive_srcpad = + gst_element_get_static_pad (GST_ELEMENT (stream->receive_bin), + "data_src"); + gst_pad_remove_probe (receive_srcpad, sctp_transport->sctpdec_block_id); + + sctp_transport->sctpdec_block_id = 0; + gst_object_unref (receive_srcpad); + } + g_signal_handlers_disconnect_by_func (transport, _on_sctp_notify_dtls_state, webrtc); } @@ -1844,6 +1856,14 @@ _on_sctp_notify_dtls_state (GstWebRTCDTLSTransport * transport, } } +static GstPadProbeReturn +pad_block (GstPad * pad, GstPadProbeInfo * info, gpointer unused) +{ + GST_LOG_OBJECT (pad, "blocking pad with data %" GST_PTR_FORMAT, info->data); + + return GST_PAD_PROBE_OK; +} + static TransportStream * _get_or_create_data_channel_transports (GstWebRTCBin * webrtc, guint session_id) { @@ -1885,6 +1905,19 @@ _get_or_create_data_channel_transports (GstWebRTCBin * webrtc, guint session_id) g_signal_connect (sctp_transport, "notify::state", G_CALLBACK (_on_sctp_state_notify), webrtc); + if (sctp_transport->sctpdec_block_id == 0) { + GstPad *receive_srcpad; + receive_srcpad = + gst_element_get_static_pad (GST_ELEMENT (stream->receive_bin), + "data_src"); + sctp_transport->sctpdec_block_id = + gst_pad_add_probe (receive_srcpad, + GST_PAD_PROBE_TYPE_BLOCK | + GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST, + (GstPadProbeCallback) pad_block, NULL, NULL); + gst_object_unref (receive_srcpad); + } + if (!gst_element_link_pads (GST_ELEMENT (stream->receive_bin), "data_src", GST_ELEMENT (sctp_transport->sctpdec), "sink")) g_warn_if_reached (); @@ -5424,14 +5457,6 @@ gst_webrtc_bin_change_state (GstElement * element, GstStateChange transition) return ret; } -static GstPadProbeReturn -pad_block (GstPad * pad, GstPadProbeInfo * info, gpointer unused) -{ - GST_LOG_OBJECT (pad, "blocking pad with data %" GST_PTR_FORMAT, info->data); - - return GST_PAD_PROBE_OK; -} - static GstPad * gst_webrtc_bin_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * name, const GstCaps * caps) diff --git a/ext/webrtc/sctptransport.h b/ext/webrtc/sctptransport.h index d5327a7..212f15e 100644 --- a/ext/webrtc/sctptransport.h +++ b/ext/webrtc/sctptransport.h @@ -47,6 +47,7 @@ struct _GstWebRTCSCTPTransport gboolean association_established; + gulong sctpdec_block_id; GstElement *sctpdec; GstElement *sctpenc; -- 2.7.4