movdec: Make sure the stream duration is set based on stts instead of mdhd

Message ID 1328192860-20581-1-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö Feb. 2, 2012, 2:27 p.m.
A nonzero mdhd duration sets st->duration, but st->duration is used
for setting dts on all packets in later fragments. For fragmented
files, st->duration should after the moov atom be the duration of
all samples described within the moov, not the duration of the
complete file.

This fixes part of bug 215.
---
 libavformat/mov.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

Comments

Luca Barbato Feb. 6, 2012, 7:54 p.m. | #1
On 2/2/12 9:27 AM, Martin Storsjö wrote:
> A nonzero mdhd duration sets st->duration, but st->duration is used
> for setting dts on all packets in later fragments. For fragmented
> files, st->duration should after the moov atom be the duration of
> all samples described within the moov, not the duration of the
> complete file.
>

That might fix some issue with fragmented stream I'm messing with as 
well. Seems good, I need to find the time to test it soon.

lu

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 8723695..3b97893 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1609,8 +1609,14 @@  static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     av_dlog(c->fc, "track[%i].stts.entries = %i\n",
             c->fc->nb_streams-1, entries);
 
-    if (!entries)
+    if (!entries) {
+        /* No samples? For fragmented streams, we need to make sure st->duration
+         * is set to the duration of the samples described in moov. Some ismv
+         * files have the full file duration in mdhd and no samples at all
+         * here. */
+        st->duration = 0;
         return 0;
+    }
     if (entries >= UINT_MAX / sizeof(*sc->stts_data))
         return AVERROR(EINVAL);
 
@@ -1637,7 +1643,7 @@  static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     }
 
     st->nb_frames= total_sample_count;
-    if (duration)
+    if (duration || !total_sample_count)
         st->duration= duration;
     return 0;
 }