rtpgstpay: Don't push packets before the first input buffer is received
authorSebastian Dröge <sebastian@centricular.com>
Wed, 20 Apr 2022 14:35:29 +0000 (17:35 +0300)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 27 Apr 2022 11:55:17 +0000 (11:55 +0000)
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2250>

subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.c
subprojects/gst-plugins-good/gst/rtp/gstrtpgstpay.h

index c76a38e..5dba040 100644 (file)
@@ -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,
index 2294e17..671186b 100644 (file)
@@ -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