summaryrefslogtreecommitdiff
path: root/gst/isomp4/qtdemux.c
diff options
context:
space:
mode:
authorJulien Moutte <julien@fluendo.com>2013-01-10 18:34:09 +0100
committerJosep Torra <n770galaxy@gmail.com>2013-05-22 14:25:20 +0200
commit9e99e3c628cd4d5e14f4d997eb6ee0a6db7d3ee9 (patch)
tree103a40697e705dab5d3d52e502c7e2e9bbb668fe /gst/isomp4/qtdemux.c
parentf15e0fb60da4060b787cef4885b8b002973c22c0 (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.
Diffstat (limited to 'gst/isomp4/qtdemux.c')
-rw-r--r--gst/isomp4/qtdemux.c35
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]);