baseparse: loses (doesn't propagate) sticky events after a flush
Context
gst_base_parse_sink_event_default()
stores serialized events in pending_events
rather than propagating them immediately through the srcpad, except for events specifically whitelisted with the forward_immediate
flag (Namely: SEGMENT_DONE, FLUSH_STOP, EOS, CUSTOM_DOWNSTREAM, GAP and STREAM_START):
if (event) {
if (!GST_EVENT_IS_SERIALIZED (event) || forward_immediate) {
ret = gst_pad_push_event (parse->srcpad, event);
} else {
parse->priv->pending_events =
g_list_prepend (parse->priv->pending_events, event);
ret = TRUE;
}
}
pending_events
is later read from gst_base_parse_push_pending_events()
, which is called by gst_base_parse_push_frame()
. In a way, this is similar to sticky events, but it's done for all events and handled specifically by baseparse.
pending_events
was introduced in 2012 in 495aca49, and originally was only for SEGMENT events. Later, 257ad2c7 made it apply to all serialized events.
gst_base_parse_clear_queues()
clears the entire pending_events
. This is called by gst_base_parse_sink_event_default()
on FLUSH_STOP, and also by gst_base_parse_handle_seek()
when handling a flushing seek.
The bug
If a flush occurs after the STREAM_COLLECTION event but before the first buffer is pushed, the STREAM_COLLECTION is lost forever as the queue is cleared, and therefore the STREAM_COLLECTION is never sent downstream.
When upstream is stream-collection-aware, decodebin3 expects STREAM_COLLECTION to arrive before the first buffer, and therefore this bug causes all the buffers to be lost to not-linked
once they arrive to decodebin3.
Reproducibility
Reproduced on both 1.24.9 and main.
This is one of several bugs that can be frequently reproduced with WEBKIT_GST_ALLOW_PLAYBACK_OF_INVISIBLE_VIDEOS=1 epiphany "https://www.apple.com/macbook-air/"
.