From ed425e2785e96b8c1385e4cad7f0df16afb19f42 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 20 Apr 2022 17:35:29 +0300 Subject: [PATCH] rtpgstpay: Don't push packets before the first input buffer is received It's not possible to create a valid RTP timestamp for them, which would cause a potentially very big RTP timestamp discontinuity between those first packets (created from initial events) and the packet based on the first input buffer. As a side-effect, also simplify the packet aggregation code a bit and work with only a single level of buffer lists. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1157 Part-of: --- .../gst-plugins-good/gst/rtp/gstrtpgstpay.c | 32 +++++++++++----------- .../gst-plugins-good/gst/rtp/gstrtpgstpay.h | 4 ++- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.c b/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.c index c76a38e..5dba040 100644 --- a/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.c +++ b/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.c @@ -171,8 +171,7 @@ gst_rtp_gst_pay_reset (GstRtpGSTPay * rtpgstpay, gboolean full) rtpgstpay->flags &= 0x70; rtpgstpay->etype = 0; if (rtpgstpay->pending_buffers) - g_list_free_full (rtpgstpay->pending_buffers, - (GDestroyNotify) gst_buffer_list_unref); + gst_buffer_list_unref (rtpgstpay->pending_buffers); rtpgstpay->pending_buffers = NULL; if (full) { if (rtpgstpay->taglist) @@ -183,6 +182,7 @@ gst_rtp_gst_pay_reset (GstRtpGSTPay * rtpgstpay, gboolean full) rtpgstpay->current_CV = 0; rtpgstpay->next_CV = 0; } + rtpgstpay->received_buffer = FALSE; } static void @@ -271,7 +271,6 @@ gst_rtp_gst_pay_create_from_adapter (GstRtpGSTPay * rtpgstpay, { guint avail, mtu; guint frag_offset; - GstBufferList *list; avail = gst_adapter_available (rtpgstpay->adapter); if (avail == 0) @@ -279,7 +278,9 @@ gst_rtp_gst_pay_create_from_adapter (GstRtpGSTPay * rtpgstpay, mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpgstpay); - list = gst_buffer_list_new_sized ((avail / (mtu - (RTP_HEADER_LEN + 8))) + 1); + if (!rtpgstpay->pending_buffers) + rtpgstpay->pending_buffers = + gst_buffer_list_new_sized ((avail / (mtu - (RTP_HEADER_LEN + 8))) + 1); frag_offset = 0; while (avail) { @@ -356,12 +357,11 @@ gst_rtp_gst_pay_create_from_adapter (GstRtpGSTPay * rtpgstpay, GST_BUFFER_PTS (outbuf) = timestamp; /* and add to list */ - gst_buffer_list_insert (list, -1, outbuf); + gst_buffer_list_insert (rtpgstpay->pending_buffers, -1, outbuf); } rtpgstpay->flags &= 0x70; rtpgstpay->etype = 0; - rtpgstpay->pending_buffers = g_list_append (rtpgstpay->pending_buffers, list); return TRUE; } @@ -370,22 +370,20 @@ static GstFlowReturn gst_rtp_gst_pay_flush (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp) { GstFlowReturn ret = GST_FLOW_OK; - GList *iter; gst_rtp_gst_pay_create_from_adapter (rtpgstpay, timestamp); - iter = rtpgstpay->pending_buffers; - while (iter) { - GstBufferList *list = iter->data; - - rtpgstpay->pending_buffers = iter = - g_list_delete_link (rtpgstpay->pending_buffers, iter); + if (!rtpgstpay->received_buffer) { + GST_DEBUG_OBJECT (rtpgstpay, + "Can't flush without having received a buffer yet"); + return GST_FLOW_OK; + } + if (rtpgstpay->pending_buffers) { /* push the whole buffer list at once */ ret = gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpgstpay), - list); - if (ret != GST_FLOW_OK) - break; + rtpgstpay->pending_buffers); + rtpgstpay->pending_buffers = NULL; } return ret; @@ -656,6 +654,8 @@ gst_rtp_gst_pay_handle_buffer (GstRTPBasePayload * basepayload, rtpgstpay = GST_RTP_GST_PAY (basepayload); + rtpgstpay->received_buffer = TRUE; + timestamp = GST_BUFFER_PTS (buffer); running_time = gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME, diff --git a/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.h b/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.h index 2294e17..671186b 100644 --- a/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.h +++ b/subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.h @@ -44,7 +44,7 @@ struct _GstRtpGSTPay { GstRTPBasePayload payload; - GList *pending_buffers; /* GstBufferList */ + GstBufferList *pending_buffers; GstAdapter *adapter; guint8 flags; guint8 etype; @@ -57,6 +57,8 @@ struct _GstRtpGSTPay guint config_interval; GstClockTime last_config; gboolean force_config; + + gboolean received_buffer; }; struct _GstRtpGSTPayClass -- 2.7.4