mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
adaptivedemux2/hlsdemux2: Handle loss of sync when dowloading.
Media playlist updates and fragment downloads happen in an interleaved fashion. When a media playlist update fails *while* a segment is being downloaded, this means we lost synchronization. Properly propagate and handle this Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2839>
This commit is contained in:
parent
6a9bdceb5e
commit
5d0b112c0c
2 changed files with 29 additions and 5 deletions
|
@ -297,7 +297,12 @@ gst_adaptive_demux2_stream_finish_download (GstAdaptiveDemux2Stream *
|
|||
}
|
||||
|
||||
/* Handle all the possible flow returns here: */
|
||||
if (ret == GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT) {
|
||||
if (ret == GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC) {
|
||||
/* We lost sync, seek back to live and return */
|
||||
GST_WARNING_OBJECT (stream, "Lost sync when downloading");
|
||||
gst_adaptive_demux_handle_lost_sync (demux);
|
||||
return;
|
||||
} else if (ret == GST_ADAPTIVE_DEMUX_FLOW_END_OF_FRAGMENT) {
|
||||
/* The sub-class wants to stop the fragment immediately */
|
||||
stream->fragment.finished = TRUE;
|
||||
ret = klass->finish_fragment (demux, stream);
|
||||
|
|
|
@ -1476,7 +1476,17 @@ gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
|
|||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
g_assert (hls_stream->current_segment);
|
||||
/* If current segment is not present, this means that a playlist update
|
||||
* happened between the moment ::update_fragment_info() was called and the
|
||||
* moment we received data. And that playlist update couldn't match the
|
||||
* current position. This will happen in live playback when we are downloading
|
||||
* too slowly, therefore we try to "catch up" back to live
|
||||
*/
|
||||
if (hls_stream->current_segment == NULL) {
|
||||
GST_WARNING_OBJECT (stream, "Lost sync");
|
||||
return GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (stream,
|
||||
"buffer:%p at_eos:%d do_typefind:%d uri:%s", buffer, at_eos,
|
||||
hls_stream->do_typefind, hls_stream->current_segment->uri);
|
||||
|
@ -1562,7 +1572,7 @@ gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
|
|||
if (hls_stream->current_key)
|
||||
gst_hls_demux_stream_decrypt_end (hls_stream);
|
||||
|
||||
if (stream->last_ret == GST_FLOW_OK) {
|
||||
if (hls_stream->current_segment && stream->last_ret == GST_FLOW_OK) {
|
||||
if (hls_stream->pending_decrypted_buffer) {
|
||||
if (hls_stream->current_key) {
|
||||
GstMapInfo info;
|
||||
|
@ -1606,6 +1616,12 @@ gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
|
|||
if (G_UNLIKELY (stream->downloading_header || stream->downloading_index))
|
||||
return GST_FLOW_OK;
|
||||
|
||||
if (hls_stream->current_segment == NULL) {
|
||||
/* We can't advance, we just return OK for now and let the base class
|
||||
* trigger a new download (or fail and resync itself) */
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
if (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED) {
|
||||
/* We can update the stream current position with a more accurate value
|
||||
* before advancing. Note that we don't have any period so we can set the
|
||||
|
@ -1624,6 +1640,9 @@ gst_hls_demux_data_received (GstAdaptiveDemux * demux,
|
|||
GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
|
||||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||
|
||||
if (hls_stream->current_segment == NULL)
|
||||
return GST_ADAPTIVE_DEMUX_FLOW_LOST_SYNC;
|
||||
|
||||
if (hls_stream->current_offset == -1)
|
||||
hls_stream->current_offset = 0;
|
||||
|
||||
|
@ -2199,8 +2218,8 @@ gst_hls_demux_stream_update_rendition_playlist (GstHLSDemux * demux,
|
|||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
GstHLSRenditionStream *target_rendition =
|
||||
stream->pending_rendition ? stream->pending_rendition : stream->
|
||||
current_rendition;
|
||||
stream->pending_rendition ? stream->
|
||||
pending_rendition : stream->current_rendition;
|
||||
|
||||
ret = gst_hls_demux_stream_update_media_playlist (demux, stream,
|
||||
&target_rendition->uri, NULL);
|
||||
|
|
Loading…
Reference in a new issue