From f4f1819416f977b3c09382eb8715e0022e8ec41b Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 12 Aug 2022 21:57:25 +1000 Subject: [PATCH] adaptivedemux2: Fix for period switching in live streams When playing live, it's possible that one stream reaches the end of the available playback window and goes to sleep waiting for a manifest update, and the manifest update introduces a new period. In that case, the sleeping stream needs to wake up and go 'properly' EOS before we can advance the input to the new period. Accordingly, make sure that a stream's last_ret value is not marked as EOS if it's just sleeping waiting for a live manifest update. Also fix the output loop to go back and re-check if it's time to switch to the next period after dequeuing and discarding an EOS event. https://livesim.dashif.org/livesim/periods_20/testpic_2s/Manifest.mpd Part-of: --- .../gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c | 4 ++++ subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c index cfc0882..b56f1e9 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c @@ -1639,6 +1639,9 @@ gst_adaptive_demux2_stream_handle_playlist_eos (GstAdaptiveDemux2Stream * GST_DEBUG_OBJECT (stream, "Live playlist EOS - waiting for manifest update"); stream->state = GST_ADAPTIVE_DEMUX2_STREAM_STATE_WAITING_MANIFEST_UPDATE; + /* Clear the stream last_ret EOS state, since we're not actually EOS */ + if (stream->last_ret == GST_FLOW_EOS) + stream->last_ret = GST_FLOW_OK; gst_adaptive_demux2_stream_wants_manifest_update (demux); return; } @@ -1733,6 +1736,7 @@ gst_adaptive_demux2_stream_load_a_fragment (GstAdaptiveDemux2Stream * stream) break; /* all is good, let's go */ case GST_FLOW_EOS: GST_DEBUG_OBJECT (stream, "EOS, checking to stop download loop"); + stream->last_ret = ret; gst_adaptive_demux2_stream_handle_playlist_eos (stream); return FALSE; case GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC: diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c index f17f6c4..9923a18 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c @@ -3647,6 +3647,8 @@ restart: * * Pop next pending data from track and update pending position * */ + gboolean need_restart = FALSE; + for (tmp = demux->priv->outputs; tmp; tmp = tmp->next) { OutputSlot *slot = (OutputSlot *) tmp->data; GstAdaptiveDemuxTrack *track = slot->track; @@ -3708,6 +3710,8 @@ restart: gst_event_store_mark_delivered (&track->sticky_events, event); gst_event_unref (event); event = NULL; + /* We'll need to re-check if all tracks are empty again above */ + need_restart = TRUE; } } @@ -3756,6 +3760,9 @@ restart: if (global_output_position != GST_CLOCK_STIME_NONE) demux->priv->global_output_position = global_output_position; + if (need_restart) + goto restart; + if (global_output_position == GST_CLOCK_STIME_NONE) { if (!demux->priv->flushing) { GST_DEBUG_OBJECT (demux, -- 2.7.4