adaptivedemux2: Expose a max-retries property

So the user can configure what is the maximum number of time HTTP requests can
be performed

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8128>
This commit is contained in:
Thibault Saunier 2024-12-11 22:00:56 -03:00 committed by GStreamer Marge Bot
parent ba4a260c07
commit 6d0c0d5d29
6 changed files with 63 additions and 6 deletions

View File

@ -1404,6 +1404,20 @@
"type": "guint64",
"writable": true
},
"max-retries": {
"blurb": "Maximum number of retries for HTTP requests (-1=infinite)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "3",
"max": "2147483647",
"min": "-1",
"mutable": "null",
"readable": true,
"type": "gint",
"writable": true
},
"min-bitrate": {
"blurb": "Minimum bitrate to use when switching to alternates (bits/s)",
"conditionally-available": false,

View File

@ -36,7 +36,6 @@
G_BEGIN_DECLS
#define NUM_LOOKBACK_FRAGMENTS 3
#define MAX_DOWNLOAD_ERROR_COUNT 3
/* Internal, so not using GST_FLOW_CUSTOM_SUCCESS_N */
#define GST_ADAPTIVE_DEMUX_FLOW_SWITCH (GST_FLOW_CUSTOM_SUCCESS_2 + 2)
@ -164,6 +163,11 @@ struct _GstAdaptiveDemuxPrivate
* Head is the period being outputted, or to be outputted first
* Tail is where new streams get added */
GQueue *periods;
/* The maximum number of times HTTP request can be required before considering
* failed */
gint max_retries;
};
static inline gboolean gst_adaptive_demux_scheduler_lock(GstAdaptiveDemux *d)

View File

