rtpbasepayload: always store input buffer meta before negotiation

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>
This commit is contained in:
Mathieu Duponchelle 2022-04-27 02:08:00 +02:00 committed by GStreamer Marge Bot
parent 4cd3830bc8
commit a03db32bbe

View 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;