diff mbox

[FFmpeg-devel] lavf/mov: Add support for edit list parsing.

Message ID 1470442720-16940-2-git-send-email-isasi@google.com
State Changes Requested
Headers show

Commit Message

Sasi Inguva Aug. 6, 2016, 12:18 a.m. UTC
Signed-off-by: Sasi Inguva <isasi@google.com>
---
 libavcodec/avcodec.h                           |   6 +
 libavcodec/utils.c                             |   6 +
 libavformat/avformat.h                         |   3 +
 libavformat/mov.c                              | 305 ++++++++++++++++++++++++-
 libavutil/frame.h                              |   4 +
 tests/Makefile                                 |   1 +
 tests/fate/mov.mak                             |  28 +++
 tests/ref/fate/mov-1elist-1ctts                |  57 +++++
 tests/ref/fate/mov-1elist-ends-last-bframe     |  56 +++++
 tests/ref/fate/mov-1elist-noctts               |  57 +++++
 tests/ref/fate/mov-2elist-elist1-ends-bframe   |  51 +++++
 tests/ref/fate/mov-3elist                      |  57 +++++
 tests/ref/fate/mov-3elist-1ctts                |  57 +++++
 tests/ref/fate/mov-elist-starts-ctts-2ndsample |  57 +++++
 14 files changed, 744 insertions(+), 1 deletion(-)
 create mode 100644 tests/fate/mov.mak
 create mode 100644 tests/ref/fate/mov-1elist-1ctts
 create mode 100644 tests/ref/fate/mov-1elist-ends-last-bframe
 create mode 100644 tests/ref/fate/mov-1elist-noctts
 create mode 100644 tests/ref/fate/mov-2elist-elist1-ends-bframe
 create mode 100644 tests/ref/fate/mov-3elist
 create mode 100644 tests/ref/fate/mov-3elist-1ctts
 create mode 100644 tests/ref/fate/mov-elist-starts-ctts-2ndsample

Comments

Michael Niedermayer Aug. 6, 2016, 10:05 a.m. UTC | #1
On Fri, Aug 05, 2016 at 05:18:40PM -0700, Sasi Inguva wrote:
> Signed-off-by: Sasi Inguva <isasi@google.com>
> ---
>  libavcodec/avcodec.h                           |   6 +
>  libavcodec/utils.c                             |   6 +
>  libavformat/avformat.h                         |   3 +
>  libavformat/mov.c                              | 305 ++++++++++++++++++++++++-
>  libavutil/frame.h                              |   4 +
>  tests/Makefile                                 |   1 +
>  tests/fate/mov.mak                             |  28 +++
>  tests/ref/fate/mov-1elist-1ctts                |  57 +++++
>  tests/ref/fate/mov-1elist-ends-last-bframe     |  56 +++++
>  tests/ref/fate/mov-1elist-noctts               |  57 +++++
>  tests/ref/fate/mov-2elist-elist1-ends-bframe   |  51 +++++
>  tests/ref/fate/mov-3elist                      |  57 +++++
>  tests/ref/fate/mov-3elist-1ctts                |  57 +++++
>  tests/ref/fate/mov-elist-starts-ctts-2ndsample |  57 +++++
>  14 files changed, 744 insertions(+), 1 deletion(-)
>  create mode 100644 tests/fate/mov.mak
>  create mode 100644 tests/ref/fate/mov-1elist-1ctts
>  create mode 100644 tests/ref/fate/mov-1elist-ends-last-bframe
>  create mode 100644 tests/ref/fate/mov-1elist-noctts
>  create mode 100644 tests/ref/fate/mov-2elist-elist1-ends-bframe
>  create mode 100644 tests/ref/fate/mov-3elist
>  create mode 100644 tests/ref/fate/mov-3elist-1ctts
>  create mode 100644 tests/ref/fate/mov-elist-starts-ctts-2ndsample

breaks make fate

make: *** [fate-gaplessenc-itunes-to-ipod-aac] Error 1
make: *** [fate-gaplessenc-pcm-to-mov-aac] Error 1
make: *** [fate-h264-invalid-ref-mod] Error 1
make: *** [fate-pcm_s16be-stereo] Error 1
make: *** [fate-prores-gray] Error 1
make: *** [fate-tscc2-mov] Error 1
make: *** [fate-lavf-fate-mov_qtrle_mace6] Error 1
make: *** [fate-filter-fps-cfr] Error 1
make: *** [fate-quickdraw] Error 1
make: *** [fate-gsm-toast] Error 1

[...]
Michael Niedermayer Aug. 6, 2016, 10:32 a.m. UTC | #2
On Fri, Aug 05, 2016 at 05:18:40PM -0700, Sasi Inguva wrote:
> Signed-off-by: Sasi Inguva <isasi@google.com>
> ---
>  libavcodec/avcodec.h                           |   6 +
>  libavcodec/utils.c                             |   6 +
>  libavformat/avformat.h                         |   3 +
>  libavformat/mov.c                              | 305 ++++++++++++++++++++++++-
>  libavutil/frame.h                              |   4 +

the patch should be split into one patch per lib with version and
APIChanges updates to document the API changes used in the interface
between the libs


[...]
diff mbox

Patch

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 3b21537..d68da01 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1621,6 +1621,12 @@  typedef struct AVPacket {
 } AVPacket;
 #define AV_PKT_FLAG_KEY     0x0001 ///< The packet contains a keyframe
 #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
+/**
+ * Flag is used to discard packets which are required to maintain valid
+ * decoder state but are not required for output and should be dropped
+ * after decoding.
+ **/
+#define AV_PKT_FLAG_DISCARD   0x0004
 
 enum AVSideDataParamChangeFlags {
     AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT  = 0x0001,
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index f7adb52..eab5225 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -784,6 +784,10 @@  int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
             }
         }
         add_metadata_from_side_data(pkt, frame);
