diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index 2b4f48c487..cba70b3979 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -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; } diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index dd83165917..7166ecbf4a 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -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; +} diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h index 1b303aaabd..bc3f1ef2ff 100644 --- a/ext/dash/gstmpdparser.h +++ b/ext/dash/gstmpdparser.h @@ -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);