decodebin3: Fix keyframe drop probe handling

We were storing the probe id in a different structure (DecodebinOutputStream)
than the pad it is targetting (which is in MultiQueueSlot).

The problem is that when re-targetting outputs (to a different slot)... we would
end up having an invalid probe id, or not have a reference to an existing one.

Instead, store the probe id in the same structure as the pad it's targetting

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7074>
This commit is contained in:
Edward Hervey 2024-06-20 11:37:33 +02:00 committed by Backport Bot
parent 455ca1326b
commit 6615af3f5f

View file

@ -429,6 +429,9 @@ typedef struct _MultiQueueSlot
/* id of the MQ src_pad event probe */ /* id of the MQ src_pad event probe */
gulong probe_id; gulong probe_id;
/* keyframe dropping probe */
gulong drop_probe_id;
/* TRUE if EOS was pushed out by multiqueue */ /* TRUE if EOS was pushed out by multiqueue */
gboolean is_drained; gboolean is_drained;
@ -456,9 +459,6 @@ struct _DecodebinOutputStream
/* Reported decoder latency */ /* Reported decoder latency */
GstClockTime decoder_latency; GstClockTime decoder_latency;
/* keyframe dropping probe */
gulong drop_probe_id;
}; };
/* properties */ /* properties */
@ -3789,7 +3789,7 @@ create_decoder_factory_list (GstDecodebin3 * dbin, GstCaps * caps)
static GstPadProbeReturn static GstPadProbeReturn
keyframe_waiter_probe (GstPad * pad, GstPadProbeInfo * info, keyframe_waiter_probe (GstPad * pad, GstPadProbeInfo * info,
DecodebinOutputStream * output) MultiQueueSlot * slot)
{ {
GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info); GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
@ -3798,7 +3798,7 @@ keyframe_waiter_probe (GstPad * pad, GstPadProbeInfo * info,
GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER)) { GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER)) {
GST_DEBUG_OBJECT (pad, GST_DEBUG_OBJECT (pad,
"Buffer is keyframe or header, letting through and removing probe"); "Buffer is keyframe or header, letting through and removing probe");
output->drop_probe_id = 0; slot->drop_probe_id = 0;
return GST_PAD_PROBE_REMOVE; return GST_PAD_PROBE_REMOVE;
} }
GST_DEBUG_OBJECT (pad, "Buffer is not a keyframe, dropping"); GST_DEBUG_OBJECT (pad, "Buffer is not a keyframe, dropping");
@ -4001,11 +4001,11 @@ db_output_stream_setup_decoder (DecodebinOutputStream * output,
gst_plugin_feature_list_free (factories); gst_plugin_feature_list_free (factories);
done: done:
if (output->type & GST_STREAM_TYPE_VIDEO) { if (output->type & GST_STREAM_TYPE_VIDEO && slot->drop_probe_id == 0) {
GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe"); GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
output->drop_probe_id = slot->drop_probe_id =
gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER, gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
(GstPadProbeCallback) keyframe_waiter_probe, output, NULL); (GstPadProbeCallback) keyframe_waiter_probe, slot, NULL);
} }
/* Set the decode pad target */ /* Set the decode pad target */
@ -4090,11 +4090,11 @@ db_output_stream_reconfigure (DecodebinOutputStream * output, GstMessage ** msg)
"Reusing existing decoder '%" GST_PTR_FORMAT "' for slot %p", "Reusing existing decoder '%" GST_PTR_FORMAT "' for slot %p",
output->decoder, slot); output->decoder, slot);
/* Re-add the keyframe-waiter probe */ /* Re-add the keyframe-waiter probe */
if (output->type & GST_STREAM_TYPE_VIDEO && output->drop_probe_id == 0) { if (output->type & GST_STREAM_TYPE_VIDEO && slot->drop_probe_id == 0) {
GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe"); GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
output->drop_probe_id = slot->drop_probe_id =
gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER, gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
(GstPadProbeCallback) keyframe_waiter_probe, output, NULL); (GstPadProbeCallback) keyframe_waiter_probe, slot, NULL);
} }
if (output->linked == FALSE) { if (output->linked == FALSE) {
gst_pad_link_full (slot->src_pad, output->decoder_sink, gst_pad_link_full (slot->src_pad, output->decoder_sink,
@ -4538,6 +4538,8 @@ mq_slot_free (GstDecodebin3 * dbin, MultiQueueSlot * slot)
{ {
if (slot->probe_id) if (slot->probe_id)
gst_pad_remove_probe (slot->src_pad, slot->probe_id); gst_pad_remove_probe (slot->src_pad, slot->probe_id);
if (slot->drop_probe_id)
gst_pad_remove_probe (slot->src_pad, slot->drop_probe_id);
if (slot->input) { if (slot->input) {
if (slot->input->srcpad) if (slot->input->srcpad)
gst_pad_unlink (slot->input->srcpad, slot->sink_pad); gst_pad_unlink (slot->input->srcpad, slot->sink_pad);
@ -4638,9 +4640,9 @@ db_output_stream_reset (DecodebinOutputStream * output)
} }
output->linked = FALSE; output->linked = FALSE;
if (slot && output->drop_probe_id) { if (slot && slot->drop_probe_id) {
gst_pad_remove_probe (slot->src_pad, output->drop_probe_id); gst_pad_remove_probe (slot->src_pad, slot->drop_probe_id);
output->drop_probe_id = 0; slot->drop_probe_id = 0;
} }
/* Remove/Reset pads */ /* Remove/Reset pads */