guint32 def_sample_flags;
gboolean disabled;
+
+ GstClockTime elst_offset; /* sample offset from edit list */
};
enum QtDemuxState
if (qtdemux->duration != 0) {
if (qtdemux->duration != G_MAXINT64 && qtdemux->timescale != 0) {
*duration = gst_util_uint64_scale (qtdemux->duration,
- GST_SECOND, qtdemux->timescale);
+ GST_SECOND, qtdemux->timescale) - qtdemux->min_elst_offset;
}
}
return res;
{
GstFlowReturn ret = GST_FLOW_OK;
+ /* offset the timestamps according to the edit list */
+ if (GST_CLOCK_TIME_IS_VALID (pts))
+ pts += stream->elst_offset;
+ if (GST_CLOCK_TIME_IS_VALID (dts))
+ dts += stream->elst_offset;
+ position += stream->elst_offset;
+
if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) {
gchar *url;
GstMapInfo map;
guint32 rate_int;
media_time = QT_UINT32 (buffer + 20 + i * 12);
+ duration = QT_UINT32 (buffer + 16 + i * 12);
/* -1 media time is an empty segment, just ignore it */
- if (media_time == G_MAXUINT32)
+ if (media_time == G_MAXUINT32) {
+ if (i == 0) {
+ /* first empty segment specifies sample offset (if movie timescale) */
+ stream->elst_offset =
+ gst_util_uint64_scale (duration, GST_SECOND, qtdemux->timescale);
+ }
continue;
-
- duration = QT_UINT32 (buffer + 16 + i * 12);
+ }
segment = &stream->segments[count++];
guint64 creation_time;
GstDateTime *datetime = NULL;
gint version;
+ int i;
/* make sure we have a usable taglist */
if (!qtdemux->tag_list) {
qtdemux_parse_mehd (qtdemux, &mehd_data);
}
+ /* parse all traks */
+ trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
+ while (trak) {
+ qtdemux_parse_trak (qtdemux, trak);
+ /* iterate all siblings */
+ trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak);
+ }
+
+ /* make sure we don't offset samples more than we have to */
+ qtdemux->min_elst_offset = GST_CLOCK_TIME_NONE;
+ for (i = 0; i < qtdemux->n_streams; ++i) {
+ QtDemuxStream *stream = qtdemux->streams[i];
+ if (!GST_CLOCK_TIME_IS_VALID (qtdemux->min_elst_offset)
+ || stream->elst_offset < qtdemux->min_elst_offset) {
+ qtdemux->min_elst_offset = stream->elst_offset;
+ }
+ }
+ if (!GST_CLOCK_TIME_IS_VALID (qtdemux->min_elst_offset)) {
+ qtdemux->min_elst_offset = 0;
+ }
+ for (i = 0; i < qtdemux->n_streams; ++i) {
+ QtDemuxStream *stream = qtdemux->streams[i];
+ stream->elst_offset -= qtdemux->min_elst_offset;
+ }
+
/* set duration in the segment info */
gst_qtdemux_get_duration (qtdemux, &duration);
if (duration) {
qtdemux->segment.stop = duration;
}
- /* parse all traks */
- trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
- while (trak) {
- qtdemux_parse_trak (qtdemux, trak);
- /* iterate all siblings */
- trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak);
- }
-
/* find tags */
udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta);
if (udta) {