summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2015-03-17 14:19:31 +0000
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2015-03-18 14:30:07 +0000
commit414d6547f33175b3f53eb3320aa13161a584a151 (patch)
tree3ba0050e56d116866d6074df1b14943709f8a529
parentfbb9ef5b1727b9d133987617afad7a9f62781d9d (diff)
mov: Add option to keep exact packet sequence after seeking
The current behavior may produce a different sequence of packets after seeking, compared to demuxing linearly from the beginning. This is because the MOV demuxer seeks in each stream individually, based on timestamp, which may set each stream at a slightly different position than if the file would have been read sequentially. This makes implementing certain operations, such as segmenting, quite hard, and slower than need be. Therefore, add an option which retains the same packet sequence after seeking, as when a file is demuxed linearly.
-rw-r--r--libavformat/isom.h1
-rw-r--r--libavformat/mov.c46
-rw-r--r--libavformat/version.h4
3 files changed, 38 insertions, 13 deletions
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, \