decodebin3: Don't send sticky events to unlinked decoder

This causes a lot of nasty side effects (like decoders assuming they are
actually linked downstream).

The reason why this was done was to check whether a decoder could handle the
actual caps, but this is the wrong way to do it.

The proper way to query whether a decoder can handle certain caps is via
`GST_QUERY_ACCEPT_CAPS` which is already done just before.

Partially reverts !4677 and partially fixes #3160

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5821>
This commit is contained in:
Edward Hervey 2023-12-18 09:23:14 +01:00 committed by Edward Hervey
parent 533f814fd9
commit 2d57bec920

View file

@ -899,37 +899,6 @@ decode_pad_set_target (GstGhostPad * pad, GstPad * target)
return res; return res;
} }
typedef struct
{
gboolean ret;
GstPad *peer;
} SendStickyEventsData;
static gboolean
send_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
{
SendStickyEventsData *data = user_data;
data->ret &= gst_pad_send_event (data->peer, gst_event_ref (*event));
return data->ret;
}
static gboolean
send_sticky_events (GstDecodebin3 * dbin, GstPad * pad)
{
SendStickyEventsData data;
data.ret = TRUE;
data.peer = gst_pad_get_peer (pad);
gst_pad_sticky_events_foreach (pad, send_sticky_event, &data);
gst_object_unref (data.peer);
return data.ret;
}
static CandidateDecoder * static CandidateDecoder *
add_candidate_decoder (GstDecodebin3 * dbin, GstElement * element) add_candidate_decoder (GstDecodebin3 * dbin, GstElement * element)
{ {
@ -3008,24 +2977,14 @@ reconfigure_output_stream (DecodebinOutputStream * output,
goto try_next; goto try_next;
} }
/* First lock element's sinkpad stream lock so no data reaches
* the possible new element added when caps are sent by element
* while we're still sending sticky events */
GST_PAD_STREAM_LOCK (output->decoder_sink);
if (gst_element_set_state (output->decoder, if (gst_element_set_state (output->decoder,
GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE || GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
!send_sticky_events (dbin, slot->src_pad)) { GST_WARNING_OBJECT (dbin, "Decoder '%s' failed to reach PAUSED state",
GST_PAD_STREAM_UNLOCK (output->decoder_sink);
GST_WARNING_OBJECT (dbin,
"Decoder '%s' failed to reach PAUSED state",
GST_ELEMENT_NAME (output->decoder)); GST_ELEMENT_NAME (output->decoder));
decoder_failed = TRUE; decoder_failed = TRUE;
goto try_next; goto try_next;
} else { } else {
/* Everything went well */ /* Everything went well */
GST_PAD_STREAM_UNLOCK (output->decoder_sink);
output->linked = TRUE; output->linked = TRUE;
GST_DEBUG ("created decoder %" GST_PTR_FORMAT, output->decoder); GST_DEBUG ("created decoder %" GST_PTR_FORMAT, output->decoder);