rtpbasepayload: always store input buffer meta before negotiation
authorMathieu Duponchelle <mathieu@centricular.com>
Wed, 27 Apr 2022 00:08:00 +0000 (02:08 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 27 Apr 2022 08:43:30 +0000 (08:43 +0000)
The decision to store the input buffer depends on whether extensions
are to be added to the output buffer, I assume as an optimization.

This creates an issue for subclasses that call negotiate(), where
header_exts is actually populated, from their handle_buffer()
implementation: at chain time, no header extension has been negotiated
yet, which means that we don't add extensions to the first batch of
buffers that comes out.

Keep track of whether negotiate has been called (this is different
from the negotiated field) and always store the input buffer until
then. This fixes the issue while largely preserving the optimization.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2304>

subprojects/gst-plugins-base/gst-libs/gst/rtp/gstrtpbasepayload.c

index 2c5728e7113ec7ea6a3e028125d3e33b69b415c8..f7cd5593151fd8ac427a4fbbba0e33b8dc7bcb43 100644 (file)
@@ -63,6 +63,13 @@ struct _GstRTPBasePayloadPrivate
 
   gboolean negotiated;
 
+  /* We need to know whether negotiate was called in order to decide
+   * whether we should store the input buffer as input meta in case
+   * negotiate() gets called from the subclass' handle_buffer() implementation,
+   * as negotiate() is where we instantiate header extensions.
+   */
+  gboolean negotiate_called;
+
   gboolean delay_segment;
   GstEvent *pending_segment;
 
@@ -840,7 +847,8 @@ gst_rtp_base_payload_chain (GstPad * pad, GstObject * parent,
     goto not_negotiated;
 
   if (rtpbasepayload->priv->source_info
-      || rtpbasepayload->priv->header_exts->len > 0) {
+      || rtpbasepayload->priv->header_exts->len > 0
+      || !rtpbasepayload->priv->negotiate_called) {
     /* Save a copy of meta (instead of taking an extra reference before
      * handle_buffer) to make the meta available when allocating a output
      * buffer. */
@@ -1508,6 +1516,7 @@ gst_rtp_base_payload_negotiate (GstRTPBasePayload * payload)
   gst_caps_unref (templ);
 
 out:
+  payload->priv->negotiate_called = TRUE;
 
   if (!res)
     gst_pad_mark_reconfigure (GST_RTP_BASE_PAYLOAD_SRCPAD (payload));
@@ -2285,6 +2294,7 @@ gst_rtp_base_payload_change_state (GstElement * element,
       g_atomic_int_set (&rtpbasepayload->priv->notified_first_timestamp, 1);
       priv->base_offset = GST_BUFFER_OFFSET_NONE;
       priv->negotiated = FALSE;
+      priv->negotiate_called = FALSE;
       gst_caps_replace (&rtpbasepayload->priv->subclass_srccaps, NULL);
       gst_caps_replace (&rtpbasepayload->priv->sinkcaps, NULL);
       break;