diff options
author | Thiago Santos <thiago.sousa.santos@collabora.com> | 2013-07-01 13:19:15 -0300 |
---|---|---|
committer | Thiago Santos <thiago.sousa.santos@collabora.com> | 2013-07-01 18:52:08 -0300 |
commit | d68fffc21758399c401593f1bd5915cbcf74e131 (patch) | |
tree | 30b3d1f1860772848b8d21acf680e3f25e9b13e4 /ext | |
parent | 54d87f071c152e05de210047180c3147c88f0634 (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.c | 70 | ||||
-rw-r--r-- | ext/dash/gstmpdparser.c | 52 | ||||
-rw-r--r-- | ext/dash/gstmpdparser.h | 3 |
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); |