[FFmpeg-devel] [PATCH] lavf/mov: Add support for edit list parsing.
Sasi Inguva
isasi at google.com
Sat Aug 6 03:18:40 EEST 2016
Signed-off-by: Sasi Inguva <isasi at 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
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
--
2.8.0.rc3.226.g39d4020
More information about the ffmpeg-devel
mailing list