From 0962908e62e1f688af8f4decc704551a1fb64e07 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 15 Dec 2022 02:27:27 +1100 Subject: [PATCH] adaptivedemux2: Add start/stop vfuncs Remove the can_start() vfunc, in favour of vfuncs when the stream starts/stops, allowing the sub-class to do custom logic before (or preventing) the stream from starting and stopping. Part-of: --- .../adaptivedemux2/gstadaptivedemux-stream.c | 51 ++++++++++--------- .../adaptivedemux2/gstadaptivedemux-stream.h | 22 ++++++-- .../adaptivedemux2/hls/gsthlsdemux-stream.c | 24 +++++++-- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c index e69d62c930..93bb81ddeb 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.c @@ -53,6 +53,10 @@ static void gst_adaptive_demux2_stream_update_track_ids (GstAdaptiveDemux2Stream static GstFlowReturn gst_adaptive_demux2_stream_submit_request_default (GstAdaptiveDemux2Stream * stream, DownloadRequest * download_req); +static void +gst_adaptive_demux2_stream_start_default (GstAdaptiveDemux2Stream * stream); +static void +gst_adaptive_demux2_stream_stop_default (GstAdaptiveDemux2Stream * stream); #define gst_adaptive_demux2_stream_parent_class parent_class G_DEFINE_ABSTRACT_TYPE (GstAdaptiveDemux2Stream, gst_adaptive_demux2_stream, @@ -65,6 +69,8 @@ gst_adaptive_demux2_stream_class_init (GstAdaptiveDemux2StreamClass * klass) gobject_class->finalize = gst_adaptive_demux2_stream_finalize; + klass->start = gst_adaptive_demux2_stream_start_default; + klass->stop = gst_adaptive_demux2_stream_stop_default; klass->data_received = gst_adaptive_demux2_stream_data_received_default; klass->finish_fragment = gst_adaptive_demux2_stream_finish_fragment_default; klass->submit_request = gst_adaptive_demux2_stream_submit_request_default; @@ -2066,45 +2072,35 @@ gst_adaptive_demux2_stream_next_download (GstAdaptiveDemux2Stream * stream) return gst_adaptive_demux2_stream_load_a_fragment (stream); } -static gboolean -gst_adaptive_demux2_stream_can_start (GstAdaptiveDemux2Stream * stream) -{ - GstAdaptiveDemux2StreamClass *klass = - GST_ADAPTIVE_DEMUX2_STREAM_GET_CLASS (stream); - - if (!klass->can_start) - return TRUE; - return klass->can_start (stream); -} - /** * gst_adaptive_demux2_stream_start: * @stream: a #GstAdaptiveDemux2Stream * - * Start the given @stream. Should be called by subclasses that previously - * returned %FALSE in `GstAdaptiveDemux::stream_can_start()` + * Start the given @stream. Can be called by subclasses that previously + * returned %FALSE in `GstAdaptiveDemux2Stream::start()`, or from + * the demuxer when a stream should start downloading. */ void gst_adaptive_demux2_stream_start (GstAdaptiveDemux2Stream * stream) { - GstAdaptiveDemux *demux; - g_return_if_fail (stream && stream->demux); - demux = stream->demux; - if (stream->pending_cb_id != 0 || stream->download_active) { /* There is already something active / pending on this stream */ GST_LOG_OBJECT (stream, "Stream already running"); return; } - /* Some streams require a delayed start, i.e. they need more information - * before they can actually be started */ - if (!gst_adaptive_demux2_stream_can_start (stream)) { - GST_LOG_OBJECT (stream, "Stream will be started asynchronously"); - return; - } + GstAdaptiveDemux2StreamClass *klass = + GST_ADAPTIVE_DEMUX2_STREAM_GET_CLASS (stream); + + klass->start (stream); +} + +static void +gst_adaptive_demux2_stream_start_default (GstAdaptiveDemux2Stream * stream) +{ + GstAdaptiveDemux *demux = stream->demux; if (stream->state == GST_ADAPTIVE_DEMUX2_STREAM_STATE_EOS) { GST_LOG_OBJECT (stream, "Stream is EOS already"); @@ -2130,6 +2126,15 @@ gst_adaptive_demux2_stream_start (GstAdaptiveDemux2Stream * stream) void gst_adaptive_demux2_stream_stop (GstAdaptiveDemux2Stream * stream) +{ + GstAdaptiveDemux2StreamClass *klass = + GST_ADAPTIVE_DEMUX2_STREAM_GET_CLASS (stream); + + klass->stop (stream); +} + +static void +gst_adaptive_demux2_stream_stop_default (GstAdaptiveDemux2Stream * stream) { GstAdaptiveDemux *demux = stream->demux; diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.h index 12440c8be2..3463bf922c 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux-stream.h @@ -154,14 +154,26 @@ struct _GstAdaptiveDemux2StreamClass GstClockTimeDiff * final_ts); /** - * can_start: + * start: * @stream: a #GstAdaptiveDemux2Stream * - * Called before starting a @stream. sub-classes can return %FALSE if more - * information is required before it can be started. Sub-classes will have to - * call gst_adaptive_demux2_stream_start() when the stream should be started. + * Called to start downloading a @stream, sub-classes should chain up to the default + * implementation. Sub-classes can return %FALSE if more + * information is required before the stream can be started. In that case, sub-classes + * will have to call gst_adaptive_demux2_stream_start() again when the stream should + * be started. */ - gboolean (*can_start) (GstAdaptiveDemux2Stream *stream); + void (*start) (GstAdaptiveDemux2Stream *stream); + + /** + * stop: + * @stream: a #GstAdaptiveDemux2Stream + * + * Called to stop downloading a @stream, sub-classes should chain up to the default + * implementation. + */ + void (*stop) (GstAdaptiveDemux2Stream *stream); + /** * create_tracks: diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c index c4b7522dd1..11b512bca9 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux-stream.c @@ -72,8 +72,8 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream); static GstFlowReturn gst_hls_demux_stream_submit_request (GstAdaptiveDemux2Stream * stream, DownloadRequest * download_req); -static gboolean gst_hls_demux_stream_can_start (GstAdaptiveDemux2Stream * - stream); +static void gst_hls_demux_stream_start (GstAdaptiveDemux2Stream * stream); +static void gst_hls_demux_stream_stop (GstAdaptiveDemux2Stream * stream); static void gst_hls_demux_stream_create_tracks (GstAdaptiveDemux2Stream * stream); static gboolean gst_hls_demux_stream_select_bitrate (GstAdaptiveDemux2Stream * @@ -107,7 +107,8 @@ gst_hls_demux_stream_class_init (GstHLSDemuxStreamClass * klass) gst_hls_demux_stream_advance_fragment; adaptivedemux2stream_class->select_bitrate = gst_hls_demux_stream_select_bitrate; - adaptivedemux2stream_class->can_start = gst_hls_demux_stream_can_start; + adaptivedemux2stream_class->start = gst_hls_demux_stream_start; + adaptivedemux2stream_class->stop = gst_hls_demux_stream_stop; adaptivedemux2stream_class->create_tracks = gst_hls_demux_stream_create_tracks; @@ -2007,6 +2008,23 @@ gst_hls_demux_stream_can_start (GstAdaptiveDemux2Stream * stream) return FALSE; } +static void +gst_hls_demux_stream_start (GstAdaptiveDemux2Stream * stream) +{ + if (!gst_hls_demux_stream_can_start (stream)) + return; + + /* Chain up, to start the downloading */ + GST_ADAPTIVE_DEMUX2_STREAM_CLASS (stream_parent_class)->start (stream); +} + +static void +gst_hls_demux_stream_stop (GstAdaptiveDemux2Stream * stream) +{ + /* Chain up, to stop the downloading */ + GST_ADAPTIVE_DEMUX2_STREAM_CLASS (stream_parent_class)->stop (stream); +} + /* Returns TRUE if the rendition stream switched group-id */ static gboolean gst_hls_demux_update_rendition_stream (GstHLSDemux * hlsdemux,