[FFmpeg-cvslog] movenc: Heuristically set the duration of the last sample in a fragment if not set

Martin Storsjö git at videolan.org
Thu Mar 19 12:18:22 CET 2015


ffmpeg | branch: master | Martin Storsjö <martin at martin.st> | Fri Mar  6 15:45:50 2015 +0200| [2889c5e16711770437f380f1bead5f72c6a0b17a] | committer: Martin Storsjö

movenc: Heuristically set the duration of the last sample in a fragment if not set

Even if this is a guess, it is way better than writing a zero duration
of the last sample in a fragment (because if the duration is zero,
the first sample of the next fragment will have the same timestamp
as the last sample in the previous one).

Since we normally don't require libavformat muxer users to set
the duration field in AVPacket, we probably can't strictly require
it here either, so don't log this as a strict warning, only as info.

Signed-off-by: Martin Storsjö <martin at martin.st>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2889c5e16711770437f380f1bead5f72c6a0b17a
---

 libavformat/movenc.c |   26 ++++++++++++++++++++++++++
 libavformat/movenc.h |    1 +
 2 files changed, 27 insertions(+)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index ae7029d..d2d7561 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3154,6 +3154,32 @@ static int mov_flush_fragment(AVFormatContext *s)
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
         return 0;
 
+    for (i = 0; i < mov->nb_streams; i++) {
+        MOVTrack *track = &mov->tracks[i];
+        if (track->entry <= 1)
+            continue;
+        // Sample durations are calculated as the diff of dts values,
+        // but for the last sample in a fragment, we don't know the dts
+        // of the first sample in the next fragment, so we have to rely
+        // on what was set as duration in the AVPacket. Not all callers
+        // set this though, so we might want to replace it with an
+        // estimate if it currently is zero.
+        if (get_cluster_duration(track, track->entry - 1) != 0)
+            continue;
+        // Use the duration (i.e. dts diff) of the second last sample for
+        // the last one. This is a wild guess (and fatal if it turns out
+        // to be too long), but probably the best we can do - having a zero
+        // duration is bad as well.
+        track->track_duration += get_cluster_duration(track, track->entry - 2);
+        if (!mov->missing_duration_warned) {
+            av_log(s, AV_LOG_WARNING,
+                   "Estimating the duration of the last packet in a "
+                   "fragment, consider setting the duration field in "
+                   "AVPacket instead.\n");
+            mov->missing_duration_warned = 1;
+        }
+    }
+
     if (!mov->moov_written) {
         int64_t pos = avio_tell(s->pb);
         int ret;
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index eb059d9..a1d4902 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -174,6 +174,7 @@ typedef struct MOVMuxContext {
 
     int use_editlist;
     int frag_interleave;
+    int missing_duration_warned;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT              (1 <<  0)



More information about the ffmpeg-cvslog mailing list