summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2015-09-22 16:17:38 +0200
committerSebastian Dröge <sebastian@centricular.com>2015-10-02 11:01:56 +0300
commit84e45d96b9f426268c2431cead42929f99d780bf (patch)
tree294075d0fe3857b2e639ac4ef91f508c3938d001 /ext
parent24ed035d0360188eccfbd59d5d5b385728652a77 (diff)
downloadgstreamer-plugins-bad-84e45d96b9f426268c2431cead42929f99d780bf.tar.gz
dashdemux: Implement lazy-loading of external periods
https://bugzilla.gnome.org/show_bug.cgi?id=752230
Diffstat (limited to 'ext')
-rw-r--r--ext/dash/gstdashdemux.c10
-rw-r--r--ext/dash/gstmpdparser.c55
-rw-r--r--ext/dash/gstmpdparser.h2
3 files changed, 58 insertions, 9 deletions
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 5445ad4a4..20d676419 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -736,7 +736,8 @@ gst_dash_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
if (gst_buffer_map (buf, &mapinfo, GST_MAP_READ)) {
manifest = (gchar *) mapinfo.data;
if (gst_mpd_parse (dashdemux->client, manifest, mapinfo.size)) {
- if (gst_mpd_client_setup_media_presentation (dashdemux->client)) {
+ if (gst_mpd_client_setup_media_presentation (dashdemux->client, 0, 0,
+ NULL)) {
ret = TRUE;
} else {
GST_ELEMENT_ERROR (demux, STREAM, DECODE,
@@ -1208,6 +1209,10 @@ gst_dash_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
target_pos = (GstClockTime) demux->segment.stop;
/* select the requested Period in the Media Presentation */
+ if (!gst_mpd_client_setup_media_presentation (dashdemux->client, target_pos,
+ -1, NULL))
+ return FALSE;
+
current_period = 0;
for (list = g_list_first (dashdemux->client->periods); list;
list = g_list_next (list)) {
@@ -1295,7 +1300,8 @@ gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
period_idx = gst_mpd_client_get_period_index (dashdemux->client);
/* setup video, audio and subtitle streams, starting from current Period */
- if (!gst_mpd_client_setup_media_presentation (new_client)) {
+ if (!gst_mpd_client_setup_media_presentation (new_client, -1,
+ (period_id ? -1 : period_idx), period_id)) {
/* TODO */
}
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index 3e6c0fef5..bb9d7b057 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -2978,6 +2978,9 @@ gst_mpd_client_get_period_index_at_time (GstMpdClient * client,
if (time_offset < 0)
return 0;
+ if (!gst_mpd_client_setup_media_presentation (client, time_offset, -1, NULL))
+ return 0;
+
for (idx = 0, iter = client->periods; iter; idx++, iter = g_list_next (iter)) {
stream_period = iter->data;
if (stream_period->start <= time_offset
@@ -3893,12 +3896,9 @@ gst_mpd_client_fetch_external_period (GstMpdClient * client,
return new_periods;
}
-/* TODO: Implement xlink actuation onRequest properly. Currently we download
- * each external MPD immediately when iterating over the periods. We should
- * do this only when actually switching to this period.
- */
gboolean
-gst_mpd_client_setup_media_presentation (GstMpdClient * client)
+gst_mpd_client_setup_media_presentation (GstMpdClient * client,
+ GstClockTime time, gint period_idx, const gchar * period_id)
{
GstStreamPeriod *stream_period;
GstClockTime start, duration;
@@ -3909,8 +3909,30 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client)
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (client->mpd_node != NULL, FALSE);
+ /* Check if we set up the media presentation far enough already */
+ for (list = client->periods; list; list = list->next) {
+ GstStreamPeriod *stream_period = list->data;
+
+ if ((time != GST_CLOCK_TIME_NONE
+ && stream_period->duration != GST_CLOCK_TIME_NONE
+ && stream_period->start + stream_period->duration >= time)
+ || (time != GST_CLOCK_TIME_NONE && stream_period->start >= time))
+ return TRUE;
+
+ if (period_idx != -1 && stream_period->number >= period_idx)
+ return TRUE;
+
+ if (period_id != NULL && stream_period->period->id != NULL
+ && strcmp (stream_period->period->id, period_id) == 0)
+ return TRUE;
+
+ }
+
GST_DEBUG ("Building the list of Periods in the Media Presentation");
/* clean the old period list, if any */
+ /* TODO: In theory we could reuse the ones we have so far but that
+ * seems more complicated than the overhead caused here
+ */
if (client->periods) {
g_list_foreach (client->periods,
(GFunc) gst_mpdparser_free_stream_period, NULL);
@@ -4076,10 +4098,24 @@ gst_mpd_client_setup_media_presentation (GstMpdClient * client)
GST_LOG (" - added Period %d start=%" GST_TIME_FORMAT " duration=%"
GST_TIME_FORMAT, idx, GST_TIME_ARGS (start), GST_TIME_ARGS (duration));
+ if ((time != GST_CLOCK_TIME_NONE
+ && stream_period->duration != GST_CLOCK_TIME_NONE
+ && stream_period->start + stream_period->duration >= time)
+ || (time != GST_CLOCK_TIME_NONE && stream_period->start >= time))
+ break;
+
+ if (period_idx != -1 && stream_period->number >= period_idx)
+ break;
+
+ if (period_id != NULL && stream_period->period->id != NULL
+ && strcmp (stream_period->period->id, period_id) == 0)
+ break;
+
list = list->next;
}
- GST_DEBUG ("Found a total of %d valid Periods in the Media Presentation",
+ GST_DEBUG
+ ("Found a total of %d valid Periods in the Media Presentation up to this point",
idx);
return ret;
@@ -5052,6 +5088,10 @@ gst_mpd_client_set_period_id (GstMpdClient * client, const gchar * period_id)
g_return_val_if_fail (client->periods != NULL, FALSE);
g_return_val_if_fail (period_id != NULL, FALSE);
+ if (!gst_mpd_client_setup_media_presentation (client, GST_CLOCK_TIME_NONE, -1,
+ period_id))
+ return FALSE;
+
for (period_idx = 0, iter = client->periods; iter;
period_idx++, iter = g_list_next (iter)) {
next_stream_period = iter->data;
@@ -5076,6 +5116,9 @@ gst_mpd_client_set_period_index (GstMpdClient * client, guint period_idx)
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (client->periods != NULL, FALSE);
+ if (!gst_mpd_client_setup_media_presentation (client, -1, period_idx, NULL))
+ return FALSE;
+
next_stream_period = g_list_nth_data (client->periods, period_idx);
if (next_stream_period != NULL) {
client->period_idx = period_idx;
diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h
index 85ddc8476..36569b567 100644
--- a/ext/dash/gstmpdparser.h
+++ b/ext/dash/gstmpdparser.h
@@ -531,7 +531,7 @@ void gst_mpd_client_set_uri_downloader (GstMpdClient * client, GstUriDownloader
gboolean gst_mpd_parse (GstMpdClient *client, const gchar *data, gint size);
/* Streaming management */
-gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client);
+gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client, GstClockTime time, gint period_index, const gchar *period_id);
gboolean gst_mpd_client_setup_streaming (GstMpdClient * client, GstAdaptationSetNode * adapt_set);
gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation);
GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstActiveStream * stream);