diff options
Diffstat (limited to 'gst/isomp4/qtdemux.c')
-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]); |