+
+        if (pkt->flags & AV_PKT_FLAG_DISCARD) {
+            frame->flags |= AV_FRAME_FLAG_DISCARD;
+        }
     } else {
         frame->pkt_pts = AV_NOPTS_VALUE;
         av_frame_set_pkt_pos     (frame, -1);
@@ -2248,6 +2252,8 @@  fail:
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
+        if (picture->flags & AV_FRAME_FLAG_DISCARD)
+            *got_picture_ptr = 0;
 
         if (*got_picture_ptr) {
             if (!avctx->refcounted_frames) {
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index d8a6cf3..8cf1401 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -814,6 +814,9 @@  typedef struct AVIndexEntry {
                                * is known
                                */
 #define AVINDEX_KEYFRAME 0x0001
+#define AVINDEX_DISCARD_FRAME  0x0002    /**
+                                          * Flag is used to indicate which frame should be discarded after decoding.
+                                          */
     int flags:2;
     int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
     int min_distance;         /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 7c8f784..4f88948 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2768,6 +2768,304 @@  static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     return pb->eof_reached ? AVERROR_EOF : 0;
 }
 
+/**
+ * Get ith edit list entry (media time, duration).
+ */
+static int get_edit_list_entry(MOVStreamContext *msc,
+                               unsigned int edit_list_index,
+                               int64_t *edit_list_media_time,
+                               int64_t *edit_list_duration,
+                               int64_t global_timescale)
+{
+    if (edit_list_index == msc->elst_count) {
+        return 0;
+    }
+    *edit_list_media_time = msc->elst_data[edit_list_index].time;
+    *edit_list_duration = msc->elst_data[edit_list_index].duration;
+    /* duration is in global timescale units;convert to msc timescale */
+    *edit_list_duration *= msc->time_scale;
+    *edit_list_duration /= global_timescale;
+    return 1;
+}
+
+/**
+ * Find the closest previous keyframe to the timestamp, in e_old index
+ * entries.
+ * Returns the index of the entry in st->index_entries if successful,
+ * else returns -1.
+ */
+static int64_t find_prev_closest_keyframe_index(AVStream *st,
+                                                AVIndexEntry *e_old,
+                                                int nb_old,
+                                                int64_t timestamp,
+                                                int flag)
+{
+    AVIndexEntry *e_keep = st->index_entries;
+    int nb_keep = st->nb_index_entries;
+    int64_t found = -1;
+
+    st->index_entries = e_old;
+    st->nb_index_entries = nb_old;
+    found = av_index_search_timestamp(st, timestamp, flag | AVSEEK_FLAG_BACKWARD);
+
+    /* restore AVStream  state*/
+    st->index_entries = e_keep;
+    st->nb_index_entries = nb_keep;
+    return found;
+}
+
+/**
+ * Add index entry with the given values, to the end of st->index_entries.
+ * Returns the new size st->index_entries if successful, else returns -1.
+ */
+static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+                               int size, int distance, int flags)
+{
+    AVIndexEntry *entries, *ie;
+    int64_t index = -1;
+    const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry);
+    const size_t requested_size =
+        min_size_needed > st->index_entries_allocated_size ?
+        FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
+        min_size_needed;
+
+    if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
+        return -1;
+
+    entries = av_fast_realloc(st->index_entries,
+                              &st->index_entries_allocated_size,
+                              requested_size);
+    if(!entries)
+        return -1;
+
+    st->index_entries= entries;
+
+    index= st->nb_index_entries++;
+    ie= &entries[index];
+    assert(!index || ie[-1].timestamp <= timestamp);
+
+    ie->pos = pos;
+    ie->timestamp = timestamp;
+    ie->min_distance= distance;
+    ie->size= size;
+    ie->flags = flags;
+    return index;
+}
+
+/**
+ * Append a new ctts entry to ctts_data.
+ * Returns the new ctts_count if successful, else returns -1.
+ */
+static int64_t add_ctts_entry(MOVStts** ctts_data, int64_t* ctts_count, unsigned int* allocated_size,
+                          int count, int duration)
+{
+    MOVStts *ctts_buf_new;
+    const size_t min_size_needed = (*ctts_count + 1) * sizeof(MOVStts);
+    const size_t requested_size =
+        min_size_needed > *allocated_size ?
+        FFMAX(min_size_needed, 2 * (*allocated_size)) :
+        min_size_needed;
+
+    if((unsigned)(*ctts_count) + 1 >= UINT_MAX / sizeof(MOVStts))
+        return -1;
+
+    ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
+
+    if(!ctts_buf_new)
+        return -1;
+
+    *ctts_data = ctts_buf_new;
+
+    ctts_buf_new[*ctts_count].count = count;
+    ctts_buf_new[*ctts_count].duration = duration;
+
+    *ctts_count = (*ctts_count) + 1;
+    return *ctts_count;
+}
+
+/**
+ * Fix st->index_entries, so that it contains only the entries (and the entries
+ * which are needed to decode them) that fall in the edit list time ranges.
+ * Also fixes the timestamps of the index entries to match the timeline
+ * specified the edit lists.
+ */
+static void mov_fix_index(MOVContext *mov, AVStream *st)
+{
+    MOVStreamContext *msc = st->priv_data;
+    AVIndexEntry *e_old = st->index_entries;
+    int nb_old = st->nb_index_entries;
+    const AVIndexEntry *e_old_end = e_old + nb_old;
+    const AVIndexEntry *current = NULL;
+    MOVStts *ctts_data_old = msc->ctts_data;
+    int64_t ctts_index_old = 0;
+    int64_t ctts_sample_old = 0;
+    int64_t ctts_count_old = msc->ctts_count;
+    int64_t edit_list_media_time = 0;
+    int64_t edit_list_duration = 0;
+    int64_t frame_duration = 0;
+    int64_t edit_list_dts_counter = 0;
+    int64_t edit_list_dts_entry_end = 0;
+    int64_t edit_list_start_ctts_sample = 0;
+    int64_t curr_cts;
+    int64_t edit_list_index = 0;
+    int64_t index;
+    int64_t index_ctts_count;
+    int flags;
+    unsigned int ctts_allocated_size = 0;
+    int64_t start_dts = 0;
+    int64_t edit_list_media_time_dts = 0;
+    int64_t edit_list_start_encountered = 0;
+
+
+    if (!msc->elst_data || msc->elst_count <= 0) {
+        return;
+    }
+    // Clean AVStream from traces of old index
+    st->index_entries = NULL;
+    st->index_entries_allocated_size = 0;
+    st->nb_index_entries = 0;
+
+    // Clean ctts fields of MOVStreamContext
+    msc->ctts_data = NULL;
+    msc->ctts_count = 0;
+    msc->ctts_index = 0;
+    msc->ctts_sample = 0;
+
+    // If the dts_shift is positive (in case of negative ctts values in mov),
+    // then negate the DTS by dts_shift
+    if (msc->dts_shift > 0)
+        edit_list_dts_entry_end -= msc->dts_shift;
+
+    // Offset the DTS by ctts[0] to make the PTS of the first frame 0
+    if (ctts_data_old && ctts_count_old > 0) {
+        edit_list_dts_entry_end -= ctts_data_old[0].duration;
+        av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by ctts[%d].duration: %d\n", 0, ctts_data_old[0].duration);
+    }
+
+    start_dts = edit_list_dts_entry_end;
+
+    while (get_edit_list_entry(msc, edit_list_index, &edit_list_media_time,
+                               &edit_list_duration, mov->time_scale)) {
+        av_log(mov->fc, AV_LOG_DEBUG, "Prrocessing st: %d, edit list %lld - media time: %lld, duration: %lld\n",
+               st->index, edit_list_index, edit_list_media_time, edit_list_duration);
+        edit_list_index++;
+        edit_list_dts_counter = edit_list_dts_entry_end;
+        edit_list_dts_entry_end += edit_list_duration;
+        if (edit_list_media_time == -1) {
+            continue;
+        }
+        //find closest previous key frame
+        edit_list_media_time_dts = edit_list_media_time;
+        if (msc->dts_shift > 0) {
+            edit_list_media_time_dts -= msc->dts_shift;
+        }
+
+        // While reordering frame index according to edit list we must handle properly
+        // the scenario when edit list entry starts from none key frame.
+        // We find closest previous key frame and preserve it and consequent frames in index.
+        // All frames which are outside edit list entry time boundaries will be dropped after decoding.
+        index = find_prev_closest_keyframe_index(st, e_old, nb_old, edit_list_media_time_dts,
+                                                 (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ? AVSEEK_FLAG_ANY : 0);
+        if (index == -1) {
+            av_log(mov->fc, AV_LOG_ERROR, "Missing key frame while reordering index according to edit list\n");
+            continue;
+        }
+        current = e_old + index;
+
+        ctts_index_old = 0;
+        ctts_sample_old = 0;
+
+        // set ctts_index properly for the found key frame
+        for (index_ctts_count = 0; index_ctts_count < index; index_ctts_count++) {
+            if (ctts_data_old && ctts_index_old < ctts_count_old) {
+                ctts_sample_old++;
+                if (ctts_data_old[ctts_index_old].count == ctts_sample_old) {
+                    ctts_index_old++;
+                    ctts_sample_old = 0;
+                }
+            }
+        }
+
+        edit_list_start_ctts_sample = ctts_sample_old;
+
+        // Iterate over index and arrange it according to edit list
+        edit_list_start_encountered = 0;
+        for (; current < e_old_end; current++, index++) {
+            // check  if frame outside edit list mark it for discard
+            frame_duration = (current + 1 <  e_old_end) ?
+                             ((current + 1)->timestamp - current->timestamp) : edit_list_duration;
+
+            flags = current->flags;
+
+            // frames (pts) before or after edit list
+            curr_cts = current->timestamp + msc->dts_shift;
+
+            if (ctts_data_old && ctts_index_old < ctts_count_old) {
+                av_log(mov->fc, AV_LOG_DEBUG, "shifted frame pts, curr_cts: %lld @ %lld, ctts: %d, ctts_count: %lld\n",
+                       curr_cts, ctts_index_old, ctts_data_old[ctts_index_old].duration, ctts_count_old);
+                curr_cts += ctts_data_old[ctts_index_old].duration;
+                ctts_sample_old++;
+                if (ctts_sample_old == ctts_data_old[ctts_index_old].count) {
+                    if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
+                                       &ctts_allocated_size,
+                                       ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
+                                       ctts_data_old[ctts_index_old].duration) == -1) {
+                        av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %lld - {%lld, %lld}\n",
+                               ctts_index_old,
+                               ctts_data_old[ctts_index_old].count - edit_list_start_ctts_sample,
+                               ctts_data_old[ctts_index_old].duration);
+                        break;
+                    }
+                    ctts_index_old++;
+                    ctts_sample_old = 0;
+                    edit_list_start_ctts_sample = 0;
+                }
+            }
+            if (curr_cts < edit_list_media_time || curr_cts >= (edit_list_duration + edit_list_media_time)) {
+                flags |= AVINDEX_DISCARD_FRAME;
+                av_log(mov->fc, AV_LOG_DEBUG, "drop a frame at curr_cts: %lld @ %lld\n", curr_cts, index);
+            } else if (edit_list_start_encountered == 0) {
+                edit_list_start_encountered = 1;
+            }
+
+            if (add_index_entry(st, current->pos, edit_list_dts_counter, current->size,
+                                current->min_distance, flags) == -1) {
+                av_log(mov->fc, AV_LOG_ERROR, "Cannot add index entry\n");
+                break;
+            }
+
+            // Only start incrementing DTS in frame_duration amounts, when we encounter a frame in edit list.
+            if (edit_list_start_encountered > 0) {
+                edit_list_dts_counter = edit_list_dts_counter + frame_duration;
+            }
+
+            // Break when found first key frame after edit entry completion
+            if (((curr_cts + frame_duration) >= (edit_list_duration + edit_list_media_time)) &&
+                ((flags & AVINDEX_KEYFRAME) || ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO)))) {
+
+                if (ctts_data_old && ctts_sample_old != 0) {
+                    if (add_ctts_entry(&msc->ctts_data, &msc->ctts_count,
+                                       &ctts_allocated_size,
+                                       ctts_sample_old - edit_list_start_ctts_sample,
+                                       ctts_data_old[ctts_index_old].duration) == -1) {
+                        av_log(mov->fc, AV_LOG_ERROR, "Cannot add CTTS entry %lld - {%lld, %d}\n",
+                               ctts_index_old, ctts_sample_old - edit_list_start_ctts_sample,
+                               ctts_data_old[ctts_index_old].duration);
+                        break;
+                    }
+                }
+                break;
+            }
+        }
+    }
+    // Update av stream length
+    st->duration = edit_list_dts_entry_end - start_dts;
+
+    // Free the old index and the old CTTS structures
+    av_free(e_old);
+    av_free(ctts_data_old);
+}
+
 static void mov_build_index(MOVContext *mov, AVStream *st)
 {
     MOVStreamContext *sc = st->priv_data;
@@ -2806,7 +3104,6 @@  static void mov_build_index(MOVContext *mov, AVStream *st)
             if (empty_duration)
                 empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
             sc->time_offset = start_time - empty_duration;
-            current_dts = -sc->time_offset;
             if (sc->ctts_count>0 && sc->stts_count>0 &&
                 sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) {
                 /* more than 16 frames delay, dts are likely wrong
@@ -3050,6 +3347,9 @@  static void mov_build_index(MOVContext *mov, AVStream *st)
             }
         }
     }
+
+    // Fix index according to edit lists.
+    mov_fix_index(mov, st);
 }
 
 static int test_same_origin(const char *src, const char *ref) {
@@ -5344,6 +5644,9 @@  static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     pkt->stream_index = sc->ffindex;
     pkt->dts = sample->timestamp;
+    if (sample->flags & AVINDEX_DISCARD_FRAME) {
+        pkt->flags |= AV_PKT_FLAG_DISCARD;
+    }
     if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
         pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
         /* update ctts context */
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 8a41a86..68f42f3 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -396,6 +396,10 @@  typedef struct AVFrame {
  */
 #define AV_FRAME_FLAG_CORRUPT       (1 << 0)
 /**
+ * A flag to mark the frames which need to be decoded, but shouldn't be output.
+ */
+#define AV_FRAME_FLAG_DISCARD   0x0004
+/**
  * @}
  */
 
diff --git a/tests/Makefile b/tests/Makefile
index 895944d..e191470 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -148,6 +148,7 @@  include $(SRC_PATH)/tests/fate/lossless-video.mak
 include $(SRC_PATH)/tests/fate/matroska.mak
 include $(SRC_PATH)/tests/fate/microsoft.mak
 include $(SRC_PATH)/tests/fate/monkeysaudio.mak
+include $(SRC_PATH)/tests/fate/mov.mak
 include $(SRC_PATH)/tests/fate/mp3.mak
 include $(SRC_PATH)/tests/fate/mpc.mak
 include $(SRC_PATH)/tests/fate/mpeg4.mak
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
new file mode 100644
index 0000000..5b3a187
--- /dev/null
+++ b/tests/fate/mov.mak
@@ -0,0 +1,28 @@ 
+FATE_MOV = fate-mov-3elist \
+	   fate-mov-3elist-1ctts \
+	   fate-mov-1elist-1ctts \
+	   fate-mov-1elist-noctts \
+	   fate-mov-elist-starts-ctts-2ndsample \
+	   fate-mov-1elist-ends-last-bframe \
+	   fate-mov-2elist-elist1-ends-bframe
+
+FATE_SAMPLES_AVCONV += $(FATE_MOV)
+
+fate-mov: $(FATE_MOV)
+
+# Make sure we handle edit lists correctly in normal cases.
+fate-mov-1elist-noctts: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-1elist-noctts.mov
+fate-mov-1elist-1ctts: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-1elist-1ctts.mov
+fate-mov-3elist: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-3elist.mov
+fate-mov-3elist-1ctts: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-3elist-1ctts.mov
+
+# Makes sure that the CTTS is also modified when we fix avindex in mov.c while parsing edit lists.
+fate-mov-elist-starts-ctts-2ndsample: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-elist-starts-ctts-2ndsample.mov
+
+# Makes sure that we handle edit lists ending on a B-frame correctly.
+# The last frame in decoding order which is B-frame should be output, but the last but-one P-frame shouldn't be
+# output.
+fate-mov-1elist-ends-last-bframe: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-1elist-ends-last-bframe.mov
+
+# Makes sure that we handle timestamps of packets in case of multiple edit lists with one of them ending on a B-frame correctly.
+fate-mov-2elist-elist1-ends-bframe: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/mov-2elist-elist1-ends-bframe.mov
\ No newline at end of file
diff --git a/tests/ref/fate/mov-1elist-1ctts b/tests/ref/fate/mov-1elist-1ctts
new file mode 100644
index 0000000..379d47a
--- /dev/null
+++ b/tests/ref/fate/mov-1elist-1ctts
@@ -0,0 +1,57 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, 3dd21395fc5d3429f9b08492f47af093
+0,          1,          1,        1,   460800, 117009cceecc160c385dac3d344505c9
+0,          2,          2,        1,   460800, c093aa6e8747287cfeb758f2da7476d1
+0,          3,          3,        1,   460800, 6b7c94a3363f3381f7f930ac02b0c975
+0,          4,          4,        1,   460800, 87c3824a0ef3566f1a384c3c3e2b0d96
+0,          5,          5,        1,   460800, 3de48f3009a159e4737b5993102266de
+0,          6,          6,        1,   460800, 2be0ed1afe921093645af2ff917281ab
+0,          7,          7,        1,   460800, a89170c8413305fdba8d413a5080e57a
+0,          8,          8,        1,   460800, 5a3be131222c223ef8eccd9636330839
+0,          9,          9,        1,   460800, 01068b423526481b9732214c16b9e229
+0,         10,         10,        1,   460800, f9ea60560154e82d77e2661c34dca143
+0,         11,         11,        1,   460800, d77f5b82e34ea5a450076a85141a5618
+0,         12,         12,        1,   460800, 91ff4efcfc3a2301fb2329139e0e71a2
+0,         13,         13,        1,   460800, af8d914008f5f64f2ec1fadfae8bc697
+0,         14,         14,        1,   460800, abb2c4fd1f1ce3c449236da246b62bef
+0,         15,         15,        1,   460800, 66b0558f03dd5a472836fea045dd06ea
+0,         16,         16,        1,   460800, 224207d3e5b93fc4e8c71b782aabca51
+0,         17,         17,        1,   460800, ef975cfa7bc4de88f1333eb301f7ebdd
+0,         18,         18,        1,   460800, d75bf790003d2b1ee56bea0cef068e8e
+0,         19,         19,        1,   460800, d7a16935d7f808cca046db971e5b612a
+0,         20,         20,        1,   460800, f49d06ca4995c267fdc8c674c992cdd1
+0,         21,         21,        1,   460800, f53fd634154dec26ec85b6bef01ba890
+0,         22,         22,        1,   460800, d2d36371e50ace43ae4d2bab092a24c3
+0,         23,         23,        1,   460800, a4c08f4979e7dc914d69a170e198656c
+0,         24,         24,        1,   460800, 0d128e33f156fcc228d92117d56a5f93
+0,         25,         25,        1,   460800, 52fb8fc75c848ed9bc61d5129473f3fb
+0,         26,         26,        1,   460800, 5517f79d2ccb4fc93ede061bfcd632ea
+0,         27,         27,        1,   460800, c24fea9e8d02240328de3cb520904a6b
+0,         28,         28,        1,   460800, 0cbe46a4b91a0bd235d5e74084058e61
+0,         29,         29,        1,   460800, 355b17c2feb6b809c95bb71b333a670d
+0,         30,         30,        1,   460800, 063643ba941293ba95e024da202267cb
+0,         31,         31,        1,   460800, 8b31727d492fa9b25e025a1f45425b16
+0,         32,         32,        1,   460800, 45c5901c24d2ae2304b3e82c075a96bf
+0,         33,         33,        1,   460800, b7d4449d0e2157093727cb0f00648751
+0,         34,         34,        1,   460800, 167642e702f645853c974531853987f8
+0,         35,         35,        1,   460800, 2eb4596d675f099bab6c3b40ce30fd88
+0,         36,         36,        1,   460800, 8dd1aec35b92610cb22bedd3c54cb26a
+0,         37,         37,        1,   460800, 8eacf32e58d9a731467aba0f61d9e60f
+0,         38,         38,        1,   460800, 6a735f86d18ebe265894f633071a25d7
+0,         39,         39,        1,   460800, 843b0c938845b72e1c23bc39f7479cba
+0,         40,         40,        1,   460800, ca2099b43141cb9131505ab40ac3959f
+0,         41,         41,        1,   460800, e65322e1929def11f9985683365ab6bf
+0,         42,         42,        1,   460800, 565410a8c2f4b50a192f9590e6ab32c0
+0,         43,         43,        1,   460800, fa9a8ac625854cc279a07766ddad6e6f
+0,         44,         44,        1,   460800, a46ac62886c48edef3dc58de34a2a004
+0,         45,         45,        1,   460800, 414e01b6c24e71efc9c58f65dc0f4aca
+0,         46,         46,        1,   460800, e0501b903f21b490da049e51e7a02bae
+0,         47,         47,        1,   460800, 48b30eec1e9d862ee54b136045e1d90f
diff --git a/tests/ref/fate/mov-1elist-ends-last-bframe b/tests/ref/fate/mov-1elist-ends-last-bframe
new file mode 100644
index 0000000..4f8f1ae
--- /dev/null
+++ b/tests/ref/fate/mov-1elist-ends-last-bframe
@@ -0,0 +1,56 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, b3d774603a22dbf9e952465c0d295166
+0,          1,          1,        1,   460800, d8f88e4269888dfadeb15bec662a3851
+0,          2,          2,        1,   460800, 6d6e686070143f797f8f1eca43d9cf28
+0,          3,          3,        1,   460800, a934f883968e71f22df044f043e61b14
+0,          4,          4,        1,   460800, 83dc65c7703f43ce97c87eea7191f69e
+0,          5,          5,        1,   460800, d633ab0dba64277b104ff5c2e1983424
+0,          6,          6,        1,   460800, 6c7d2c7481bd11584d68dbb9262d8351
+0,          7,          7,        1,   460800, 59b0bbc661b79ba82d726ca4d28255f2
+0,          8,          8,        1,   460800, 821cd7ca0adc4d6a3f10419b6c4283a6
+0,          9,          9,        1,   460800, 4655b1d6e8237b2e880f5b4140f7cf08
+0,         10,         10,        1,   460800, 264858653f9ac0623ffc87ca5e4c9939
+0,         11,         11,        1,   460800, b7129e91b9a6b4f8582747f12cafa52e
+0,         12,         12,        1,   460800, 1f6596fba655e213fd5c2ea99a891138
+0,         13,         13,        1,   460800, c8d67dc8fa8bdca263060ae542e55278
+0,         14,         14,        1,   460800, 57aa680b64b140eaeaa7f4250c12b59e
+0,         15,         15,        1,   460800, b87e8a9c0701cd8811dd38292b9994f7
+0,         16,         16,        1,   460800, 2427eb2900c8e18da0f36e47799a5ed8
+0,         17,         17,        1,   460800, 710a727a7ba51bc2938ca83376c6edd6
+0,         18,         18,        1,   460800, 44d5ce80804d9ca470f9e5348c66e9b3
+0,         19,         19,        1,   460800, 448e1fc3af42c4143e5fc4120090cdd6
+0,         20,         20,        1,   460800, 7c2c4c61843cfdd033b8fa295766a524
+0,         21,         21,        1,   460800, 20a197cb4e20857e135d4c10945987f6
+0,         22,         22,        1,   460800, 7534b00e60f6920da7b767aef0876e65
+0,         23,         23,        1,   460800, b88cedb84145f07226d5573aa57a1cce
+0,         24,         24,        1,   460800, 620751271985df3728b6dbc627974183
+0,         25,         25,        1,   460800, 643719b26ac93f93d1674fee97c58a35
+0,         26,         26,        1,   460800, 5d3f8fa9abab0256afbf4285cd337804
+0,         27,         27,        1,   460800, a6c302c54c6481088f9c27189ecda5a8
+0,         28,         28,        1,   460800, 2851ad86c15a1dc7b6d4a0fe8f15de8f
+0,         29,         29,        1,   460800, 42157005018908c810b1840856778482
+0,         30,         30,        1,   460800, 2541042038568329922fd6f7187aad49
+0,         31,         31,        1,   460800, 855b9ecfa9da66ef5971fcea7e515890
+0,         32,         32,        1,   460800, 85df610183efce5de91946cb909019c9
+0,         33,         33,        1,   460800, 369bce83d8aa0ac3cfb853b7e2886896
+0,         34,         34,        1,   460800, b428e7b294e5ac0d316971e02a25b12a
+0,         35,         35,        1,   460800, aa66321995b890e8dbd0d7b188ecb19c
+0,         36,         36,        1,   460800, 1533e3c85fd9d1f6710442653b936ef0
+0,         37,         37,        1,   460800, 99f3d38c95f1e4c0b442007a466f77cb
+0,         38,         38,        1,   460800, 30e007d8a4c0f0cfa22c8b6051980b59
+0,         39,         39,        1,   460800, fef21426b54048af617211234ee9b602
+0,         40,         40,        1,   460800, ff9a482c793a8e9950c0aa7e2845ca0e
+0,         41,         41,        1,   460800, ac0bb586786c35a51bdb6a5514ff54b9
+0,         42,         42,        1,   460800, bb008ec74fe642d6350bb1b4c922a6b0
+0,         43,         43,        1,   460800, 3e4255d1e817b9c6fa2cfbb0f198069d
+0,         44,         44,        1,   460800, 0fe04242f0441fa5c90e69ca015f4b2d
+0,         45,         45,        1,   460800, f14c12ec008a56c9aa99ef1be857ad23
+0,         46,         46,        1,   460800, 43ac558397b699ac82f7e12810c7ade9
diff --git a/tests/ref/fate/mov-1elist-noctts b/tests/ref/fate/mov-1elist-noctts
new file mode 100644
index 0000000..379d47a
--- /dev/null
+++ b/tests/ref/fate/mov-1elist-noctts
@@ -0,0 +1,57 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, 3dd21395fc5d3429f9b08492f47af093
+0,          1,          1,        1,   460800, 117009cceecc160c385dac3d344505c9
+0,          2,          2,        1,   460800, c093aa6e8747287cfeb758f2da7476d1
+0,          3,          3,        1,   460800, 6b7c94a3363f3381f7f930ac02b0c975
+0,          4,          4,        1,   460800, 87c3824a0ef3566f1a384c3c3e2b0d96
+0,          5,          5,        1,   460800, 3de48f3009a159e4737b5993102266de
+0,          6,          6,        1,   460800, 2be0ed1afe921093645af2ff917281ab
+0,          7,          7,        1,   460800, a89170c8413305fdba8d413a5080e57a
+0,          8,          8,        1,   460800, 5a3be131222c223ef8eccd9636330839
+0,          9,          9,        1,   460800, 01068b423526481b9732214c16b9e229
+0,         10,         10,        1,   460800, f9ea60560154e82d77e2661c34dca143
+0,         11,         11,        1,   460800, d77f5b82e34ea5a450076a85141a5618
+0,         12,         12,        1,   460800, 91ff4efcfc3a2301fb2329139e0e71a2
+0,         13,         13,        1,   460800, af8d914008f5f64f2ec1fadfae8bc697
+0,         14,         14,        1,   460800, abb2c4fd1f1ce3c449236da246b62bef
+0,         15,         15,        1,   460800, 66b0558f03dd5a472836fea045dd06ea
+0,         16,         16,        1,   460800, 224207d3e5b93fc4e8c71b782aabca51
+0,         17,         17,        1,   460800, ef975cfa7bc4de88f1333eb301f7ebdd
+0,         18,         18,        1,   460800, d75bf790003d2b1ee56bea0cef068e8e
+0,         19,         19,        1,   460800, d7a16935d7f808cca046db971e5b612a
+0,         20,         20,        1,   460800, f49d06ca4995c267fdc8c674c992cdd1
+0,         21,         21,        1,   460800, f53fd634154dec26ec85b6bef01ba890
+0,         22,         22,        1,   460800, d2d36371e50ace43ae4d2bab092a24c3
+0,         23,         23,        1,   460800, a4c08f4979e7dc914d69a170e198656c
+0,         24,         24,        1,   460800, 0d128e33f156fcc228d92117d56a5f93
+0,         25,         25,        1,   460800, 52fb8fc75c848ed9bc61d5129473f3fb
+0,         26,         26,        1,   460800, 5517f79d2ccb4fc93ede061bfcd632ea
+0,         27,         27,        1,   460800, c24fea9e8d02240328de3cb520904a6b
+0,         28,         28,        1,   460800, 0cbe46a4b91a0bd235d5e74084058e61
+0,         29,         29,        1,   460800, 355b17c2feb6b809c95bb71b333a670d
+0,         30,         30,        1,   460800, 063643ba941293ba95e024da202267cb
+0,         31,         31,        1,   460800, 8b31727d492fa9b25e025a1f45425b16
+0,         32,         32,        1,   460800, 45c5901c24d2ae2304b3e82c075a96bf
+0,         33,         33,        1,   460800, b7d4449d0e2157093727cb0f00648751
+0,         34,         34,        1,   460800, 167642e702f645853c974531853987f8
+0,         35,         35,        1,   460800, 2eb4596d675f099bab6c3b40ce30fd88
+0,         36,         36,        1,   460800, 8dd1aec35b92610cb22bedd3c54cb26a
+0,         37,         37,        1,   460800, 8eacf32e58d9a731467aba0f61d9e60f
+0,         38,         38,        1,   460800, 6a735f86d18ebe265894f633071a25d7
+0,         39,         39,        1,   460800, 843b0c938845b72e1c23bc39f7479cba
+0,         40,         40,        1,   460800, ca2099b43141cb9131505ab40ac3959f
+0,         41,         41,        1,   460800, e65322e1929def11f9985683365ab6bf
+0,         42,         42,        1,   460800, 565410a8c2f4b50a192f9590e6ab32c0
+0,         43,         43,        1,   460800, fa9a8ac625854cc279a07766ddad6e6f
+0,         44,         44,        1,   460800, a46ac62886c48edef3dc58de34a2a004
+0,         45,         45,        1,   460800, 414e01b6c24e71efc9c58f65dc0f4aca
+0,         46,         46,        1,   460800, e0501b903f21b490da049e51e7a02bae
+0,         47,         47,        1,   460800, 48b30eec1e9d862ee54b136045e1d90f
diff --git a/tests/ref/fate/mov-2elist-elist1-ends-bframe b/tests/ref/fate/mov-2elist-elist1-ends-bframe
new file mode 100644
index 0000000..76296ca
--- /dev/null
+++ b/tests/ref/fate/mov-2elist-elist1-ends-bframe
@@ -0,0 +1,51 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, b3d774603a22dbf9e952465c0d295166
+0,          1,          1,        1,   460800, d8f88e4269888dfadeb15bec662a3851
+0,          2,          2,        1,   460800, 6d6e686070143f797f8f1eca43d9cf28
+0,          3,          3,        1,   460800, a934f883968e71f22df044f043e61b14
+0,          4,          4,        1,   460800, 83dc65c7703f43ce97c87eea7191f69e
+0,          5,          5,        1,   460800, d633ab0dba64277b104ff5c2e1983424
+0,          6,          6,        1,   460800, 6c7d2c7481bd11584d68dbb9262d8351
+0,          7,          7,        1,   460800, 59b0bbc661b79ba82d726ca4d28255f2
+0,          8,          8,        1,   460800, 821cd7ca0adc4d6a3f10419b6c4283a6
+0,          9,          9,        1,   460800, 4655b1d6e8237b2e880f5b4140f7cf08
+0,         10,         10,        1,   460800, 264858653f9ac0623ffc87ca5e4c9939
+0,         11,         11,        1,   460800, b7129e91b9a6b4f8582747f12cafa52e
+0,         12,         12,        1,   460800, 1f6596fba655e213fd5c2ea99a891138
+0,         13,         13,        1,   460800, c8d67dc8fa8bdca263060ae542e55278
+0,         14,         14,        1,   460800, 57aa680b64b140eaeaa7f4250c12b59e
+0,         15,         15,        1,   460800, b87e8a9c0701cd8811dd38292b9994f7
+0,         16,         16,        1,   460800, 2427eb2900c8e18da0f36e47799a5ed8
+0,         17,         17,        1,   460800, 710a727a7ba51bc2938ca83376c6edd6
+0,         18,         18,        1,   460800, 620751271985df3728b6dbc627974183
+0,         19,         19,        1,   460800, 643719b26ac93f93d1674fee97c58a35
+0,         20,         20,        1,   460800, 5d3f8fa9abab0256afbf4285cd337804
+0,         21,         21,        1,   460800, a6c302c54c6481088f9c27189ecda5a8
+0,         22,         22,        1,   460800, 2851ad86c15a1dc7b6d4a0fe8f15de8f
+0,         23,         23,        1,   460800, 42157005018908c810b1840856778482
+0,         24,         24,        1,   460800, 2541042038568329922fd6f7187aad49
+0,         25,         25,        1,   460800, 855b9ecfa9da66ef5971fcea7e515890
+0,         26,         26,        1,   460800, 85df610183efce5de91946cb909019c9
+0,         27,         27,        1,   460800, 369bce83d8aa0ac3cfb853b7e2886896
+0,         28,         28,        1,   460800, b428e7b294e5ac0d316971e02a25b12a
+0,         29,         29,        1,   460800, aa66321995b890e8dbd0d7b188ecb19c
+0,         30,         30,        1,   460800, 1533e3c85fd9d1f6710442653b936ef0
+0,         31,         31,        1,   460800, 99f3d38c95f1e4c0b442007a466f77cb
+0,         32,         32,        1,   460800, 30e007d8a4c0f0cfa22c8b6051980b59
+0,         33,         33,        1,   460800, fef21426b54048af617211234ee9b602
+0,         34,         34,        1,   460800, ff9a482c793a8e9950c0aa7e2845ca0e
+0,         35,         35,        1,   460800, ac0bb586786c35a51bdb6a5514ff54b9
+0,         36,         36,        1,   460800, bb008ec74fe642d6350bb1b4c922a6b0
+0,         37,         37,        1,   460800, 3e4255d1e817b9c6fa2cfbb0f198069d
+0,         38,         38,        1,   460800, 0fe04242f0441fa5c90e69ca015f4b2d
+0,         39,         39,        1,   460800, f14c12ec008a56c9aa99ef1be857ad23
+0,         40,         40,        1,   460800, 43ac558397b699ac82f7e12810c7ade9
+0,         41,         41,        1,   460800, 35431eb1a8be4f05d08d23380655178c
diff --git a/tests/ref/fate/mov-3elist b/tests/ref/fate/mov-3elist
new file mode 100644
index 0000000..daf4927
--- /dev/null
+++ b/tests/ref/fate/mov-3elist
@@ -0,0 +1,57 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, 80fbbdec589e15e6c493b44d243f92a9
+0,          1,          1,        1,   460800, f4b23293bb2ecf69cc3570853d8c56a1
+0,          2,          2,        1,   460800, 0c03ce2c1c6ec405d7455465ecd559a3
+0,          3,          3,        1,   460800, 7921791695537fba2c3c123da4834cb9
+0,          4,          4,        1,   460800, 30c8e2903a561b84d4cbaf95c668d236
+0,          5,          5,        1,   460800, 7ff42e998217c17592ddf6b584f26cef
+0,          6,          6,        1,   460800, 5e402c48bf097db2d31b82bb4194a382
+0,          7,          7,        1,   460800, 824c49e92c8ae6d99a0207b514dd756c
+0,          8,          8,        1,   460800, 24f189216a1d9cf2313b2d6dbe3dbdd3
+0,          9,          9,        1,   460800, 519179a8e74275d26b183374637e003f
+0,         10,         10,        1,   460800, f18331ddcef0adf5b069bfa98baf8db4
+0,         11,         11,        1,   460800, 081f61688690d47dbdddd5384e5d5a70
+0,         12,         12,        1,   460800, 90dbf019b9035433371a8df41a9268b7
+0,         13,         13,        1,   460800, bb5adfb9c66732898b34186eca1667ba
+0,         14,         14,        1,   460800, cc08cfd64f37783ecddaf143f6ad78bc
+0,         15,         15,        1,   460800, b8ae21d024fe4df903d56f4521993c72
+0,         16,         16,        1,   460800, b45a99907f045dcadf0a2befc11555e3
+0,         17,         17,        1,   460800, 603ba935845e65ab6cccbbec88bbf60d
+0,         18,         18,        1,   460800, df80c8d3e6a77258a306903f17995a18
+0,         19,         19,        1,   460800, 4b7e90c0a5fd0e0cd958d47f0afac636
+0,         20,         20,        1,   460800, 9feb6e36182f1745be6387edea240eb6
+0,         21,         21,        1,   460800, 86e6de4bd0a5ff7558f4cf6c1ec3930d
+0,         22,         22,        1,   460800, 726b69df77edbe7b503d4698656d1320
+0,         23,         23,        1,   460800, d282fb7a953ac205b0a43d00c2d60a33
+0,         24,         24,        1,   460800, eece3daa70cc20208dd75d91ac84c8fd
+0,         25,         25,        1,   460800, c86d23e73bcce351fc315fb1f13348da
+0,         26,         26,        1,   460800, 93497b4f7c5ad9d61212239b7c9d2770
+0,         27,         27,        1,   460800, eb217d2c12de67903835a8c58f620488
+0,         28,         28,        1,   460800, d966480867bb54c8cd044f18388ed486
+0,         29,         29,        1,   460800, 3ea6207942b3181fdd8e8aa6cae1062a
+0,         30,         30,        1,   460800, 2620df54aca086ec0fb9527c6e6f5135
+0,         31,         31,        1,   460800, 43bb7320f0bb583188dc965ddbfade90
+0,         32,         32,        1,   460800, 0cddaa04645f804e02f65b0836412113
+0,         33,         33,        1,   460800, 83b2dc95807289d7f4a4632bf18c2e97
+0,         34,         34,        1,   460800, 98134d0e41e6dd12827049ccf33b4669
+0,         35,         35,        1,   460800, 56f55631731fa39c7acbab0afeb2eb1b
+0,         36,         36,        1,   460800, 379c1105be09d836a515dc909455ddf4
+0,         37,         37,        1,   460800, 1df87c47e9d98731faf1c3885b77e5da
+0,         38,         38,        1,   460800, 9a8734bcbfdb4d97e530683b8b556a26
+0,         39,         39,        1,   460800, c7a7990d0cddc5adfbe27da7a42e025e
+0,         40,         40,        1,   460800, 0c81e46011e03be410feaf056207fd55
+0,         41,         41,        1,   460800, ca76e4e63016ff29d8aeeb9cb053bb6c
+0,         42,         42,        1,   460800, cebfbe299c17c1f8fc1e6b189555c3c2
+0,         43,         43,        1,   460800, 4f002c5feca5e75f07089e0df47507dd
+0,         44,         44,        1,   460800, c5fd83fc4a745abee9b3d9a6eec9dd3e
+0,         45,         45,        1,   460800, 57d9bad9b45aa2746de5d8bdc2c24969
+0,         46,         46,        1,   460800, 9831673ad7dec167af4a959f64258949
+0,         47,         47,        1,   460800, 77a1cb208f70f51bcb01e28d8cba73b4
diff --git a/tests/ref/fate/mov-3elist-1ctts b/tests/ref/fate/mov-3elist-1ctts
new file mode 100644
index 0000000..379d47a
--- /dev/null
+++ b/tests/ref/fate/mov-3elist-1ctts
@@ -0,0 +1,57 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, 3dd21395fc5d3429f9b08492f47af093
+0,          1,          1,        1,   460800, 117009cceecc160c385dac3d344505c9
+0,          2,          2,        1,   460800, c093aa6e8747287cfeb758f2da7476d1
+0,          3,          3,        1,   460800, 6b7c94a3363f3381f7f930ac02b0c975
+0,          4,          4,        1,   460800, 87c3824a0ef3566f1a384c3c3e2b0d96
+0,          5,          5,        1,   460800, 3de48f3009a159e4737b5993102266de
+0,          6,          6,        1,   460800, 2be0ed1afe921093645af2ff917281ab
+0,          7,          7,        1,   460800, a89170c8413305fdba8d413a5080e57a
+0,          8,          8,        1,   460800, 5a3be131222c223ef8eccd9636330839
+0,          9,          9,        1,   460800, 01068b423526481b9732214c16b9e229
+0,         10,         10,        1,   460800, f9ea60560154e82d77e2661c34dca143
+0,         11,         11,        1,   460800, d77f5b82e34ea5a450076a85141a5618
+0,         12,         12,        1,   460800, 91ff4efcfc3a2301fb2329139e0e71a2
+0,         13,         13,        1,   460800, af8d914008f5f64f2ec1fadfae8bc697
+0,         14,         14,        1,   460800, abb2c4fd1f1ce3c449236da246b62bef
+0,         15,         15,        1,   460800, 66b0558f03dd5a472836fea045dd06ea
+0,         16,         16,        1,   460800, 224207d3e5b93fc4e8c71b782aabca51
+0,         17,         17,        1,   460800, ef975cfa7bc4de88f1333eb301f7ebdd
+0,         18,         18,        1,   460800, d75bf790003d2b1ee56bea0cef068e8e
+0,         19,         19,        1,   460800, d7a16935d7f808cca046db971e5b612a
+0,         20,         20,        1,   460800, f49d06ca4995c267fdc8c674c992cdd1
+0,         21,         21,        1,   460800, f53fd634154dec26ec85b6bef01ba890
+0,         22,         22,        1,   460800, d2d36371e50ace43ae4d2bab092a24c3
+0,         23,         23,        1,   460800, a4c08f4979e7dc914d69a170e198656c
+0,         24,         24,        1,   460800, 0d128e33f156fcc228d92117d56a5f93
+0,         25,         25,        1,   460800, 52fb8fc75c848ed9bc61d5129473f3fb
+0,         26,         26,        1,   460800, 5517f79d2ccb4fc93ede061bfcd632ea
+0,         27,         27,        1,   460800, c24fea9e8d02240328de3cb520904a6b
+0,         28,         28,        1,   460800, 0cbe46a4b91a0bd235d5e74084058e61
+0,         29,         29,        1,   460800, 355b17c2feb6b809c95bb71b333a670d
+0,         30,         30,        1,   460800, 063643ba941293ba95e024da202267cb
+0,         31,         31,        1,   460800, 8b31727d492fa9b25e025a1f45425b16
+0,         32,         32,        1,   460800, 45c5901c24d2ae2304b3e82c075a96bf
+0,         33,         33,        1,   460800, b7d4449d0e2157093727cb0f00648751
+0,         34,         34,        1,   460800, 167642e702f645853c974531853987f8
+0,         35,         35,        1,   460800, 2eb4596d675f099bab6c3b40ce30fd88
+0,         36,         36,        1,   460800, 8dd1aec35b92610cb22bedd3c54cb26a
+0,         37,         37,        1,   460800, 8eacf32e58d9a731467aba0f61d9e60f
+0,         38,         38,        1,   460800, 6a735f86d18ebe265894f633071a25d7
+0,         39,         39,        1,   460800, 843b0c938845b72e1c23bc39f7479cba
+0,         40,         40,        1,   460800, ca2099b43141cb9131505ab40ac3959f
+0,         41,         41,        1,   460800, e65322e1929def11f9985683365ab6bf
+0,         42,         42,        1,   460800, 565410a8c2f4b50a192f9590e6ab32c0
+0,         43,         43,        1,   460800, fa9a8ac625854cc279a07766ddad6e6f
+0,         44,         44,        1,   460800, a46ac62886c48edef3dc58de34a2a004
+0,         45,         45,        1,   460800, 414e01b6c24e71efc9c58f65dc0f4aca
+0,         46,         46,        1,   460800, e0501b903f21b490da049e51e7a02bae
+0,         47,         47,        1,   460800, 48b30eec1e9d862ee54b136045e1d90f
diff --git a/tests/ref/fate/mov-elist-starts-ctts-2ndsample b/tests/ref/fate/mov-elist-starts-ctts-2ndsample
new file mode 100644
index 0000000..1287a40
--- /dev/null
+++ b/tests/ref/fate/mov-elist-starts-ctts-2ndsample
@@ -0,0 +1,57 @@ 
+#format: frame checksums
+#version: 2
+#hash: MD5
+#tb 0: 1/24
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 640x480
+#sar 0: 0/1
+#stream#, dts,        pts, duration,     size, hash
+0,          0,          0,        1,   460800, e2ec4074e83dd4f9188915b6b08aa3a2
+0,          1,          1,        1,   460800, 9ed1ba935bc22ef03e6f8fd5b0b37ee6
+0,          2,          2,        1,   460800, 3f1c536514750de86571122046b5858f
+0,          3,          3,        1,   460800, 4f7943cb6f7966d19d344081b0db0d71
+0,          4,          4,        1,   460800, 0661f34eb45398f8cd158b5a1637bd96
+0,          5,          5,        1,   460800, 177620fa17c4d6fddad1d31c1605e46e
+0,          6,          6,        1,   460800, 8e22cde58a50e0279be01c23dfd7c032
+0,          7,          7,        1,   460800, 8c74c4d8ceee929fded82eeb7a0a7c29
+0,          8,          8,        1,   460800, a50d00a8868f0722be55fa5953bc6ebf
+0,          9,          9,        1,   460800, f791233c8904da4e267bf7bcf5d6201e
+0,         10,         10,        1,   460800, 4ff703ef573eb8e88639d3c700645bf8
+0,         11,         11,        1,   460800, fd4c98487779aa7783e9fb3e874f9c8b
+0,         12,         12,        1,   460800, e11fbc6c36ad086ea6e611ddd28b211c
+0,         13,         13,        1,   460800, a63b8af666ee30a243cf9ea0d49834b5
+0,         14,         14,        1,   460800, 1cec6499bfaf054bf581efdab72f5799
+0,         15,         15,        1,   460800, 5cb8ea5a7158cac1112fc6453b2a577f
+0,         16,         16,        1,   460800, 2df256cb311f97f4648cdeee41ba20d1
+0,         17,         17,        1,   460800, afb2c133204a99fe434767340f50c2b9
+0,         18,         18,        1,   460800, 27c802932fa873af8663a6b8733391d7
+0,         19,         19,        1,   460800, c53872c43baf56d496811d2809ebcd9b
+0,         20,         20,        1,   460800, d3ca26ecb6bec6bfa508f07e2a66fa3a
+0,         21,         21,        1,   460800, 2d44e18ccf734fe0ed98a7ce1e361fe7
+0,         22,         22,        1,   460800, ac4078b5426e4664029923ccf6ea3377
+0,         23,         23,        1,   460800, 60d4460a8b97e58e72c12d0c7334b4e4
+0,         24,         24,        1,   460800, 95bceab68b4ecf5df261ff9d3743041a
+0,         25,         25,        1,   460800, 0b80ad5bf2afbfbe512b83af797afd84
+0,         26,         26,        1,   460800, fbc70468f9331a0538e8c09ec3ead20e
+0,         27,         27,        1,   460800, de0578b4a114235250b7e93e9f9bf6de
+0,         28,         28,        1,   460800, 72f50490650b718e394822f8873ad071
+0,         29,         29,        1,   460800, b26594051d313892823eef711a08dc00
+0,         30,         30,        1,   460800, 1122641658f6b433e82080e092fe6943
+0,         31,         31,        1,   460800, aae4ddc51bcbdf9428f68069f5881090
+0,         32,         32,        1,   460800, 018047addf7fd2ef4f1d231d69187bf5
+0,         33,         33,        1,   460800, bd03ace29c974b64e2a7a4cc815ec582
+0,         34,         34,        1,   460800, 7fddacb17f01d8facfb09df44ff8bdfd
+0,         35,         35,        1,   460800, e8d84d6b3406404900b8342183f6ada7
+0,         36,         36,        1,   460800, 5b24faed4fdd21bf9a1218658a113009
+0,         37,         37,        1,   460800, 8d82775c56b6b0ab31db0c522999b0a1
+0,         38,         38,        1,   460800, 282e5e03295c80b2a7b472b82c57483d
+0,         39,         39,        1,   460800, 0ad41f5975c2466fc3166ea20bde6842
+0,         40,         40,        1,   460800, 1439ad336ceafda0ad62355a7d0b6e50
+0,         41,         41,        1,   460800, d3a97471ad64ac2378591d4f6eadba1c
+0,         42,         42,        1,   460800, a40c32a1e589b103f639f2068b71bf02
+0,         43,         43,        1,   460800, a339b2bedc7ef46961f8502089abfb87
+0,         44,         44,        1,   460800, 2ccde43c94259682ea72188b08489e92
+0,         45,         45,        1,   460800, fc47cca1f029d44ec92d95853e9c46b4
+0,         46,         46,        1,   460800, 6c4d3b63dc1d4291ec88a4bb8c35aecd
+0,         47,         47,        1,   460800, 7a9be67aca439dd2a7ff17447b478974