streamsynchronizer: Fix deadlock when streams have been flushed before others start

To simplify the description, I'm assuming we only have two streams: video and audio.

For the video stream, we have the following events :
- STREAM_START => stream->wait set to true
- NEW_SEGMENT(1) => blocked waiting in gst_stream_synchronizer_wait
- FLUSH_START => unblocked
- FLUSH_STOP => stream->wait reset to false
- NEW_SEGMENT(2) => not waiting, since stream->wait is false

Then for the audio stream, we have the following events :
- STREAM_START => stream->wait set to true
- NEW_SEGMENT(2) => blocked waiting in gst_stream_synchronizer_wait for ever.

Note: The first NEW_SEGMENT event and the FLUSH_START, FLUSH_STOP events of the audio stream
are dropped before being received by the streamsynchronizer element, because the decodebin audio pad src
is not yet linked to the playsink audio pad sink.

To fix this deadlock, we don't reset stream->wait to false in the FLUSH_STOP event when it is not
waiting for the EOS of the other streams.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6887>
This commit is contained in:
Yacine Bandou 2024-04-29 12:15:20 +02:00 committed by Backport Bot
parent a084bedd58
commit 1b191d1d8d

View file

@ -595,10 +595,12 @@ gst_stream_synchronizer_sink_event (GstPad * pad, GstObject * parent,
gst_segment_init (&stream->segment, GST_FORMAT_UNDEFINED);
}
stream->is_eos = FALSE;
if (stream->is_eos) {
stream->wait = FALSE;
stream->is_eos = FALSE;
}
stream->eos_sent = FALSE;
stream->flushing = FALSE;
stream->wait = FALSE;
g_cond_broadcast (&stream->stream_finish_cond);
if (reset_time) {