@ -1212,6 +1212,7 @@ on_download_error (DownloadRequest * request, DownloadRequestState state,
request->state, last_status_code,
stream->download_error_count, live, stream->download_error_retry);
gint max_retries = gst_adaptive_demux_max_retries (demux);
if (!stream->download_error_retry && ((last_status_code / 100 == 4 && live)
|| last_status_code / 100 == 5)) {
/* 4xx/5xx */
@ -1255,7 +1256,7 @@ on_download_error (DownloadRequest * request, DownloadRequestState state,
}
}
if (++stream->download_error_count >= MAX_DOWNLOAD_ERROR_COUNT) {
if (max_retries >= 0 && ++stream->download_error_count >= max_retries) {
/* 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 */
GST_DEBUG_OBJECT (stream, "Converting error of live stream to EOS");
@ -1271,7 +1272,7 @@ on_download_error (DownloadRequest * request, DownloadRequestState state,
return;
} else {
/* retry same segment */
if (++stream->download_error_count > MAX_DOWNLOAD_ERROR_COUNT) {
if (max_retries >= 0 && ++stream->download_error_count > max_retries) {
gst_adaptive_demux2_stream_error (stream);
return;
}
@ -2007,7 +2008,8 @@ gst_adaptive_demux2_stream_load_a_fragment (GstAdaptiveDemux2Stream * stream)
default:
if (ret <= GST_FLOW_ERROR) {
GST_WARNING_OBJECT (demux, "Error while downloading fragment");
if (++stream->download_error_count > MAX_DOWNLOAD_ERROR_COUNT) {
gint max_retries = gst_adaptive_demux_max_retries (demux);
if (max_retries >= 0 && ++stream->download_error_count > max_retries) {
gst_adaptive_demux2_stream_error (stream);
return FALSE;
}

View File

@ -113,6 +113,7 @@ GST_DEBUG_CATEGORY_EXTERN (adaptivedemux2_debug);
#define GST_CAT_DEFAULT adaptivedemux2_debug
#define DEFAULT_FAILED_COUNT 3
#define DEFAULT_MAX_RETRIES 3
#define DEFAULT_CONNECTION_BITRATE 0
#define DEFAULT_BANDWIDTH_TARGET_RATIO 0.8f
@ -133,6 +134,7 @@ enum
{
PROP_0,
PROP_CONNECTION_SPEED,
PROP_MAX_RETRIES,
PROP_BANDWIDTH_TARGET_RATIO,
PROP_CONNECTION_BITRATE,
PROP_MIN_BITRATE,
@ -288,6 +290,11 @@ gst_adaptive_demux_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (demux);
switch (prop_id) {
case PROP_MAX_RETRIES:
demux->priv->max_retries = g_value_get_int (value);
GST_DEBUG_OBJECT (demux, "Maximum retries set to %u",
demux->priv->max_retries);
break;
case PROP_CONNECTION_SPEED:
demux->connection_speed = g_value_get_uint (value) * 1000;
GST_DEBUG_OBJECT (demux, "Connection speed set to %u",
@ -339,6 +346,9 @@ gst_adaptive_demux_get_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (demux);
switch (prop_id) {
case PROP_MAX_RETRIES:
g_value_set_int (value, demux->priv->max_retries);
break;
case PROP_CONNECTION_SPEED:
g_value_set_uint (value, demux->connection_speed / 1000);
break;
@ -506,6 +516,20 @@ gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass)
G_PARAM_READABLE | GST_PARAM_MUTABLE_PLAYING |
G_PARAM_STATIC_STRINGS));
/**
* GstAdaptiveDemux2:max-retries:
*
* Maximum number of times HTTP request can be retried before considering
* the request as failed (-1=infinite)
*
* Since: 1.26
*/
g_object_class_install_property (gobject_class, PROP_MAX_RETRIES,
g_param_spec_int ("max-retries", "Maximum Retries",
"Maximum number of retries for HTTP requests (-1=infinite)",
-1, G_MAXUINT, DEFAULT_MAX_RETRIES,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_static_pad_template (gstelement_class,
&gst_adaptive_demux_audiosrc_template);
gst_element_class_add_static_pad_template (gstelement_class,
@ -588,6 +612,7 @@ gst_adaptive_demux_init (GstAdaptiveDemux * demux,
demux->current_level_time_video = DEFAULT_CURRENT_LEVEL_TIME_VIDEO;
demux->current_level_time_audio = DEFAULT_CURRENT_LEVEL_TIME_AUDIO;
demux->priv->max_retries = DEFAULT_MAX_RETRIES;
gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
@ -3004,7 +3029,7 @@ gst_adaptive_demux_manifest_update_cb (GstAdaptiveDemux * demux)
} else {
demux->priv->update_failed_count++;
if (demux->priv->update_failed_count <= DEFAULT_FAILED_COUNT) {
if (demux->priv->update_failed_count <= demux->priv->max_retries) {
GST_WARNING_OBJECT (demux, "Could not update the playlist, flow: %s",
gst_flow_get_name (ret));
} else {
@ -3956,3 +3981,13 @@ gst_adaptive_demux_get_loop (GstAdaptiveDemux * demux)
{
return gst_adaptive_demux_loop_ref (demux->priv->scheduler_task);
}
gint
gst_adaptive_demux_max_retries (GstAdaptiveDemux * self)
{
GST_OBJECT_LOCK (self);
gint res = self->priv->max_retries;
GST_OBJECT_UNLOCK (self);
return res;
}

View File

@ -481,6 +481,7 @@ gdouble gst_adaptive_demux_play_rate (GstAdaptiveDemux *demux);
void gst_adaptive_demux2_manual_manifest_update (GstAdaptiveDemux * demux);
GstAdaptiveDemuxLoop *gst_adaptive_demux_get_loop (GstAdaptiveDemux *demux);
gint gst_adaptive_demux_max_retries (GstAdaptiveDemux *self);
G_END_DECLS

View File

@ -470,7 +470,8 @@ static void
handle_download_error (GstHLSDemuxPlaylistLoader * pl,
GstHLSDemuxPlaylistLoaderPrivate * priv)
{
if (++priv->download_error_count > MAX_DOWNLOAD_ERROR_COUNT) {
gint max_retries = gst_adaptive_demux_max_retries (priv->demux);
if (max_retries >= 0 && ++priv->download_error_count > max_retries) {
GST_DEBUG_OBJECT (pl,
"Reached %d download failures on URI %s. Reporting the failure",
priv->download_error_count, priv->loading_playlist_uri);