summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.com>2013-07-01 13:19:15 -0300
committerThiago Santos <thiago.sousa.santos@collabora.com>2013-07-01 18:52:08 -0300
commitd68fffc21758399c401593f1bd5915cbcf74e131 (patch)
tree30b3d1f1860772848b8d21acf680e3f25e9b13e4 /ext
parent54d87f071c152e05de210047180c3147c88f0634 (diff)
dashdemux: handle top-level index urls
Parse and provide access to top-level index segments if available. dashdemux should push those whenever a header is pushed. Fixes #700489
Diffstat (limited to 'ext')
-rw-r--r--ext/dash/gstdashdemux.c70
-rw-r--r--ext/dash/gstmpdparser.c52
-rw-r--r--ext/dash/gstmpdparser.h3
3 files changed, 99 insertions, 26 deletions
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 70f7aadac..a56896e36 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -1686,35 +1686,63 @@ gst_dash_demux_select_representations (GstDashDemux * demux)
return ret;
}
-static GstFragment *
-gst_dash_demux_get_next_header (GstDashDemux * demux, guint stream_idx)
+static GstBuffer *
+gst_dash_demux_download_header_fragment (GstDashDemux * demux, guint stream_idx,
+ gchar * path, gint64 range_start, gint64 range_end)
{
- gchar *initializationURL;
+ GstBuffer *buffer;
gchar *next_header_uri;
GstFragment *fragment;
- gint64 range_start, range_end;
-
- if (!gst_mpd_client_get_next_header (demux->client, &initializationURL,
- stream_idx, &range_start, &range_end))
- return NULL;
- if (strncmp (initializationURL, "http://", 7) != 0) {
+ if (strncmp (path, "http://", 7) != 0) {
next_header_uri =
g_strconcat (gst_mpdparser_get_baseURL (demux->client, stream_idx),
- initializationURL, NULL);
- g_free (initializationURL);
+ path, NULL);
+ g_free (path);
} else {
- next_header_uri = initializationURL;
+ next_header_uri = path;
}
- GST_INFO_OBJECT (demux, "Fetching header %s %" G_GINT64_FORMAT "-%"
- G_GINT64_FORMAT, next_header_uri, range_start, range_end);
-
fragment = gst_uri_downloader_fetch_uri_with_range (demux->downloader,
next_header_uri, range_start, range_end);
g_free (next_header_uri);
+ buffer = gst_fragment_get_buffer (fragment);
+ g_object_unref (fragment);
+ return buffer;
+}
- return fragment;
+static GstBuffer *
+gst_dash_demux_get_next_header (GstDashDemux * demux, guint stream_idx)
+{
+ gchar *initializationURL;
+ GstBuffer *header_buffer, *index_buffer = NULL;
+ gint64 range_start, range_end;
+
+ if (!gst_mpd_client_get_next_header (demux->client, &initializationURL,
+ stream_idx, &range_start, &range_end))
+ return NULL;
+
+ GST_INFO_OBJECT (demux, "Fetching header %s %" G_GINT64_FORMAT "-%"
+ G_GINT64_FORMAT, initializationURL, range_start, range_end);
+ header_buffer = gst_dash_demux_download_header_fragment (demux, stream_idx,
+ initializationURL, range_start, range_end);
+
+ /* check if we have an index */
+ if (gst_mpd_client_get_next_header_index (demux->client, &initializationURL,
+ stream_idx, &range_start, &range_end)) {
+ GST_INFO_OBJECT (demux, "Fetching index %s %" G_GINT64_FORMAT "-%"
+ G_GINT64_FORMAT, initializationURL, range_start, range_end);
+ index_buffer = gst_dash_demux_download_header_fragment (demux, stream_idx,
+ initializationURL, range_start, range_end);
+ }
+
+ if (index_buffer && header_buffer) {
+ header_buffer = gst_buffer_append (header_buffer, index_buffer);
+ } else if (index_buffer) {
+ gst_buffer_unref (index_buffer);
+ }
+
+ return header_buffer;
}
static GstCaps *
@@ -1824,7 +1852,8 @@ static gboolean
gst_dash_demux_get_next_fragment (GstDashDemux * demux)
{
GstActiveStream *active_stream;
- GstFragment *download, *header;
+ GstFragment *download;
+ GstBuffer *header_buffer;
gchar *next_fragment_uri;
GstClockTime duration;
GstClockTime timestamp;
@@ -1923,16 +1952,11 @@ gst_dash_demux_get_next_fragment (GstDashDemux * demux)
if (selected_stream->need_header) {
/* We need to fetch a new header */
- if ((header =
+ if ((header_buffer =
gst_dash_demux_get_next_header (demux, stream_idx)) == NULL) {
GST_WARNING_OBJECT (demux, "Unable to fetch header");
} else {
- GstBuffer *header_buffer;
- /* Replace fragment with a new one including the header */
-
- header_buffer = gst_fragment_get_buffer (header);
buffer = gst_buffer_append (header_buffer, buffer);
- g_object_unref (header);
}
selected_stream->need_header = FALSE;
}
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index c1a03b929..92eaa1159 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -1098,7 +1098,7 @@ gst_mpdparser_parse_seg_base_type_ext (GstSegmentBaseType ** pointer,
gst_mpdparser_get_xml_prop_unsigned_integer (a_node,
"presentationTimeOffset", 0);
seg_base_type->indexRange =
- gst_mpdparser_get_xml_prop_string (a_node, "indexRange");
+ gst_mpdparser_get_xml_prop_range (a_node, "indexRange");
seg_base_type->indexRangeExact =
gst_mpdparser_get_xml_prop_boolean (a_node, "indexRangeExact");
@@ -2227,7 +2227,7 @@ gst_mpdparser_free_seg_base_type_ext (GstSegmentBaseType * seg_base_type)
{
if (seg_base_type) {
if (seg_base_type->indexRange)
- xmlFree (seg_base_type->indexRange);
+ g_slice_free (GstRange, seg_base_type->indexRange);
gst_mpdparser_free_url_type_node (seg_base_type->Initialization);
gst_mpdparser_free_url_type_node (seg_base_type->RepresentationIndex);
g_slice_free (GstSegmentBaseType, seg_base_type);
@@ -3397,6 +3397,54 @@ gst_mpd_client_get_next_header (GstMpdClient * client, gchar ** uri,
return *uri == NULL ? FALSE : TRUE;
}
+gboolean
+gst_mpd_client_get_next_header_index (GstMpdClient * client, gchar ** uri,
+ guint stream_idx, gint64 * range_start, gint64 * range_end)
+{
+ GstActiveStream *stream;
+ GstStreamPeriod *stream_period;
+
+ stream = gst_mpdparser_get_active_stream_by_index (client, stream_idx);
+ g_return_val_if_fail (stream != NULL, FALSE);
+ g_return_val_if_fail (stream->cur_representation != NULL, FALSE);
+ stream_period = gst_mpdparser_get_stream_period (client);
+ g_return_val_if_fail (stream_period != NULL, FALSE);
+ g_return_val_if_fail (stream_period->period != NULL, FALSE);
+
+ *range_start = 0;
+ *range_end = -1;
+
+ GST_DEBUG ("Looking for current representation index");
+ GST_MPD_CLIENT_LOCK (client);
+ *uri = NULL;
+ if (stream->cur_segment_base && stream->cur_segment_base->indexRange) {
+ *uri =
+ g_strdup (gst_mpdparser_get_initializationURL (stream, stream->cur_segment_base->
+ Initialization));
+ *range_start =
+ stream->cur_segment_base->indexRange->first_byte_pos;
+ *range_end =
+ stream->cur_segment_base->indexRange->last_byte_pos;
+ } else if (stream->cur_seg_template) {
+ const gchar *initialization = NULL;
+ if (stream->cur_seg_template->index) {
+ initialization = stream->cur_seg_template->index;
+ } else if (stream->cur_adapt_set->SegmentTemplate
+ && stream->cur_adapt_set->SegmentTemplate->index) {
+ initialization = stream->cur_adapt_set->SegmentTemplate->index;
+ } else if (stream_period->period->SegmentTemplate
+ && stream_period->period->SegmentTemplate->index) {
+ initialization = stream_period->period->SegmentTemplate->index;
+ }
+ *uri = gst_mpdparser_build_URL_from_template (initialization,
+ stream->cur_representation->id, 0,
+ stream->cur_representation->bandwidth, 0);
+ }
+ GST_MPD_CLIENT_UNLOCK (client);
+
+ return *uri == NULL ? FALSE : TRUE;
+}
+
GstClockTime
gst_mpd_client_get_current_position (GstMpdClient * client)
{
diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h
index 9f005ba12..f7582f992 100644
--- a/ext/dash/gstmpdparser.h
+++ b/ext/dash/gstmpdparser.h
@@ -142,7 +142,7 @@ struct _GstSegmentBaseType
{
guint timescale;
guint presentationTimeOffset;
- gchar *indexRange;
+ GstRange *indexRange;
gboolean indexRangeExact;
/* Initialization node */
GstURLType *Initialization;
@@ -475,6 +475,7 @@ gboolean gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client, guin
gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, gboolean *discontinuity, gchar **uri, gint64 * range_start, gint64 * range_end, GstClockTime *duration, GstClockTime *timestamp);
gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
+gboolean gst_mpd_client_get_next_header_index (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
gboolean gst_mpd_client_is_live (GstMpdClient * client);
gboolean gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream, GstClockTime ts);