mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +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
2 changed files with 42 additions and 26 deletions
|
@ -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