dashdemux: implement get_presentation_offset.

To account for presentationTimeOffset as per section 7.2.1 .

https://bugzilla.gnome.org/show_bug.cgi?id=745455
This commit is contained in:
Mathieu Duponchelle 2015-03-02 14:00:03 +01:00
parent b4d8c04f08
commit bd70c73a8a
3 changed files with 45 additions and 5 deletions

View file

@ -282,6 +282,17 @@ gst_dash_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
return TRUE; 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 static void
gst_dash_demux_class_init (GstDashDemuxClass * klass) 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->stream_free = gst_dash_demux_stream_free;
gstadaptivedemux_class->get_live_seek_range = gstadaptivedemux_class->get_live_seek_range =
gst_dash_demux_get_live_seek_range; gst_dash_demux_get_live_seek_range;
gstadaptivedemux_class->get_presentation_offset =
gst_dash_demux_get_presentation_offset;
} }
static void static void

View file

@ -3140,19 +3140,31 @@ gst_mpd_client_setup_representation (GstMpdClient * client,
return FALSE; return FALSE;
} }
} else { } else {
GstMultSegmentBaseType *mult_seg =
stream->cur_seg_template->MultSegBaseType;
/* build segment list */ /* build segment list */
i = stream->cur_seg_template->MultSegBaseType->startNumber; i = mult_seg->startNumber;
start = 0; start = 0;
start_time = PeriodStart; start_time = PeriodStart;
GST_LOG ("Building media segment list using this template: %s", GST_LOG ("Building media segment list using this template: %s",
stream->cur_seg_template->media); 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; GstSegmentTimelineNode *timeline;
GstSNode *S; GstSNode *S;
GList *list; GList *list;
timeline = stream->cur_seg_template->MultSegBaseType->SegmentTimeline; timeline = mult_seg->SegmentTimeline;
gst_mpdparser_init_active_stream_segments (stream); gst_mpdparser_init_active_stream_segments (stream);
for (list = g_queue_peek_head_link (&timeline->S); list; for (list = g_queue_peek_head_link (&timeline->S); list;
list = g_list_next (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=%" GST_LOG ("Processing S node: d=%" G_GUINT64_FORMAT " r=%u t=%"
G_GUINT64_FORMAT, S->d, S->r, S->t); G_GUINT64_FORMAT, S->d, S->r, S->t);
duration = S->d * GST_SECOND; duration = S->d * GST_SECOND;
timescale = timescale = mult_seg->SegBaseType->timescale;
stream->cur_seg_template->MultSegBaseType->SegBaseType->timescale;
if (timescale > 1) if (timescale > 1)
duration /= timescale; duration /= timescale;
if (S->t > 0) { if (S->t > 0) {
@ -3583,6 +3594,20 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client,
return TRUE; 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 gboolean
gst_mpd_client_get_next_fragment (GstMpdClient * client, gst_mpd_client_get_next_fragment (GstMpdClient * client,
guint indexStream, GstMediaFragmentInfo * fragment) guint indexStream, GstMediaFragmentInfo * fragment)

View file

@ -456,6 +456,7 @@ struct _GstActiveStream
GstSegmentTemplateNode *cur_seg_template; /* active segment template */ GstSegmentTemplateNode *cur_seg_template; /* active segment template */
guint segment_idx; /* index of next sequence chunk */ guint segment_idx; /* index of next sequence chunk */
GPtrArray *segments; /* array of GstMediaSegment */ GPtrArray *segments; /* array of GstMediaSegment */
GstClockTime presentationTimeOffset; /* presentation time offset of the current segment */
}; };
struct _GstMpdClient 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); 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_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); 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 */ /* Period selection */
guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time); guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time);