[1/2] movdec: Ignore a nonzero mdhd duration if the file is fragmented

Message ID 1328007721-26731-1-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö Jan. 31, 2012, 11:02 a.m.
A nonzero mdhd duration sets st->duration, but st->duration is used
for setting dts on all packets in later fragments. For fragmented
fiels, st->duration should after the moov atom be the duration of
all samples described within the moov, not the duration of the
complete file.
---
 libavformat/mov.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 0ce32e0..2e27a94 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2159,6 +2159,8 @@  static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     MOVTrackExt *trex;
+    AVStream *st = NULL;
+    int i;
 
     if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
         return AVERROR_INVALIDDATA;
@@ -2174,6 +2176,23 @@  static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     trex->duration = avio_rb32(pb);
     trex->size     = avio_rb32(pb);
     trex->flags    = avio_rb32(pb);
+    for (i = 0; i < c->fc->nb_streams; i++) {
+        if (c->fc->streams[i]->id == trex->track_id) {
+            st = c->fc->streams[i];
+            break;
+        }
+    }
+    if (st) {
+        /* If the stts atom was empty, we didn't set st->duration based
+         * on that atom, but we might have set it based on what's written
+         * in mdhd. For some files, the mdhd duration is 0 if the moov
+         * doesn't contain any samples, but for others, this is the
+         * total duration of the file, including fragments. So make
+         * sure duration is 0 at this point, if the moov didn't contain
+         * any samples. */
+        if (!st->nb_frames)
+            st->duration = 0;
+    }
     return 0;
 }