diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 411911dbe9..8409123d14 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -2372,12 +2372,44 @@ unknown_stream: } } +static gboolean +qtdemux_parse_tfdt (GstQTDemux * qtdemux, GstByteReader * br, + guint64 * decode_time) +{ + guint32 version = 0; + + if (!gst_byte_reader_get_uint32_be (br, &version)) + return FALSE; + + version >>= 24; + if (version == 1) { + if (!gst_byte_reader_get_uint64_be (br, decode_time)) + goto failed; + } else { + guint32 dec_time = 0; + if (!gst_byte_reader_get_uint32_be (br, &dec_time)) + goto failed; + *decode_time = dec_time; + } + + GST_INFO_OBJECT (qtdemux, "Track fragment decode time: %" G_GUINT64_FORMAT, + *decode_time); + + return TRUE; + +failed: + { + GST_DEBUG_OBJECT (qtdemux, "parsing tfdt failed"); + return FALSE; + } +} + static gboolean qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length, guint64 moof_offset, QtDemuxStream * stream) { - GNode *moof_node, *traf_node, *tfhd_node, *trun_node; - GstByteReader trun_data, tfhd_data; + GNode *moof_node, *traf_node, *tfhd_node, *trun_node, *tfdt_node; + GstByteReader trun_data, tfhd_data, tfdt_data; guint32 ds_size = 0, ds_duration = 0, ds_flags = 0; gint64 base_offset, running_offset; @@ -2400,6 +2432,22 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length, if (!qtdemux_parse_tfhd (qtdemux, &tfhd_data, &stream, &ds_duration, &ds_size, &ds_flags, &base_offset)) goto missing_tfhd; + tfdt_node = + 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 (qtdemux->pending_newsegment) { + 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))); + } + } + if (G_UNLIKELY (!stream)) { /* we lost track of offset, we'll need to regain it, * but can delay complaining until later or avoid doing so altogether */ diff --git a/gst/isomp4/qtdemux_dump.c b/gst/isomp4/qtdemux_dump.c index 71350a6fa0..952b0c78da 100644 --- a/gst/isomp4/qtdemux_dump.c +++ b/gst/isomp4/qtdemux_dump.c @@ -720,6 +720,28 @@ qtdemux_dump_mehd (GstQTDemux * qtdemux, GstByteReader * data, int depth) return FALSE; } +gboolean +qtdemux_dump_tfdt (GstQTDemux * qtdemux, GstByteReader * data, int depth) +{ + guint32 version = 0; + guint64 decode_time; + guint value_size; + + if (!gst_byte_reader_get_uint32_be (data, &version)) + return FALSE; + + GST_LOG ("%*s version/flags: %08x", depth, "", version); + + value_size = ((version >> 24) == 1) ? sizeof (guint64) : sizeof (guint32); + if (qt_atom_parser_get_offset (data, value_size, &decode_time)) { + GST_LOG ("%*s Track fragment decode time: %" G_GUINT64_FORMAT, + depth, "", decode_time); + return TRUE; + } + + return FALSE; +} + gboolean qtdemux_dump_sdtp (GstQTDemux * qtdemux, GstByteReader * data, int depth) { diff --git a/gst/isomp4/qtdemux_dump.h b/gst/isomp4/qtdemux_dump.h index 9bb1f95d4b..d5486eebf0 100644 --- a/gst/isomp4/qtdemux_dump.h +++ b/gst/isomp4/qtdemux_dump.h @@ -75,6 +75,8 @@ gboolean qtdemux_dump_mehd (GstQTDemux * qtdemux, GstByteReader * data, int depth); gboolean qtdemux_dump_sdtp (GstQTDemux * qtdemux, GstByteReader * data, int depth); +gboolean qtdemux_dump_tfdt (GstQTDemux * qtdemux, GstByteReader * data, + int depth); gboolean qtdemux_dump_unknown (GstQTDemux * qtdemux, GstByteReader * data, int depth); diff --git a/gst/isomp4/qtdemux_fourcc.h b/gst/isomp4/qtdemux_fourcc.h index 6666a94e55..f2a3492916 100644 --- a/gst/isomp4/qtdemux_fourcc.h +++ b/gst/isomp4/qtdemux_fourcc.h @@ -230,6 +230,9 @@ G_BEGIN_DECLS #define FOURCC_ovc1 GST_MAKE_FOURCC('o','v','c','1') #define FOURCC_owma GST_MAKE_FOURCC('o','w','m','a') +/* MPEG DASH */ +#define FOURCC_tfdt GST_MAKE_FOURCC('t','f','d','t') + G_END_DECLS #endif /* __GST_QTDEMUX_FOURCC_H__ */ diff --git a/gst/isomp4/qtdemux_types.c b/gst/isomp4/qtdemux_types.c index 38da35b3d5..65afc8e2a8 100644 --- a/gst/isomp4/qtdemux_types.c +++ b/gst/isomp4/qtdemux_types.c @@ -171,6 +171,7 @@ static const QtNodeType qt_node_types[] = { qtdemux_dump_mehd}, {FOURCC_ovc1, "ovc1", 0}, {FOURCC_owma, "owma", 0}, + {FOURCC_tfdt, "Track fragment decode time", 0, qtdemux_dump_tfdt}, {0, "unknown", 0,}, };