From 00fa625677e1943d78ff6974e34b57229861931d Mon Sep 17 00:00:00 2001 From: Sergei Date: Thu, 8 Jan 2026 16:32:33 +0100 Subject: [PATCH] gst/gstpad: Invoke pad probe callback only once when pushing buffer lists When pushing a buffer list through a pad that does not implement a custom chainlist function (i.e. it uses gst_pad_chain_list_default), and a pad probe is installed that handles both buffer lists and individual buffers, the probe callback is invoked twice: - once for the buffer list itself - once for each buffer in the list, via the default chainlist function From within the probe callback, it is not possible to distinguish whether buffers are received as part of a buffer list or as individual buffers, which can lead to buffers being processed multiple times. Use case Consider a section of a pipeline where both individual buffers and buffer lists may flow, and a pad is selected dynamically such that it is not known in advance whether the pad supports a custom chainlist function. A pad probe is attached to this pad and is expected to handle both individual buffers and buffer lists uniformly. With the current behavior, pads without a custom chainlist function invoke the probe callback multiple times for the same buffers when a buffer list is pushed, while pads with a custom chainlist function invoke the probe callback only once for the buffer list. This results in inconsistent probe behavior depending on the pad implementation. To address this inconsistency, skip invoking the pad probe callback for the buffer list when the pad does not have a custom chainlist function. In this case, the default chainlist implementation will invoke the probe callback for each buffer in the list. Pads with a custom chainlist function continue to receive the probe callback for the buffer list as before, ensuring consistent and predictable probe semantics. --- subprojects/gstreamer/gst/gstpad.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/subprojects/gstreamer/gst/gstpad.c b/subprojects/gstreamer/gst/gstpad.c index f22190e955..22c5260068 100644 --- a/subprojects/gstreamer/gst/gstpad.c +++ b/subprojects/gstreamer/gst/gstpad.c @@ -4503,11 +4503,15 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data) pad->priv->last_cookie = pad->priv->events_cookie; } #endif - - PROBE_HANDLE (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped, + /* When buffer list is being pushed and the pad has a default chainlistfunc, + * we don't need to call the probes, as default chainlistfunc will + * call eventualy probes for each buffer in the list. */ + if ((!(type & GST_PAD_PROBE_TYPE_BUFFER_LIST)) + || (GST_PAD_CHAINLISTFUNC (pad) != gst_pad_chain_list_default)) { + PROBE_HANDLE (pad, type | GST_PAD_PROBE_TYPE_BLOCK, data, probe_stopped, probe_handled); - - PROBE_HANDLE (pad, type, data, probe_stopped, probe_handled); + PROBE_HANDLE (pad, type, data, probe_stopped, probe_handled); + } ACQUIRE_PARENT (pad, parent, no_parent); GST_OBJECT_UNLOCK (pad);