dashdemux: include segment duration when calculating seek range

The gst_dash_demux_get_live_seek_range () function returns a stop value
that is beyond the available range. The functions
gst_mpd_client_check_time_position() and
gst_mpd_client_get_next_segment_availability_end_time() in
gstmpdparser.c include the segment duration when checking if a segment
is available. The gst_dash_demux_get_live_seek_range() function
in gstdashdemux.c ignores the segment duration.

According to the DASH specification, if maxSegmentDuration is not present,
then the maximum Segment duration is the maximum duration of any Segment
documented in the MPD.

https://bugzilla.gnome.org/show_bug.cgi?id=753751
This commit is contained in:
Alex Ashley 2016-02-24 15:54:54 +00:00 committed by Vincent Penquerc'h
parent 535f10b61d
commit d9bcf4dbd9
3 changed files with 40 additions and 0 deletions

View file

@ -317,10 +317,12 @@ gst_dash_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
GDateTime *now;
GDateTime *mstart;
GTimeSpan stream_now;
GstClockTime seg_duration;
if (self->client->mpd_node->availabilityStartTime == NULL)
return FALSE;
seg_duration = gst_mpd_client_get_maximum_segment_duration (self->client);
now = gst_dash_demux_get_server_now_utc (self);
mstart =
gst_date_time_to_g_date_time (self->client->
@ -341,6 +343,17 @@ gst_dash_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
if (*start < 0)
*start = 0;
}
/* As defined in 5.3.9.5.3 of the DASH specification, a segment does
not become available until the sum of:
* the value of the MPD@availabilityStartTime,
* the PeriodStart time of the containing Period
* the MPD start time of the Media Segment, and
* the MPD duration of the Media Segment.
Therefore we need to subtract the media segment duration from the stop
time.
*/
*stop -= seg_duration;
return TRUE;
}

View file

@ -5989,3 +5989,29 @@ gst_mpd_client_parse_default_presentation_delay (GstMpdClient * client,
}
return value;
}
GstClockTime
gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client)
{
GstClockTime ret = GST_CLOCK_TIME_NONE, dur;
GList *stream;
g_return_val_if_fail (client != NULL, GST_CLOCK_TIME_NONE);
g_return_val_if_fail (client->mpd_node != NULL, GST_CLOCK_TIME_NONE);
if (client->mpd_node->maxSegmentDuration != GST_MPD_DURATION_NONE) {
return client->mpd_node->maxSegmentDuration * GST_MSECOND;
}
/* According to the DASH specification, if maxSegmentDuration is not present:
"If not present, then the maximum Segment duration shall be the maximum
duration of any Segment documented in this MPD"
*/
for (stream = client->active_streams; stream; stream = g_list_next (stream)) {
dur = gst_mpd_client_get_segment_duration (client, stream->data, NULL);
if (dur != GST_CLOCK_TIME_NONE && (dur > ret || ret == GST_CLOCK_TIME_NONE)) {
ret = dur;
}
}
return ret;
}

View file

@ -538,6 +538,7 @@ gboolean gst_mpd_client_setup_streaming (GstMpdClient * client, GstAdaptationSet
gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation);
GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstActiveStream * stream);
GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client);
GstClockTime gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client);
gboolean gst_mpd_client_get_last_fragment_timestamp_end (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, GstMediaFragmentInfo * fragment);