mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +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: */
|
/* 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 */
|
/* The sub-class wants to stop the fragment immediately */
|
||||||
stream->fragment.finished = TRUE;
|
stream->fragment.finished = TRUE;
|
||||||
ret = klass->finish_fragment (demux, stream);
|
ret = klass->finish_fragment (demux, stream);
|
||||||
|
|
|
@ -1476,7 +1476,17 @@ gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
|
||||||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
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,
|
GST_DEBUG_OBJECT (stream,
|
||||||
"buffer:%p at_eos:%d do_typefind:%d uri:%s", buffer, at_eos,
|
"buffer:%p at_eos:%d do_typefind:%d uri:%s", buffer, at_eos,
|
||||||
hls_stream->do_typefind, hls_stream->current_segment->uri);
|
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)
|
if (hls_stream->current_key)
|
||||||
gst_hls_demux_stream_decrypt_end (hls_stream);
|
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->pending_decrypted_buffer) {
|
||||||
if (hls_stream->current_key) {
|
if (hls_stream->current_key) {
|
||||||
GstMapInfo info;
|
GstMapInfo info;
|
||||||
|
@ -1606,6 +1616,12 @@ gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
|
||||||
if (G_UNLIKELY (stream->downloading_header || stream->downloading_index))
|
if (G_UNLIKELY (stream->downloading_header || stream->downloading_index))
|
||||||
return GST_FLOW_OK;
|
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) {
|
if (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED) {
|
||||||
/* We can update the stream current position with a more accurate value
|
/* 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
|
* 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);
|
GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
|
||||||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
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)
|
if (hls_stream->current_offset == -1)
|
||||||
hls_stream->current_offset = 0;
|
hls_stream->current_offset = 0;
|
||||||
|
|
||||||
|
@ -2199,8 +2218,8 @@ gst_hls_demux_stream_update_rendition_playlist (GstHLSDemux * demux,
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstHLSRenditionStream *target_rendition =
|
GstHLSRenditionStream *target_rendition =
|
||||||
stream->pending_rendition ? stream->pending_rendition : stream->
|
stream->pending_rendition ? stream->
|
||||||
current_rendition;
|
pending_rendition : stream->current_rendition;
|
||||||
|
|
||||||
ret = gst_hls_demux_stream_update_media_playlist (demux, stream,
|
ret = gst_hls_demux_stream_update_media_playlist (demux, stream,
|
||||||
&target_rendition->uri, NULL);
|
&target_rendition->uri, NULL);
|
||||||
|
|
Loading…
Reference in a new issue