diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index d4692acf12..16c548854f 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -282,6 +282,17 @@ gst_dash_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start, return TRUE; } +static GstClockTime +gst_dash_demux_get_presentation_offset (GstAdaptiveDemux * demux, + GstAdaptiveDemuxStream * stream) +{ + GstDashDemuxStream *dashstream = (GstDashDemuxStream *) stream; + GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux); + + return gst_mpd_parser_get_stream_presentation_offset (dashdemux->client, + dashstream->index); +} + static void gst_dash_demux_class_init (GstDashDemuxClass * klass) { @@ -361,6 +372,8 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass) gstadaptivedemux_class->stream_free = gst_dash_demux_stream_free; gstadaptivedemux_class->get_live_seek_range = gst_dash_demux_get_live_seek_range; + gstadaptivedemux_class->get_presentation_offset = + gst_dash_demux_get_presentation_offset; } static void diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index 7d2e29560b..d5e9d75c8b 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -3140,19 +3140,31 @@ gst_mpd_client_setup_representation (GstMpdClient * client, return FALSE; } } else { + GstMultSegmentBaseType *mult_seg = + stream->cur_seg_template->MultSegBaseType; /* build segment list */ - i = stream->cur_seg_template->MultSegBaseType->startNumber; + i = mult_seg->startNumber; start = 0; start_time = PeriodStart; GST_LOG ("Building media segment list using this template: %s", stream->cur_seg_template->media); - if (stream->cur_seg_template->MultSegBaseType->SegmentTimeline) { + stream->presentationTimeOffset = + mult_seg->SegBaseType->presentationTimeOffset * GST_SECOND; + + /* Avoid dividing by zero */ + if (mult_seg->SegBaseType->timescale) + stream->presentationTimeOffset /= mult_seg->SegBaseType->timescale; + + GST_LOG ("Setting stream's presentation time offset to %" GST_TIME_FORMAT, + GST_TIME_ARGS (stream->presentationTimeOffset)); + + if (mult_seg->SegmentTimeline) { GstSegmentTimelineNode *timeline; GstSNode *S; GList *list; - timeline = stream->cur_seg_template->MultSegBaseType->SegmentTimeline; + timeline = mult_seg->SegmentTimeline; gst_mpdparser_init_active_stream_segments (stream); for (list = g_queue_peek_head_link (&timeline->S); list; list = g_list_next (list)) { @@ -3162,8 +3174,7 @@ gst_mpd_client_setup_representation (GstMpdClient * client, GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%u t=%" G_GUINT64_FORMAT, S->d, S->r, S->t); duration = S->d * GST_SECOND; - timescale = - stream->cur_seg_template->MultSegBaseType->SegBaseType->timescale; + timescale = mult_seg->SegBaseType->timescale; if (timescale > 1) duration /= timescale; if (S->t > 0) { @@ -3583,6 +3594,20 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, return TRUE; } +GstClockTime +gst_mpd_parser_get_stream_presentation_offset (GstMpdClient * client, + guint stream_idx) +{ + GstActiveStream *stream = NULL; + + g_return_val_if_fail (client != NULL, FALSE); + g_return_val_if_fail (client->active_streams != NULL, FALSE); + stream = g_list_nth_data (client->active_streams, stream_idx); + g_return_val_if_fail (stream != NULL, FALSE); + + return stream->presentationTimeOffset; +} + gboolean gst_mpd_client_get_next_fragment (GstMpdClient * client, guint indexStream, GstMediaFragmentInfo * fragment) diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h index 60433571b2..7a098c3bc8 100644 --- a/ext/dash/gstmpdparser.h +++ b/ext/dash/gstmpdparser.h @@ -456,6 +456,7 @@ struct _GstActiveStream GstSegmentTemplateNode *cur_seg_template; /* active segment template */ guint segment_idx; /* index of next sequence chunk */ GPtrArray *segments; /* array of GstMediaSegment */ + GstClockTime presentationTimeOffset; /* presentation time offset of the current segment */ }; struct _GstMpdClient @@ -503,6 +504,7 @@ gboolean gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time); GstDateTime *gst_mpd_client_add_time_difference (GstDateTime * t1, gint64 usecs); gint gst_mpd_client_get_segment_index_at_time (GstMpdClient *client, GstActiveStream * stream, const GstDateTime *time); gint gst_mpd_client_check_time_position (GstMpdClient * client, GstActiveStream * stream, GstClockTime ts, gint64 * diff); +GstClockTime gst_mpd_parser_get_stream_presentation_offset (GstMpdClient *client, guint stream_idx); /* Period selection */ guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time);