From e1b68d9a65ba512a52c3a2b298fa830a445eb451 Mon Sep 17 00:00:00 2001 From: Alex Ashley Date: Fri, 5 Feb 2016 12:44:23 +0000 Subject: [PATCH] adaptivedemux: answer duration queries for live streams For duration queries on live streams, adaptivedemux ignores the query. The problem then is that the query is answered by the downstream qtdemux element, with the duration of the currently passing fragment. This commit changes the behaviour of adaptivedemux to answer the duration queries for live streams, returning GST_CLOCK_TIME_NONE. https://bugzilla.gnome.org/show_bug.cgi?id=753879 --- ext/dash/gstmpdparser.c | 14 ++++---------- ext/hls/m3u8.c | 6 +----- ext/smoothstreaming/gstmssmanifest.c | 2 +- gst-libs/gst/adaptivedemux/gstadaptivedemux.c | 12 ++++++------ gst-libs/gst/adaptivedemux/gstadaptivedemux.h | 12 ++++++++++++ tests/check/elements/hlsdemux_m3u8.c | 7 ------- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index baf5dbc831..25eaab7d54 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -5483,18 +5483,12 @@ gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient * client) { - GstClockTime duration; - g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE); - if (client->mpd_node->mediaPresentationDuration != -1) { - duration = client->mpd_node->mediaPresentationDuration * GST_MSECOND; - } else { - /* We can only get the duration for on-demand streams */ - duration = GST_CLOCK_TIME_NONE; - } - - return duration; + /* Note: adaptivedemux makes sure we only get duration queries for on-demand streams */ + g_return_val_if_fail (client->mpd_node->mediaPresentationDuration != -1, + GST_CLOCK_TIME_NONE); + return client->mpd_node->mediaPresentationDuration * GST_MSECOND; } gboolean diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c index 6cc7a715c2..3bac7bfaaf 100644 --- a/ext/hls/m3u8.c +++ b/ext/hls/m3u8.c @@ -1015,9 +1015,7 @@ gst_m3u8_get_duration (GstM3U8 * m3u8) GST_M3U8_LOCK (m3u8); - /* We can only get the duration for on-demand streams */ - if (!m3u8->endlist) - goto out; + /* Note: adaptivedemux makes sure we only get duration queries for on-demand streams */ if (!GST_CLOCK_TIME_IS_VALID (m3u8->duration) && m3u8->files != NULL) { GList *f; @@ -1028,8 +1026,6 @@ gst_m3u8_get_duration (GstM3U8 * m3u8) } duration = m3u8->duration; -out: - GST_M3U8_UNLOCK (m3u8); return duration; diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c index 7ef11140e8..111fb7840b 100644 --- a/ext/smoothstreaming/gstmssmanifest.c +++ b/ext/smoothstreaming/gstmssmanifest.c @@ -934,7 +934,7 @@ guint64 gst_mss_manifest_get_duration (GstMssManifest * manifest) { gchar *duration; - guint64 dur = -1; + guint64 dur = GST_CLOCK_TIME_NONE; /* try the property */ duration = diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c index e46dc3a4bc..0ffb5307b6 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c @@ -1748,12 +1748,12 @@ gst_adaptive_demux_src_query (GstPad * pad, GstObject * parent, GST_MANIFEST_LOCK (demux); if (fmt == GST_FORMAT_TIME && demux->priv->have_manifest) { - duration = demux_class->get_duration (demux); - - if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) { - gst_query_set_duration (query, GST_FORMAT_TIME, duration); - ret = TRUE; - } + if (gst_adaptive_demux_is_live (demux)) + duration = GST_CLOCK_TIME_NONE; + else + duration = demux_class->get_duration (demux); + gst_query_set_duration (query, GST_FORMAT_TIME, duration); + ret = TRUE; } GST_MANIFEST_UNLOCK (demux); diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h index 830171467f..d2d2f01ecf 100644 --- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h +++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h @@ -293,6 +293,18 @@ struct _GstAdaptiveDemuxClass GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf); gboolean (*is_live) (GstAdaptiveDemux * demux); + + /** + * get_duration: + * @demux: #GstAdaptiveDemux + * + * For non-live streams, this will be called to query the duration of the + * stream. + * + * Returns: The duration of the stream, or #GST_CLOCK_TIME_NONE if the + * duration is unknown + * Since: 1.6 + */ GstClockTime (*get_duration) (GstAdaptiveDemux * demux); /** diff --git a/tests/check/elements/hlsdemux_m3u8.c b/tests/check/elements/hlsdemux_m3u8.c index 74cd69bfa8..82d778f2dd 100644 --- a/tests/check/elements/hlsdemux_m3u8.c +++ b/tests/check/elements/hlsdemux_m3u8.c @@ -838,13 +838,6 @@ GST_START_TEST (test_get_duration) assert_equals_uint64 (gst_m3u8_get_duration (pl), 40 * GST_SECOND); gst_hls_master_playlist_unref (master); - - /* Test duration for live playlists */ - master = load_playlist (LIVE_PLAYLIST); - pl = master->default_variant->m3u8; - assert_equals_uint64 (gst_m3u8_get_duration (pl), GST_CLOCK_TIME_NONE); - - gst_hls_master_playlist_unref (master); } GST_END_TEST;