diff --git a/libavformat/isom.h b/libavformat/isom.h index d233839dab..5d48989fd9 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -186,6 +186,7 @@ typedef struct MOVContext { int chapter_track; int use_absolute_path; int ignore_editlist; + int seek_individually; int64_t next_root_atom; ///< offset of the next root atom int export_all; int export_xmp; diff --git a/libavformat/mov.c b/libavformat/mov.c index 1170dd489d..09f2097a5a 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4325,8 +4325,8 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) { + MOVContext *mc = s->priv_data; AVStream *st; - int64_t seek_timestamp, timestamp; int sample; int i; @@ -4338,19 +4338,39 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if (sample < 0) return sample; - /* adjust seek timestamp to found sample timestamp */ - seek_timestamp = st->index_entries[sample].timestamp; + if (mc->seek_individually) { + /* adjust seek timestamp to found sample timestamp */ + int64_t seek_timestamp = st->index_entries[sample].timestamp; - for (i = 0; i < s->nb_streams; i++) { - MOVStreamContext *sc = s->streams[i]->priv_data; - st = s->streams[i]; - st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; + for (i = 0; i < s->nb_streams; i++) { + int64_t timestamp; + MOVStreamContext *sc = s->streams[i]->priv_data; + st = s->streams[i]; + st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; - if (stream_index == i) - continue; + if (stream_index == i) + continue; - timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); - mov_seek_stream(s, st, timestamp, flags); + timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); + mov_seek_stream(s, st, timestamp, flags); + } + } else { + for (i = 0; i < s->nb_streams; i++) { + MOVStreamContext *sc; + st = s->streams[i]; + sc = st->priv_data; + sc->current_sample = 0; + } + while (1) { + MOVStreamContext *sc; + AVIndexEntry *entry = mov_find_next_sample(s, &st); + if (!entry) + return AVERROR_INVALIDDATA; + sc = st->priv_data; + if (sc->ffindex == stream_index && sc->current_sample == sample) + break; + sc->current_sample++; + } } return 0; } @@ -4362,6 +4382,10 @@ static const AVOption mov_options[] = { "allow using absolute path when opening alias, this is a possible security issue", OFFSET(use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS}, + {"seek_streams_individually", + "Seek each stream individually to the to the closest point", + OFFSET(seek_individually), AV_OPT_TYPE_INT, { .i64 = 1 }, + 0, 1, FLAGS}, {"ignore_editlist", "", OFFSET(ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS}, {"use_mfra_for", diff --git a/libavformat/version.h b/libavformat/version.h index ba4c7c8e98..52ecfd07c4 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 56 -#define LIBAVFORMAT_VERSION_MINOR 25 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 26 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \