mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
dashdemux: add support for range based segments
Use the mediaRange information and pass it to the uridownloader to correctly download only the segment ranges indicated in the MPD https://bugzilla.gnome.org/show_bug.cgi?id=702206
This commit is contained in:
parent
e76f3e95fd
commit
4f17112392
3 changed files with 43 additions and 43 deletions
|
@ -1691,9 +1691,10 @@ gst_dash_demux_get_next_header (GstDashDemux * demux, guint stream_idx)
|
|||
gchar *initializationURL;
|
||||
gchar *next_header_uri;
|
||||
GstFragment *fragment;
|
||||
gint64 range_start, range_end;
|
||||
|
||||
if (!gst_mpd_client_get_next_header (demux->client, &initializationURL,
|
||||
stream_idx))
|
||||
stream_idx, &range_start, &range_end))
|
||||
return NULL;
|
||||
|
||||
if (strncmp (initializationURL, "http://", 7) != 0) {
|
||||
|
@ -1705,9 +1706,11 @@ gst_dash_demux_get_next_header (GstDashDemux * demux, guint stream_idx)
|
|||
next_header_uri = initializationURL;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (demux, "Fetching header %s", next_header_uri);
|
||||
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 (demux->downloader, next_header_uri);
|
||||
fragment = gst_uri_downloader_fetch_uri_with_range (demux->downloader,
|
||||
next_header_uri, range_start, range_end);
|
||||
g_free (next_header_uri);
|
||||
|
||||
return fragment;
|
||||
|
@ -1883,22 +1886,25 @@ gst_dash_demux_get_next_fragment (GstDashDemux * demux)
|
|||
if (selected_stream) {
|
||||
guint stream_idx = selected_stream->index;
|
||||
GstBuffer *buffer;
|
||||
gint64 range_start, range_end;
|
||||
|
||||
if (gst_mpd_client_get_next_fragment (demux->client,
|
||||
stream_idx, &discont, &next_fragment_uri, &duration, ×tamp)) {
|
||||
stream_idx, &discont, &next_fragment_uri, &range_start, &range_end,
|
||||
&duration, ×tamp)) {
|
||||
|
||||
g_get_current_time (&start);
|
||||
GST_INFO_OBJECT (demux, "Next fragment for stream #%i", stream_idx);
|
||||
GST_INFO_OBJECT (demux,
|
||||
"Fetching next fragment %s ts:%" GST_TIME_FORMAT " dur:%"
|
||||
GST_TIME_FORMAT, next_fragment_uri, GST_TIME_ARGS (timestamp),
|
||||
GST_TIME_ARGS (duration));
|
||||
GST_TIME_FORMAT " Range:%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT,
|
||||
next_fragment_uri, GST_TIME_ARGS (timestamp),
|
||||
GST_TIME_ARGS (duration), range_start, range_end);
|
||||
|
||||
/* got a fragment to fetch, no end of period */
|
||||
end_of_period = FALSE;
|
||||
|
||||
download = gst_uri_downloader_fetch_uri (demux->downloader,
|
||||
next_fragment_uri);
|
||||
download = gst_uri_downloader_fetch_uri_with_range (demux->downloader,
|
||||
next_fragment_uri, range_start, range_end);
|
||||
g_free (next_fragment_uri);
|
||||
|
||||
if (download == NULL)
|
||||
|
|
|
@ -111,8 +111,6 @@ static int strncmp_ext (const char *s1, const char *s2);
|
|||
static GstStreamPeriod *gst_mpdparser_get_stream_period (GstMpdClient * client);
|
||||
static gchar *gst_mpdparser_parse_baseURL (GstMpdClient * client,
|
||||
GstActiveStream * stream, gchar ** query);
|
||||
static gchar *gst_mpdparser_get_segmentURL_for_range (gchar * url,
|
||||
GstRange * range);
|
||||
static gchar *gst_mpdparser_get_mediaURL (GstActiveStream * stream,
|
||||
GstSegmentURLNode * segmentURL);
|
||||
static gchar *gst_mpdparser_get_initializationURL (GstURLType *
|
||||
|
@ -1878,14 +1876,14 @@ gst_mpdparser_get_segment_base (GstPeriodNode * Period,
|
|||
if (Representation && Representation->SegmentList
|
||||
&& Representation->SegmentList->MultSegBaseType
|
||||
&& Representation->SegmentList->MultSegBaseType->SegBaseType
|
||||
&& Representation->SegmentList->MultSegBaseType->
|
||||
SegBaseType->Initialization) {
|
||||
&& Representation->SegmentList->MultSegBaseType->SegBaseType->
|
||||
Initialization) {
|
||||
SegmentBase = Representation->SegmentList->MultSegBaseType->SegBaseType;
|
||||
} else if (AdaptationSet && AdaptationSet->SegmentList
|
||||
&& AdaptationSet->SegmentList->MultSegBaseType
|
||||
&& AdaptationSet->SegmentList->MultSegBaseType->SegBaseType
|
||||
&& AdaptationSet->SegmentList->MultSegBaseType->
|
||||
SegBaseType->Initialization) {
|
||||
&& AdaptationSet->SegmentList->MultSegBaseType->SegBaseType->
|
||||
Initialization) {
|
||||
SegmentBase = AdaptationSet->SegmentList->MultSegBaseType->SegBaseType;
|
||||
} else if (Period && Period->SegmentList
|
||||
&& Period->SegmentList->MultSegBaseType
|
||||
|
@ -2352,25 +2350,6 @@ gst_mpdparser_free_active_stream (GstActiveStream * active_stream)
|
|||
}
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gst_mpdparser_get_segmentURL_for_range (gchar * url, GstRange * range)
|
||||
{
|
||||
gchar *segmentURL;
|
||||
|
||||
if (range) {
|
||||
gchar *range_suffix;
|
||||
range_suffix =
|
||||
g_strdup_printf ("?range=%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT,
|
||||
range->first_byte_pos, range->last_byte_pos);
|
||||
segmentURL = g_strconcat (url, range_suffix, NULL);
|
||||
g_free (range_suffix);
|
||||
} else {
|
||||
segmentURL = g_strdup (url);
|
||||
}
|
||||
|
||||
return segmentURL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
gst_mpdparser_get_mediaURL (GstActiveStream * stream,
|
||||
GstSegmentURLNode * segmentURL)
|
||||
|
@ -2383,8 +2362,7 @@ gst_mpdparser_get_mediaURL (GstActiveStream * stream,
|
|||
url_prefix = segmentURL->media ? segmentURL->media : stream->baseURL;
|
||||
g_return_val_if_fail (url_prefix != NULL, NULL);
|
||||
|
||||
return gst_mpdparser_get_segmentURL_for_range (segmentURL->media,
|
||||
segmentURL->mediaRange);
|
||||
return segmentURL->media;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -2393,8 +2371,7 @@ gst_mpdparser_get_initializationURL (GstURLType * InitializationURL)
|
|||
g_return_val_if_fail (InitializationURL != NULL, NULL);
|
||||
g_return_val_if_fail (InitializationURL->sourceURL != NULL, NULL);
|
||||
|
||||
return gst_mpdparser_get_segmentURL_for_range (InitializationURL->sourceURL,
|
||||
InitializationURL->range);
|
||||
return InitializationURL->sourceURL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -3296,6 +3273,7 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client,
|
|||
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)
|
||||
{
|
||||
GstActiveStream *stream = NULL;
|
||||
|
@ -3324,7 +3302,7 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
|
|||
|
||||
GST_DEBUG ("currentChunk->SegmentURL = %p", currentChunk->SegmentURL);
|
||||
if (currentChunk->SegmentURL != NULL) {
|
||||
mediaURL = gst_mpdparser_get_mediaURL (stream, currentChunk->SegmentURL);
|
||||
mediaURL = g_strdup (gst_mpdparser_get_mediaURL (stream, currentChunk->SegmentURL));
|
||||
} else if (stream->cur_seg_template != NULL) {
|
||||
mediaURL =
|
||||
gst_mpdparser_build_URL_from_template (stream->cur_seg_template->media,
|
||||
|
@ -3336,6 +3314,13 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
|
|||
*timestamp = currentChunk->start_time;
|
||||
*duration = currentChunk->duration;
|
||||
*discontinuity = segment_idx != currentChunk->number;
|
||||
*range_start = 0;
|
||||
*range_end = -1;
|
||||
if (currentChunk->SegmentURL->mediaRange) {
|
||||
*range_start = currentChunk->SegmentURL->mediaRange->first_byte_pos;
|
||||
*range_end = currentChunk->SegmentURL->mediaRange->last_byte_pos;
|
||||
}
|
||||
|
||||
if (mediaURL == NULL) {
|
||||
/* single segment with URL encoded in the baseURL syntax element */
|
||||
*uri = g_strdup (stream->baseURL);
|
||||
|
@ -3355,7 +3340,7 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
|
|||
|
||||
gboolean
|
||||
gst_mpd_client_get_next_header (GstMpdClient * client, gchar ** uri,
|
||||
guint stream_idx)
|
||||
guint stream_idx, gint64 * range_start, gint64 * range_end)
|
||||
{
|
||||
GstActiveStream *stream;
|
||||
GstStreamPeriod *stream_period;
|
||||
|
@ -3367,13 +3352,22 @@ gst_mpd_client_get_next_header (GstMpdClient * client, gchar ** uri,
|
|||
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 header");
|
||||
GST_MPD_CLIENT_LOCK (client);
|
||||
*uri = NULL;
|
||||
if (stream->cur_segment_base && stream->cur_segment_base->Initialization) {
|
||||
*uri =
|
||||
gst_mpdparser_get_initializationURL (stream->
|
||||
cur_segment_base->Initialization);
|
||||
g_strdup (gst_mpdparser_get_initializationURL (stream->cur_segment_base->
|
||||
Initialization));
|
||||
if (stream->cur_segment_base->Initialization->range) {
|
||||
*range_start =
|
||||
stream->cur_segment_base->Initialization->range->first_byte_pos;
|
||||
*range_end =
|
||||
stream->cur_segment_base->Initialization->range->last_byte_pos;
|
||||
}
|
||||
} else if (stream->cur_seg_template) {
|
||||
const gchar *initialization = NULL;
|
||||
if (stream->cur_seg_template->initialization) {
|
||||
|
|
|
@ -473,8 +473,8 @@ GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client);
|
|||
GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client);
|
||||
gboolean gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
|
||||
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, GstClockTime *duration, GstClockTime *timestamp);
|
||||
gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx);
|
||||
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_is_live (GstMpdClient * client);
|
||||
gboolean gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream, GstClockTime ts);
|
||||
|
||||
|
|
Loading…
Reference in a new issue