mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-04 21:55:55 +00:00
webrtcbin: Sync to the clock per stream and not per bundle
By using the clocksync inside the dtlssrtpenc, all streams inside a bundled are synchronized together. This will cause problems if their buffers are not already arriving synchronized: clocksync would wait for a buffer on one stream and then buffers from the other stream(s) with lower timestamps would all be sent out too late. Placing the clocksync before the rtpbin and rtpfunnel synchronizes each stream individually and they will be send out more smoothly as a result. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2355>
This commit is contained in:
parent
ee0124cb36
commit
0e559fc2f3
|
@ -4045,37 +4045,39 @@ _connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad)
|
||||||
/*
|
/*
|
||||||
* Not-bundle case:
|
* Not-bundle case:
|
||||||
*
|
*
|
||||||
* ,-------------------------webrtcbin-------------------------,
|
* ,--------------------------------------------webrtcbin-------------------------,
|
||||||
* ; ;
|
* ; ;
|
||||||
* ; ,-------rtpbin-------, ,--transport_send_%u--, ;
|
* ; ,-------rtpbin-------, ,--transport_send_%u--, ;
|
||||||
* ; ; send_rtp_src_%u o---o rtp_sink ; ;
|
* ; ; send_rtp_src_%u o---o rtp_sink ; ;
|
||||||
* ; ; ; ; ; ;
|
* ; ,---clocksync---, ; ; ; ; ;
|
||||||
* ; ; send_rtcp_src_%u o---o rtcp_sink ; ;
|
* ; ; ; ; send_rtcp_src_%u o---o rtcp_sink ; ;
|
||||||
* ; sink_%u ; ; '---------------------' ;
|
* ; sink_%u ; ; ; ; '---------------------' ;
|
||||||
* o----------o send_rtp_sink_%u ; ;
|
* o---------o sink src o---o send_rtp_sink_%u ; ;
|
||||||
* ; '--------------------' ;
|
* ; '---------------' '--------------------' ;
|
||||||
* '--------------------- -------------------------------------'
|
* '------------------------------------------------------------------------------'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bundle case:
|
* Bundle case:
|
||||||
* ,--------------------------------webrtcbin--------------------------------,
|
* ,-----------------------------------------------------webrtcbin--------------------------------,
|
||||||
* ; ;
|
* ; ;
|
||||||
* ; ,-------rtpbin-------, ,--transport_send_%u--, ;
|
* ; ,-------rtpbin-------, ,--transport_send_%u--, ;
|
||||||
* ; ; send_rtp_src_%u o---o rtp_sink ; ;
|
* ; ; send_rtp_src_%u o---o rtp_sink ; ;
|
||||||
* ; ; ; ; ; ;
|
* ; ; ; ; ; ;
|
||||||
* ; ; send_rtcp_src_%u o---o rtcp_sink ; ;
|
* ; sink_%u ,---clocksync---, ,---funnel---, ; send_rtcp_src_%u o---o rtcp_sink ; ;
|
||||||
* ; sink_%u ,---funnel---, ; ; '---------------------' ;
|
* o----------o sink src o---o sink_%u ; ; ; '---------------------' ;
|
||||||
* o---------o sink_%u ; ; ; ;
|
* ; '---------------' ; ; ; ; ;
|
||||||
* ; sink_%u ; src o-o send_rtp_sink_%u ; ;
|
* ; ; src o-o send_rtp_sink_%u ; ;
|
||||||
* o---------o sink_%u ; ; ; ;
|
* ; sink_%u ,---clocksync---, ; ; ; ; ;
|
||||||
* ; '------------' '--------------------' ;
|
* o----------o sink src o---o sink%u ; '--------------------' ;
|
||||||
* '-------------------------------------------------------------------------'
|
* ; '---------------' '------------' ;
|
||||||
|
* '----------------------------------------------------------------------------------------------'
|
||||||
*/
|
*/
|
||||||
GstPadTemplate *rtp_templ;
|
GstPadTemplate *rtp_templ;
|
||||||
GstPad *rtp_sink;
|
GstPad *rtp_sink, *sinkpad, *srcpad;
|
||||||
gchar *pad_name;
|
gchar *pad_name;
|
||||||
WebRTCTransceiver *trans;
|
WebRTCTransceiver *trans;
|
||||||
|
GstElement *clocksync;
|
||||||
|
|
||||||
g_return_val_if_fail (pad->trans != NULL, NULL);
|
g_return_val_if_fail (pad->trans != NULL, NULL);
|
||||||
|
|
||||||
|
@ -4085,6 +4087,14 @@ _connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad)
|
||||||
|
|
||||||
g_assert (trans->stream);
|
g_assert (trans->stream);
|
||||||
|
|
||||||
|
clocksync = gst_element_factory_make ("clocksync", NULL);
|
||||||
|
g_object_set (clocksync, "sync", TRUE, NULL);
|
||||||
|
gst_bin_add (GST_BIN (webrtc), clocksync);
|
||||||
|
gst_element_sync_state_with_parent (clocksync);
|
||||||
|
|
||||||
|
srcpad = gst_element_get_static_pad (clocksync, "src");
|
||||||
|
sinkpad = gst_element_get_static_pad (clocksync, "sink");
|
||||||
|
|
||||||
if (!webrtc->rtpfunnel) {
|
if (!webrtc->rtpfunnel) {
|
||||||
rtp_templ =
|
rtp_templ =
|
||||||
_find_pad_template (webrtc->rtpbin, GST_PAD_SINK, GST_PAD_REQUEST,
|
_find_pad_template (webrtc->rtpbin, GST_PAD_SINK, GST_PAD_REQUEST,
|
||||||
|
@ -4095,9 +4105,11 @@ _connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad)
|
||||||
rtp_sink =
|
rtp_sink =
|
||||||
gst_element_request_pad (webrtc->rtpbin, rtp_templ, pad_name, NULL);
|
gst_element_request_pad (webrtc->rtpbin, rtp_templ, pad_name, NULL);
|
||||||
g_free (pad_name);
|
g_free (pad_name);
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), rtp_sink);
|
gst_pad_link (srcpad, rtp_sink);
|
||||||
gst_object_unref (rtp_sink);
|
gst_object_unref (rtp_sink);
|
||||||
|
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), sinkpad);
|
||||||
|
|
||||||
pad_name = g_strdup_printf ("send_rtp_src_%u", pad->trans->mline);
|
pad_name = g_strdup_printf ("send_rtp_src_%u", pad->trans->mline);
|
||||||
if (!gst_element_link_pads (GST_ELEMENT (webrtc->rtpbin), pad_name,
|
if (!gst_element_link_pads (GST_ELEMENT (webrtc->rtpbin), pad_name,
|
||||||
GST_ELEMENT (trans->stream->send_bin), "rtp_sink"))
|
GST_ELEMENT (trans->stream->send_bin), "rtp_sink"))
|
||||||
|
@ -4108,12 +4120,16 @@ _connect_input_stream (GstWebRTCBin * webrtc, GstWebRTCBinPad * pad)
|
||||||
GstPad *funnel_sinkpad =
|
GstPad *funnel_sinkpad =
|
||||||
gst_element_request_pad_simple (webrtc->rtpfunnel, pad_name);
|
gst_element_request_pad_simple (webrtc->rtpfunnel, pad_name);
|
||||||
|
|
||||||
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), funnel_sinkpad);
|
gst_pad_link (srcpad, funnel_sinkpad);
|
||||||
|
gst_ghost_pad_set_target (GST_GHOST_PAD (pad), sinkpad);
|
||||||
|
|
||||||
g_free (pad_name);
|
g_free (pad_name);
|
||||||
gst_object_unref (funnel_sinkpad);
|
gst_object_unref (funnel_sinkpad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
|
||||||
gst_element_sync_state_with_parent (GST_ELEMENT (trans->stream->send_bin));
|
gst_element_sync_state_with_parent (GST_ELEMENT (trans->stream->send_bin));
|
||||||
|
|
||||||
return GST_PAD (pad);
|
return GST_PAD (pad);
|
||||||
|
|
|
@ -184,7 +184,7 @@ gst_webrtc_dtls_transport_constructed (GObject * object)
|
||||||
|
|
||||||
webrtc->dtlssrtpenc = gst_element_factory_make ("dtlssrtpenc", NULL);
|
webrtc->dtlssrtpenc = gst_element_factory_make ("dtlssrtpenc", NULL);
|
||||||
g_object_set (webrtc->dtlssrtpenc, "connection-id", connection_id,
|
g_object_set (webrtc->dtlssrtpenc, "connection-id", connection_id,
|
||||||
"is-client", webrtc->client, "rtp-sync", TRUE, NULL);
|
"is-client", webrtc->client, "rtp-sync", FALSE, NULL);
|
||||||
|
|
||||||
webrtc->dtlssrtpdec = gst_element_factory_make ("dtlssrtpdec", NULL);
|
webrtc->dtlssrtpdec = gst_element_factory_make ("dtlssrtpdec", NULL);
|
||||||
g_object_set (webrtc->dtlssrtpdec, "connection-id", connection_id, NULL);
|
g_object_set (webrtc->dtlssrtpdec, "connection-id", connection_id, NULL);
|
||||||
|
|
Loading…
Reference in a new issue