summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2015-09-21 21:05:03 +0200
committerSebastian Dröge <sebastian@centricular.com>2015-10-02 11:01:49 +0300
commit24ed035d0360188eccfbd59d5d5b385728652a77 (patch)
treec9f5636392482fa8b4c7e630b0b66cb4541af673
parent7116eab153eb1103eb1ffa6984a6897b4d6fccaa (diff)
downloadgstreamer-plugins-bad-24ed035d0360188eccfbd59d5d5b385728652a77.tar.gz
mpdparser: Load OnLoad external resources immediately instead of on demand
https://bugzilla.gnome.org/show_bug.cgi?id=752230
-rw-r--r--ext/dash/gstmpdparser.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index c30a9c6e0..3e6c0fef5 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -215,6 +215,12 @@ static void gst_mpdparser_free_active_stream (GstActiveStream * active_stream);
static GstUri *combine_urls (GstUri * base, GList * list, gchar ** query,
guint idx);
+static GList *gst_mpd_client_fetch_external_period (GstMpdClient * client,
+ GstPeriodNode * period_node, gboolean * error);
+static GList *gst_mpd_client_fetch_external_adaptation_set (GstMpdClient *
+ client, GstPeriodNode * period, GstAdaptationSetNode * adapt_set,
+ gboolean * error);
+
struct GstMpdParserUtcTimingMethod
{
const gchar *name;
@@ -3216,6 +3222,169 @@ gst_mpd_client_check_profiles (GstMpdClient * client)
}
}
+static gboolean
+gst_mpd_client_fetch_on_load_external_resources (GstMpdClient * client)
+{
+ GList *l;
+
+ for (l = client->mpd_node->Periods; l; /* explicitly advanced below */ ) {
+ GstPeriodNode *period = l->data;
+ GList *m;
+
+ if (period->xlink_href && period->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
+ GList *new_periods, *prev, *next;
+ gboolean error;
+
+ new_periods =
+ gst_mpd_client_fetch_external_period (client, period, &error);
+
+ if (!new_periods && error)
+ goto syntax_error;
+
+ prev = l->prev;
+ client->mpd_node->Periods =
+ g_list_delete_link (client->mpd_node->Periods, l);
+ gst_mpdparser_free_period_node (period);
+ period = NULL;
+
+ /* Get new next node, we will insert before this */
+ if (prev)
+ next = prev->next;
+ else
+ next = client->mpd_node->Periods;
+
+ while (new_periods) {
+ client->mpd_node->Periods =
+ g_list_insert_before (client->mpd_node->Periods, next,
+ new_periods->data);
+ new_periods = g_list_delete_link (new_periods, new_periods);
+ }
+ next = NULL;
+
+ /* Update our iterator to the first new period if any, or the next */
+ if (prev)
+ l = prev->next;
+ else
+ l = client->mpd_node->Periods;
+
+ continue;
+ }
+
+ if (period->SegmentList && period->SegmentList->xlink_href
+ && period->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
+ GstSegmentListNode *new_segment_list;
+ gboolean error;
+
+ new_segment_list =
+ gst_mpd_client_fetch_external_segment_list (client, period, NULL,
+ NULL, NULL, period->SegmentList, &error);
+
+ if (!new_segment_list && error)
+ goto syntax_error;
+
+ gst_mpdparser_free_segment_list_node (period->SegmentList);
+ period->SegmentList = new_segment_list;
+ }
+
+ for (m = period->AdaptationSets; m; /* explicitly advanced below */ ) {
+ GstAdaptationSetNode *adapt_set = m->data;
+ GList *n;
+
+ if (adapt_set->xlink_href
+ && adapt_set->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
+ GList *new_adapt_sets, *prev, *next;
+ gboolean error;
+
+ new_adapt_sets =
+ gst_mpd_client_fetch_external_adaptation_set (client, period,
+ adapt_set, &error);
+
+ if (!new_adapt_sets && error)
+ goto syntax_error;
+
+ prev = l->prev;
+ period->AdaptationSets = g_list_delete_link (period->AdaptationSets, l);
+ gst_mpdparser_free_adaptation_set_node (adapt_set);
+ adapt_set = NULL;
+
+ /* Get new next node, we will insert before this */
+ if (prev)
+ next = prev->next;
+ else
+ next = period->AdaptationSets;
+
+ while (new_adapt_sets) {
+ period->AdaptationSets =
+ g_list_insert_before (period->AdaptationSets, next,
+ new_adapt_sets->data);
+ new_adapt_sets = g_list_delete_link (new_adapt_sets, new_adapt_sets);
+ }
+ next = NULL;
+
+ /* Update our iterator to the first new adapt_set if any, or the next */
+ if (prev)
+ l = prev->next;
+ else
+ l = period->AdaptationSets;
+
+ continue;
+ }
+
+ if (adapt_set->SegmentList && adapt_set->SegmentList->xlink_href
+ && adapt_set->SegmentList->actuate == GST_XLINK_ACTUATE_ON_LOAD) {
+ GstSegmentListNode *new_segment_list;
+ gboolean error;
+
+ new_segment_list =
+ gst_mpd_client_fetch_external_segment_list (client, period,
+ adapt_set, NULL, period->SegmentList, adapt_set->SegmentList,
+ &error);
+
+ if (!new_segment_list && error)
+ goto syntax_error;
+
+ gst_mpdparser_free_segment_list_node (adapt_set->SegmentList);
+ adapt_set->SegmentList = new_segment_list;
+ }
+
+ for (n = adapt_set->Representations; n; n = n->next) {
+ GstRepresentationNode *representation = n->data;
+
+ if (representation->SegmentList
+ && representation->SegmentList->xlink_href
+ && representation->SegmentList->actuate ==
+ GST_XLINK_ACTUATE_ON_LOAD) {
+
+ GstSegmentListNode *new_segment_list;
+ gboolean error;
+
+ new_segment_list =
+ gst_mpd_client_fetch_external_segment_list (client, period,
+ adapt_set, representation, adapt_set->SegmentList,
+ representation->SegmentList, &error);
+
+ if (!new_segment_list && error)
+ goto syntax_error;
+
+ gst_mpdparser_free_segment_list_node (representation->SegmentList);
+ representation->SegmentList = new_segment_list;
+
+ }
+ }
+
+ m = m->next;
+ }
+
+ l = l->next;
+ }
+
+ return TRUE;
+
+syntax_error:
+
+ return FALSE;
+}
+
gboolean
gst_mpd_parse (GstMpdClient * client, const gchar * data, gint size)
{
@@ -3256,6 +3425,9 @@ gst_mpd_parse (GstMpdClient * client, const gchar * data, gint size)
gst_mpd_client_check_profiles (client);
+ if (!gst_mpd_client_fetch_on_load_external_resources (client))
+ return FALSE;
+
return TRUE;
}