summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>2015-03-16 20:08:35 +0000
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>2015-03-18 14:28:56 +0000
commit8692d74b7364b405d7939c0ed347e8a2815193a7 (patch)
tree2ff76c21f80b4d3304c5785268ca46e0378c9b26
parent58a840e21577a2168843487a98cb2cea44b5a94a (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.c42
-rw-r--r--libavformat/version.h2
3 files changed, 35 insertions, 10 deletions
diff --git a/libavformat/isom.h b/libavformat/isom.h
index c24b962ae5..d81d4358a2 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -155,6 +155,7 @@ typedef struct MOVContext {
unsigned trex_count;
int itunes_metadata; ///< metadata are itunes style
int chapter_track;
+ 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 45c843f53e..76ce9ee217 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3468,8 +3468,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;
@@ -3483,16 +3483,36 @@ 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++) {
- st = s->streams[i];
- if (stream_index == i)
- continue;
+ for (i = 0; i < s->nb_streams; i++) {
+ int64_t timestamp;
+ st = s->streams[i];
+ 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;
}
@@ -3500,6 +3520,10 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
#define OFFSET(x) offsetof(MOVContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption mov_options[] = {
+ {"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},
{ "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
{ "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
diff --git a/libavformat/version.h b/libavformat/version.h
index 9ceb6ee6fa..495302ab87 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 56
-#define LIBAVFORMAT_VERSION_MINOR 17
+#define LIBAVFORMAT_VERSION_MINOR 18
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \