Skip to content

Commit

Permalink
lavf/mov.c: Use the correct offset to shift timestamp when seeking.
Browse files Browse the repository at this point in the history
Fixes seek for files with empty edits and files with negative ctts
(dts_shift > 0). Added fate samples and tests.

Signed-off-by: Sasi Inguva <[email protected]>
Signed-off-by: Michael Niedermayer <[email protected]>
  • Loading branch information
Sasi Inguva authored and michaelni committed Mar 10, 2018
1 parent b6fc09c commit 43205df
Show file tree
Hide file tree
Showing 6 changed files with 401 additions and 11 deletions.
1 change: 1 addition & 0 deletions libavformat/isom.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ typedef struct MOVStreamContext {
int *keyframes;
int time_scale;
int64_t time_offset; ///< time offset of the edit list entries
int64_t min_corrected_pts; ///< minimum Composition time shown by the edits excluding empty edits.
int current_sample;
int64_t current_index;
MOVIndexRange* index_ranges;
Expand Down
27 changes: 16 additions & 11 deletions libavformat/mov.c
Original file line number Diff line number Diff line change
Expand Up @@ -3378,7 +3378,6 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
int64_t edit_list_start_ctts_sample = 0;
int64_t curr_cts;
int64_t curr_ctts = 0;
int64_t min_corrected_pts = -1;
int64_t empty_edits_sum_duration = 0;
int64_t edit_list_index = 0;
int64_t index;
Expand Down Expand Up @@ -3419,6 +3418,9 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
msc->ctts_sample = 0;
msc->ctts_allocated_size = 0;

// Reinitialize min_corrected_pts so that it can be computed again.
msc->min_corrected_pts = -1;

// 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) {
Expand Down Expand Up @@ -3563,10 +3565,10 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
}
}
} else {
if (min_corrected_pts < 0) {
min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
if (msc->min_corrected_pts < 0) {
msc->min_corrected_pts = edit_list_dts_counter + curr_ctts + msc->dts_shift;
} else {
min_corrected_pts = FFMIN(min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
msc->min_corrected_pts = FFMIN(msc->min_corrected_pts, edit_list_dts_counter + curr_ctts + msc->dts_shift);
}
if (edit_list_start_encountered == 0) {
edit_list_start_encountered = 1;
Expand Down Expand Up @@ -3625,16 +3627,16 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
}
}
}
// If there are empty edits, then min_corrected_pts might be positive intentionally. So we subtract the
// sum duration of emtpy edits here.
min_corrected_pts -= empty_edits_sum_duration;
// If there are empty edits, then msc->min_corrected_pts might be positive
// intentionally. So we subtract the sum duration of emtpy edits here.
msc->min_corrected_pts -= empty_edits_sum_duration;

// If the minimum pts turns out to be greater than zero after fixing the index, then we subtract the
// dts by that amount to make the first pts zero.
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && min_corrected_pts > 0) {
av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", min_corrected_pts);
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && msc->min_corrected_pts > 0) {
av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts);
for (i = 0; i < st->nb_index_entries; ++i) {
st->index_entries[i].timestamp -= min_corrected_pts;
st->index_entries[i].timestamp -= msc->min_corrected_pts;
}
}

Expand Down Expand Up @@ -3697,6 +3699,7 @@ 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;
sc->min_corrected_pts = start_time;
if (!mov->advanced_editlist)
current_dts = -sc->time_offset;
}
Expand Down Expand Up @@ -7158,7 +7161,9 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
int sample, time_sample, ret;
unsigned int i;

timestamp -= sc->time_offset;
// Here we consider timestamp to be PTS, hence try to offset it so that we
// can search over the DTS timeline.
timestamp -= (sc->min_corrected_pts + sc->dts_shift);

ret = mov_seek_fragment(s, st, timestamp);
if (ret < 0)
Expand Down
6 changes: 6 additions & 0 deletions tests/fate/seek.mak
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,15 @@ FATE_SEEK_EXTRA-$(CONFIG_MP3_DEMUXER) += fate-seek-extra-mp3
FATE_SEEK_EXTRA-$(call ALLYES, CACHE_PROTOCOL PIPE_PROTOCOL MP3_DEMUXER) += fate-seek-cache-pipe
FATE_SEEK_EXTRA-$(CONFIG_MATROSKA_DEMUXER) += fate-seek-mkv-codec-delay
FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-extra-mp4
FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-empty-edit-mp4
FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-test-iibbibb-mp4
FATE_SEEK_EXTRA-$(CONFIG_MOV_DEMUXER) += fate-seek-test-iibbibb-neg-ctts-mp4

fate-seek-extra-mp3: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/gapless/gapless.mp3 -fastseek 1
fate-seek-extra-mp4: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/buck480p30_na.mp4 -duration 180 -frames 4
fate-seek-empty-edit-mp4: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/empty_edit_5s.mp4 -duration 15 -frames 4
fate-seek-test-iibbibb-mp4: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/test_iibbibb.mp4 -duration 13 -frames 4
fate-seek-test-iibbibb-neg-ctts-mp4: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mov/test_iibbibb_neg_ctts.mp4 -duration 13 -frames 4
fate-seek-cache-pipe: CMD = cat $(TARGET_SAMPLES)/gapless/gapless.mp3 | run libavformat/tests/seek$(EXESUF) cache:pipe:0 -read_ahead_limit -1
fate-seek-mkv-codec-delay: CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_SAMPLES)/mkv/codec_delay_opus.mkv

Expand Down
134 changes: 134 additions & 0 deletions tests/ref/seek/empty-edit-mp4
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:0 ts:-1.000000
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:1 ts: 11.894167
ret: 0 st: 0 flags:1 dts: 11.000000 pts: 11.000000 pos: 40515 size: 3214
ret: 0 st: 0 flags:0 dts: 11.100000 pts: 11.100000 pos: 43729 size: 581
ret: 0 st: 0 flags:0 dts: 11.200000 pts: 11.200000 pos: 44310 size: 432
ret: 0 st: 0 flags:0 dts: 11.300000 pts: 11.300000 pos: 44742 size: 380
ret: 0 st: 0 flags:0 ts: 9.788379
ret: 0 st: 0 flags:1 dts: 10.000000 pts: 10.000000 pos: 33523 size: 3221
ret: 0 st: 0 flags:0 dts: 10.100000 pts: 10.100000 pos: 36744 size: 575
ret: 0 st: 0 flags:0 dts: 10.200000 pts: 10.200000 pos: 37319 size: 438
ret: 0 st: 0 flags:0 dts: 10.300000 pts: 10.300000 pos: 37757 size: 449
ret: 0 st: 0 flags:1 ts: 7.682520
ret: 0 st: 0 flags:1 dts: 7.000000 pts: 7.000000 pos: 13643 size: 3234
ret: 0 st: 0 flags:0 dts: 7.100000 pts: 7.100000 pos: 16877 size: 585
ret: 0 st: 0 flags:0 dts: 7.200000 pts: 7.200000 pos: 17462 size: 442
ret: 0 st: 0 flags:0 dts: 7.300000 pts: 7.300000 pos: 17904 size: 371
ret: 0 st:-1 flags:0 ts: 5.576668
ret: 0 st: 0 flags:1 dts: 6.000000 pts: 6.000000 pos: 6953 size: 3166
ret: 0 st: 0 flags:0 dts: 6.100000 pts: 6.100000 pos: 10119 size: 599
ret: 0 st: 0 flags:0 dts: 6.200000 pts: 6.200000 pos: 10718 size: 418
ret: 0 st: 0 flags:0 dts: 6.300000 pts: 6.300000 pos: 11136 size: 354
ret: 0 st:-1 flags:1 ts: 3.470835
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st: 0 flags:0 ts: 1.365039
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st: 0 flags:1 ts:-0.740820
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:0 ts: 12.153336
ret: 0 st: 0 flags:1 dts: 13.000000 pts: 13.000000 pos: 54444 size: 3310
ret: 0 st: 0 flags:0 dts: 13.100000 pts: 13.100000 pos: 57754 size: 540
ret: 0 st: 0 flags:0 dts: 13.200000 pts: 13.200000 pos: 58294 size: 419
ret: 0 st: 0 flags:0 dts: 13.300000 pts: 13.300000 pos: 58713 size: 338
ret: 0 st:-1 flags:1 ts: 10.047503
ret: 0 st: 0 flags:1 dts: 10.000000 pts: 10.000000 pos: 33523 size: 3221
ret: 0 st: 0 flags:0 dts: 10.100000 pts: 10.100000 pos: 36744 size: 575
ret: 0 st: 0 flags:0 dts: 10.200000 pts: 10.200000 pos: 37319 size: 438
ret: 0 st: 0 flags:0 dts: 10.300000 pts: 10.300000 pos: 37757 size: 449
ret: 0 st: 0 flags:0 ts: 7.941699
ret: 0 st: 0 flags:1 dts: 8.000000 pts: 8.000000 pos: 20396 size: 3281
ret: 0 st: 0 flags:0 dts: 8.100000 pts: 8.100000 pos: 23677 size: 631
ret: 0 st: 0 flags:0 dts: 8.200000 pts: 8.200000 pos: 24308 size: 349
ret: 0 st: 0 flags:0 dts: 8.300000 pts: 8.300000 pos: 24657 size: 319
ret: 0 st: 0 flags:1 ts: 5.835840
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:0 ts: 3.730004
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:1 ts: 1.624171
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st: 0 flags:0 ts:-0.481641
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st: 0 flags:1 ts: 12.412500
ret: 0 st: 0 flags:1 dts: 12.000000 pts: 12.000000 pos: 47419 size: 3229
ret: 0 st: 0 flags:0 dts: 12.100000 pts: 12.100000 pos: 50648 size: 588
ret: 0 st: 0 flags:0 dts: 12.200000 pts: 12.200000 pos: 51236 size: 404
ret: 0 st: 0 flags:0 dts: 12.300000 pts: 12.300000 pos: 51640 size: 415
ret: 0 st:-1 flags:0 ts: 10.306672
ret: 0 st: 0 flags:1 dts: 11.000000 pts: 11.000000 pos: 40515 size: 3214
ret: 0 st: 0 flags:0 dts: 11.100000 pts: 11.100000 pos: 43729 size: 581
ret: 0 st: 0 flags:0 dts: 11.200000 pts: 11.200000 pos: 44310 size: 432
ret: 0 st: 0 flags:0 dts: 11.300000 pts: 11.300000 pos: 44742 size: 380
ret: 0 st:-1 flags:1 ts: 8.200839
ret: 0 st: 0 flags:1 dts: 8.000000 pts: 8.000000 pos: 20396 size: 3281
ret: 0 st: 0 flags:0 dts: 8.100000 pts: 8.100000 pos: 23677 size: 631
ret: 0 st: 0 flags:0 dts: 8.200000 pts: 8.200000 pos: 24308 size: 349
ret: 0 st: 0 flags:0 dts: 8.300000 pts: 8.300000 pos: 24657 size: 319
ret: 0 st: 0 flags:0 ts: 6.095020
ret: 0 st: 0 flags:1 dts: 7.000000 pts: 7.000000 pos: 13643 size: 3234
ret: 0 st: 0 flags:0 dts: 7.100000 pts: 7.100000 pos: 16877 size: 585
ret: 0 st: 0 flags:0 dts: 7.200000 pts: 7.200000 pos: 17462 size: 442
ret: 0 st: 0 flags:0 dts: 7.300000 pts: 7.300000 pos: 17904 size: 371
ret: 0 st: 0 flags:1 ts: 3.989160
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:0 ts: 1.883340
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st:-1 flags:1 ts:-0.222493
ret: 0 st: 0 flags:1 dts: 5.000000 pts: 5.000000 pos: 48 size: 2917
ret: 0 st: 0 flags:0 dts: 5.100000 pts: 5.100000 pos: 2965 size: 672
ret: 0 st: 0 flags:0 dts: 5.200000 pts: 5.200000 pos: 3637 size: 464
ret: 0 st: 0 flags:0 dts: 5.300000 pts: 5.300000 pos: 4101 size: 454
ret: 0 st: 0 flags:0 ts: 12.671680
ret: 0 st: 0 flags:1 dts: 13.000000 pts: 13.000000 pos: 54444 size: 3310
ret: 0 st: 0 flags:0 dts: 13.100000 pts: 13.100000 pos: 57754 size: 540
ret: 0 st: 0 flags:0 dts: 13.200000 pts: 13.200000 pos: 58294 size: 419
ret: 0 st: 0 flags:0 dts: 13.300000 pts: 13.300000 pos: 58713 size: 338
ret: 0 st: 0 flags:1 ts: 10.565820
ret: 0 st: 0 flags:1 dts: 10.000000 pts: 10.000000 pos: 33523 size: 3221
ret: 0 st: 0 flags:0 dts: 10.100000 pts: 10.100000 pos: 36744 size: 575
ret: 0 st: 0 flags:0 dts: 10.200000 pts: 10.200000 pos: 37319 size: 438
ret: 0 st: 0 flags:0 dts: 10.300000 pts: 10.300000 pos: 37757 size: 449
ret: 0 st:-1 flags:0 ts: 8.460008
ret: 0 st: 0 flags:1 dts: 9.000000 pts: 9.000000 pos: 27090 size: 3182
ret: 0 st: 0 flags:0 dts: 9.100000 pts: 9.100000 pos: 30272 size: 481
ret: 0 st: 0 flags:0 dts: 9.200000 pts: 9.200000 pos: 30753 size: 334
ret: 0 st: 0 flags:0 dts: 9.300000 pts: 9.300000 pos: 31087 size: 328
ret: 0 st:-1 flags:1 ts: 6.354175
ret: 0 st: 0 flags:1 dts: 6.000000 pts: 6.000000 pos: 6953 size: 3166
ret: 0 st: 0 flags:0 dts: 6.100000 pts: 6.100000 pos: 10119 size: 599
ret: 0 st: 0 flags:0 dts: 6.200000 pts: 6.200000 pos: 10718 size: 418
ret: 0 st: 0 flags:0 dts: 6.300000 pts: 6.300000 pos: 11136 size: 354
Loading

0 comments on commit 43205df

Please sign in to comment.