mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-18 13:25:56 +00:00
adaptivedemux2: Fix download error handling more
gst_adaptive_demux2_stream_finish_download() will already schedule another fragment download if it can so don't fall through to the retry code that will also try and schedule a download (triggering an assert). Fix the logic in general to retry advancing into the live seek range once. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
parent
b1354058e1
commit
6bb74ed2a0
2 changed files with 44 additions and 40 deletions
|
@ -1200,39 +1200,32 @@ on_download_error (DownloadRequest * request, DownloadRequestState state,
|
||||||
stream->download_active = FALSE;
|
stream->download_active = FALSE;
|
||||||
stream->last_status_code = last_status_code;
|
stream->last_status_code = last_status_code;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream,
|
|
||||||
"Download finished with error, request state %d http status %u, dc %d",
|
|
||||||
request->state, last_status_code, stream->download_error_count);
|
|
||||||
|
|
||||||
live = gst_adaptive_demux_is_live (demux);
|
live = gst_adaptive_demux_is_live (demux);
|
||||||
if (((last_status_code / 100 == 4 && live)
|
|
||||||
|
GST_DEBUG_OBJECT (stream,
|
||||||
|
"Download finished with error, request state %d http status %u, dc %d "
|
||||||
|
"live %d retried %d",
|
||||||
|
request->state, last_status_code,
|
||||||
|
stream->download_error_count, live, stream->download_error_retry);
|
||||||
|
|
||||||
|
if (!stream->download_error_retry && ((last_status_code / 100 == 4 && live)
|
||||||
|| last_status_code / 100 == 5)) {
|
|| last_status_code / 100 == 5)) {
|
||||||
/* 4xx/5xx */
|
/* 4xx/5xx */
|
||||||
/* if current position is before available start, switch to next */
|
/* if current position is before available start, switch to next */
|
||||||
if (live) {
|
if (live) {
|
||||||
gint64 range_start, range_stop;
|
gint64 range_start, range_stop;
|
||||||
|
|
||||||
if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
|
if (gst_adaptive_demux_get_live_seek_range (demux, &range_start,
|
||||||
&range_stop))
|
&range_stop)) {
|
||||||
goto flushing;
|
|
||||||
|
|
||||||
if (demux->segment.position < range_start) {
|
if (demux->segment.position < range_start) {
|
||||||
GstFlowReturn ret;
|
/* This should advance into the valid playlist range */
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream, "Retrying once with next segment");
|
GST_DEBUG_OBJECT (stream, "Retrying once with next segment");
|
||||||
gst_adaptive_demux2_stream_finish_download (stream, GST_FLOW_EOS, NULL);
|
stream->download_error_retry = TRUE;
|
||||||
|
gst_adaptive_demux2_stream_finish_download (stream, GST_FLOW_OK,
|
||||||
GST_DEBUG_OBJECT (demux, "Calling update_fragment_info");
|
NULL);
|
||||||
|
return;
|
||||||
ret = gst_adaptive_demux2_stream_update_fragment_info (stream);
|
|
||||||
GST_DEBUG_OBJECT (stream, "update_fragment_info ret: %s",
|
|
||||||
gst_flow_get_name (ret));
|
|
||||||
|
|
||||||
if (ret == GST_FLOW_OK)
|
|
||||||
goto again;
|
|
||||||
|
|
||||||
} else if (demux->segment.position > range_stop) {
|
} else if (demux->segment.position > range_stop) {
|
||||||
/* wait a bit to be in range, we don't have any locks at that point */
|
/* wait a bit to be in range */
|
||||||
GstClockTime wait_time =
|
GstClockTime wait_time =
|
||||||
gst_adaptive_demux2_stream_get_fragment_waiting_time (stream);
|
gst_adaptive_demux2_stream_get_fragment_waiting_time (stream);
|
||||||
if (wait_time > 0) {
|
if (wait_time > 0) {
|
||||||
|
@ -1240,17 +1233,24 @@ on_download_error (DownloadRequest * request, DownloadRequestState state,
|
||||||
"Download waiting for %" GST_TIME_FORMAT,
|
"Download waiting for %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (wait_time));
|
GST_TIME_ARGS (wait_time));
|
||||||
g_assert (stream->pending_cb_id == 0);
|
g_assert (stream->pending_cb_id == 0);
|
||||||
GST_LOG_OBJECT (stream, "Scheduling delayed load_a_fragment() call");
|
GST_LOG_OBJECT (stream,
|
||||||
|
"Scheduling delayed load_a_fragment() call");
|
||||||
stream->pending_cb_id =
|
stream->pending_cb_id =
|
||||||
gst_adaptive_demux_loop_call_delayed (demux->priv->scheduler_task,
|
gst_adaptive_demux_loop_call_delayed (demux->
|
||||||
wait_time,
|
priv->scheduler_task, wait_time,
|
||||||
(GSourceFunc) gst_adaptive_demux2_stream_load_a_fragment,
|
(GSourceFunc) gst_adaptive_demux2_stream_load_a_fragment,
|
||||||
gst_object_ref (stream), (GDestroyNotify) gst_object_unref);
|
gst_object_ref (stream), (GDestroyNotify) gst_object_unref);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
GST_LOG_OBJECT (stream,
|
||||||
|
"Failed segment is inside the live range, retrying");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GST_LOG_OBJECT (stream, "Could not get live seek range after error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flushing:
|
|
||||||
if (stream->download_error_count >= MAX_DOWNLOAD_ERROR_COUNT) {
|
if (stream->download_error_count >= MAX_DOWNLOAD_ERROR_COUNT) {
|
||||||
/* looks like there is no way of knowing when a live stream has ended
|
/* looks like there is no way of knowing when a live stream has ended
|
||||||
* Have to assume we are falling behind and cause a manifest reload */
|
* Have to assume we are falling behind and cause a manifest reload */
|
||||||
|
@ -1371,6 +1371,7 @@ on_download_complete (DownloadRequest * request, DownloadRequestState state,
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
|
|
||||||
stream->download_active = FALSE;
|
stream->download_active = FALSE;
|
||||||
|
stream->download_error_retry = FALSE;
|
||||||
|
|
||||||
if (stream->state != GST_ADAPTIVE_DEMUX2_STREAM_STATE_DOWNLOADING) {
|
if (stream->state != GST_ADAPTIVE_DEMUX2_STREAM_STATE_DOWNLOADING) {
|
||||||
GST_DEBUG_OBJECT (stream, "Stream state changed to %d. Aborting",
|
GST_DEBUG_OBJECT (stream, "Stream state changed to %d. Aborting",
|
||||||
|
@ -2193,6 +2194,8 @@ gst_adaptive_demux2_stream_stop_default (GstAdaptiveDemux2Stream * stream)
|
||||||
stream->downloading_header = stream->downloading_index = FALSE;
|
stream->downloading_header = stream->downloading_index = FALSE;
|
||||||
stream->download_request = download_request_new ();
|
stream->download_request = download_request_new ();
|
||||||
stream->download_active = FALSE;
|
stream->download_active = FALSE;
|
||||||
|
stream->download_error_retry = FALSE;
|
||||||
|
stream->download_error_count = 0;
|
||||||
|
|
||||||
stream->next_input_wakeup_time = GST_CLOCK_STIME_NONE;
|
stream->next_input_wakeup_time = GST_CLOCK_STIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,6 +342,7 @@ struct _GstAdaptiveDemux2Stream
|
||||||
|
|
||||||
GstAdaptiveDemux2StreamFragment fragment;
|
GstAdaptiveDemux2StreamFragment fragment;
|
||||||
|
|
||||||
|
gboolean download_error_retry;
|
||||||
guint download_error_count;
|
guint download_error_count;
|
||||||
|
|
||||||
/* Last collection provided by parsebin */
|
/* Last collection provided by parsebin */
|
||||||
|
|
Loading…
Reference in a new issue