diff options
author | Julien Moutte <julien@fluendo.com> | 2013-01-10 18:34:09 +0100 |
---|---|---|
committer | Josep Torra <n770galaxy@gmail.com> | 2013-05-22 14:25:20 +0200 |
commit | 9e99e3c628cd4d5e14f4d997eb6ee0a6db7d3ee9 (patch) | |
tree | 103a40697e705dab5d3d52e502c7e2e9bbb668fe | |
parent | f15e0fb60da4060b787cef4885b8b002973c22c0 (diff) |
qtdemux: Impact new segment and pts with tfdt.
Use the TFDT information to introduce an offset in the streams PTS and
related NEWSEGMENT events. Indeed with DASH, each segment should be
continuous with the previous one in terms of PTS and as Audio/Video
segments can be of different durations we can not use the TFDT as a
time position information for the NEWSEGMENT as this would lead to A/V
sync issues.
-rw-r--r-- | gst/isomp4/qtdemux.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index f769f2c97..0336732c2 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -974,6 +974,7 @@ static void gst_qtdemux_push_pending_newsegment (GstQTDemux * qtdemux) { if (qtdemux->pending_newsegment) { + GST_DEBUG_OBJECT (qtdemux, "pushing pending newsegment"); gst_qtdemux_push_event (qtdemux, qtdemux->pending_newsegment); qtdemux->pending_newsegment = NULL; } @@ -2254,7 +2255,7 @@ static gboolean qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun, QtDemuxStream * stream, guint32 d_sample_duration, guint32 d_sample_size, guint32 d_sample_flags, gint64 moof_offset, gint64 moof_length, - gint64 * base_offset, gint64 * running_offset) + gint64 * base_offset, gint64 * running_offset, gint64 base_decode_time) { guint64 timestamp; gint32 data_offset = 0; @@ -2376,7 +2377,7 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun, if (G_UNLIKELY (stream->n_samples == 0)) { /* the timestamp of the first sample is also provided by the tfra entry * but we shouldn't rely on it as it is at the end of files */ - timestamp = 0; + timestamp = base_decode_time; } else { /* subsequent fragments extend stream */ timestamp = @@ -2551,7 +2552,7 @@ qtdemux_parse_tfdt (GstQTDemux * qtdemux, GstByteReader * br, guint32 version = 0; if (!gst_byte_reader_get_uint32_be (br, &version)) - return FALSE; + goto failed; version >>= 24; if (version == 1) { @@ -2584,6 +2585,7 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length, GstByteReader trun_data, tfhd_data, tfdt_data; guint32 ds_size = 0, ds_duration = 0, ds_flags = 0; gint64 base_offset, running_offset; + guint64 decode_time = 0; /* NOTE @stream ignored */ @@ -2608,15 +2610,25 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length, qtdemux_tree_get_child_by_type_full (traf_node, FOURCC_tfdt, &tfdt_data); if (tfdt_node) { - guint64 decode_time = 0; qtdemux_parse_tfdt (qtdemux, &tfdt_data, &decode_time); - /* If there is a new segment pending, update the time/position */ + /* If there is a new segment pending, update the start */ if (qtdemux->pending_newsegment) { + GstFormat format; + gboolean update; + gdouble rate; + gint64 start, stop, time, start_offset; + + gst_event_parse_new_segment (qtdemux->pending_newsegment, &update, + &rate, &format, &start, &stop, &time); + + start_offset = + gst_util_uint64_scale (decode_time, GST_SECOND, stream->timescale); + + GST_DEBUG_OBJECT (qtdemux, "updating newsegment start with %" + GST_TIME_FORMAT " (tfdt)", GST_TIME_ARGS (start + start_offset)); gst_event_replace (&qtdemux->pending_newsegment, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, - 0, GST_CLOCK_TIME_NONE, - gst_util_uint64_scale (decode_time, - GST_SECOND, stream->timescale))); + gst_event_new_new_segment (update, rate, format, + start + start_offset, stop, time)); /* ref added when replaced, release the original _new one */ gst_event_unref (qtdemux->pending_newsegment); } @@ -2655,7 +2667,7 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length, while (trun_node) { qtdemux_parse_trun (qtdemux, &trun_data, stream, ds_duration, ds_size, ds_flags, moof_offset, length, &base_offset, - &running_offset); + &running_offset, decode_time); /* iterate all siblings */ trun_node = qtdemux_tree_get_sibling_by_type_full (trun_node, FOURCC_trun, &trun_data); @@ -4569,8 +4581,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf) /* initial newsegment sent here after having added pads, * possible others in sink_event */ if (G_UNLIKELY (demux->pending_newsegment)) { - gst_qtdemux_push_event (demux, demux->pending_newsegment); - demux->pending_newsegment = NULL; + gst_qtdemux_push_pending_newsegment (demux); /* clear to send tags on all streams */ for (i = 0; i < demux->n_streams; i++) { gst_qtdemux_push_tags (demux, demux->streams[i]); |