[FFmpeg-devel] [PATCH 2/2] mov: fix non-monotonous DTS when fragments overlap in time

John Stebbins jstebbins at jetheaddev.com
Sun Oct 1 19:46:47 EEST 2017


---
 libavformat/mov.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index c7422cd9ed..bc3c9cb35b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4267,6 +4267,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     int data_offset = 0;
     unsigned entries, first_sample_flags = frag->flags;
     int flags, distance, i;
+    int64_t last_dts = AV_NOPTS_VALUE;
 
     for (i = 0; i < c->fc->nb_streams; i++) {
         if (c->fc->streams[i]->id == frag->track_id) {
@@ -4294,6 +4295,10 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     offset = frag->base_data_offset + data_offset;
     distance = 0;
     av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
+
+    if (st->nb_index_entries)
+        last_dts = st->index_entries[st->nb_index_entries-1].timestamp;
+
     for (i = 0; i < entries && !pb->eof_reached; i++) {
         unsigned sample_size = frag->size;
         int sample_flags = i ? frag->flags : first_sample_flags;
@@ -4302,6 +4307,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         int keyframe = 0;
         int ctts_index = 0;
         int old_nb_index_entries = st->nb_index_entries;
+        int index_entry_flags = 0;
 
         if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
         if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
@@ -4338,10 +4344,16 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             keyframe =
                 !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
                                   MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
-        if (keyframe)
+        if (keyframe) {
             distance = 0;
+            index_entry_flags |= AVINDEX_KEYFRAME;
+        }
+        // Fragments can overlap in time.  Discard overlapping frames after
+        // decoding.
+        if (last_dts >= dts)
+            index_entry_flags |= AVINDEX_DISCARD_FRAME;
         ctts_index = add_index_entry(st, offset, dts, sample_size, distance,
-                                     keyframe ? AVINDEX_KEYFRAME : 0);
+                                     index_entry_flags);
         if (ctts_index >= 0 && old_nb_index_entries < st->nb_index_entries) {
             unsigned int size_needed = st->nb_index_entries * sizeof(*sc->ctts_data);
             unsigned int request_size = size_needed > sc->ctts_allocated_size ?
-- 
2.13.5



More information about the ffmpeg-devel mailing list