Message ID | tencent_7AE552D30A484053E5D379F5D2C90CEEA805@qq.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v3] avformat/mov: add interleaved_read option | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Zhao Zhili <quinkblack@foxmail.com> 于2023年9月12日周二 01:10写道: > > From: Zhao Zhili <zhilizhao@tencent.com> > > For bad interleaved files, manually interleave multiple tracks at the > demuxer level can trigger seeking back and forth, which can be > dramatically slow depending on the protocol. Demuxer level interleave > can be useless sometimes, e.g., reading mp4 via http and then > transcoding/remux to DASH. Disable this option when you don't need the > demuxer level interleave, and want to avoid the IO penalizes. > > Co-authored-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> > Signed-off-by: Zhao Zhili <zhilizhao@tencent.com> > --- > v3: update doc > v2: rename option > > This issue is well known. Two samples can be found at here > http://ffmpeg.org/pipermail/ffmpeg-devel/2022-December/304951.html > > doc/demuxers.texi | 7 +++++++ > libavformat/isom.h | 1 + > libavformat/mov.c | 5 ++++- > libavformat/version.h | 2 +- > 4 files changed, 13 insertions(+), 2 deletions(-) > > diff --git a/doc/demuxers.texi b/doc/demuxers.texi > index 2d33b47a56..ca1563abb0 100644 > --- a/doc/demuxers.texi > +++ b/doc/demuxers.texi > @@ -779,6 +779,13 @@ cast to int32 are used to adjust onward dts. > > Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto > a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range. > + > +@item interleaved_read > +Interleave packets from multiple tracks at demuxer level. For badly interleaved files, this prevents playback issues > +caused by large gaps between packets in different tracks, as MOV/MP4 do not have packet placement requirements. > +However, this can cause excessive seeking on very badly interleaved files, due to seeking between tracks, so disabling > +it may prevent I/O issues, at the expense of playback. > + > @end table > > @subsection Audible AAX > diff --git a/libavformat/isom.h b/libavformat/isom.h > index 4b1cd42f0f..3d375d7a46 100644 > --- a/libavformat/isom.h > +++ b/libavformat/isom.h > @@ -327,6 +327,7 @@ typedef struct MOVContext { > int64_t extent_offset; > } *avif_info; > int avif_info_size; > + int interleaved_read; > } MOVContext; > > int ff_mp4_read_descr_len(AVIOContext *pb); > diff --git a/libavformat/mov.c b/libavformat/mov.c > index aa1d9e4ccc..8ad5f0b646 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -8780,6 +8780,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) > AVIndexEntry *sample = NULL; > int64_t best_dts = INT64_MAX; > int i; > + MOVContext *mov = s->priv_data; > + int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL); > for (i = 0; i < s->nb_streams; i++) { > AVStream *avst = s->streams[i]; > FFStream *const avsti = ffstream(avst); > @@ -8788,7 +8790,7 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) > AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample]; > int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); > av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); > - if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || > + if (!sample || (no_interleave && current_sample->pos < sample->pos) || > ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && > ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE && > ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || > @@ -9282,6 +9284,7 @@ static const AVOption mov_options[] = { > { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL, > {.i64 = 0}, 0, 1, FLAGS }, > { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM }, > + { "interleaved_read", "Manually interleave between multiple tracks", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM }, > > { NULL }, > }; > diff --git a/libavformat/version.h b/libavformat/version.h > index cb67e0a1f8..e41362ac9d 100644 > --- a/libavformat/version.h > +++ b/libavformat/version.h > @@ -32,7 +32,7 @@ > #include "version_major.h" > > #define LIBAVFORMAT_VERSION_MINOR 12 > -#define LIBAVFORMAT_VERSION_MICRO 100 > +#define LIBAVFORMAT_VERSION_MICRO 101 > > #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ > LIBAVFORMAT_VERSION_MINOR, \ > -- > 2.34.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". lgtm Thanks Steven
> On Sep 14, 2023, at 09:41, Steven Liu <lingjiujianke@gmail.com> wrote: > > Zhao Zhili <quinkblack@foxmail.com> 于2023年9月12日周二 01:10写道: >> >> From: Zhao Zhili <zhilizhao@tencent.com> >> >> For bad interleaved files, manually interleave multiple tracks at the >> demuxer level can trigger seeking back and forth, which can be >> dramatically slow depending on the protocol. Demuxer level interleave >> can be useless sometimes, e.g., reading mp4 via http and then >> transcoding/remux to DASH. Disable this option when you don't need the >> demuxer level interleave, and want to avoid the IO penalizes. >> >> Co-authored-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> >> Signed-off-by: Zhao Zhili <zhilizhao@tencent.com> >> --- >> v3: update doc >> v2: rename option >> >> This issue is well known. Two samples can be found at here >> http://ffmpeg.org/pipermail/ffmpeg-devel/2022-December/304951.html >> >> doc/demuxers.texi | 7 +++++++ >> libavformat/isom.h | 1 + >> libavformat/mov.c | 5 ++++- >> libavformat/version.h | 2 +- >> 4 files changed, 13 insertions(+), 2 deletions(-) >> >> diff --git a/doc/demuxers.texi b/doc/demuxers.texi >> index 2d33b47a56..ca1563abb0 100644 >> --- a/doc/demuxers.texi >> +++ b/doc/demuxers.texi >> @@ -779,6 +779,13 @@ cast to int32 are used to adjust onward dts. >> >> Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto >> a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range. >> + >> +@item interleaved_read >> +Interleave packets from multiple tracks at demuxer level. For badly interleaved files, this prevents playback issues >> +caused by large gaps between packets in different tracks, as MOV/MP4 do not have packet placement requirements. >> +However, this can cause excessive seeking on very badly interleaved files, due to seeking between tracks, so disabling >> +it may prevent I/O issues, at the expense of playback. >> + >> @end table >> >> @subsection Audible AAX >> diff --git a/libavformat/isom.h b/libavformat/isom.h >> index 4b1cd42f0f..3d375d7a46 100644 >> --- a/libavformat/isom.h >> +++ b/libavformat/isom.h >> @@ -327,6 +327,7 @@ typedef struct MOVContext { >> int64_t extent_offset; >> } *avif_info; >> int avif_info_size; >> + int interleaved_read; >> } MOVContext; >> >> int ff_mp4_read_descr_len(AVIOContext *pb); >> diff --git a/libavformat/mov.c b/libavformat/mov.c >> index aa1d9e4ccc..8ad5f0b646 100644 >> --- a/libavformat/mov.c >> +++ b/libavformat/mov.c >> @@ -8780,6 +8780,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) >> AVIndexEntry *sample = NULL; >> int64_t best_dts = INT64_MAX; >> int i; >> + MOVContext *mov = s->priv_data; >> + int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL); >> for (i = 0; i < s->nb_streams; i++) { >> AVStream *avst = s->streams[i]; >> FFStream *const avsti = ffstream(avst); >> @@ -8788,7 +8790,7 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) >> AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample]; >> int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); >> av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); >> - if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || >> + if (!sample || (no_interleave && current_sample->pos < sample->pos) || >> ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && >> ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE && >> ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || >> @@ -9282,6 +9284,7 @@ static const AVOption mov_options[] = { >> { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL, >> {.i64 = 0}, 0, 1, FLAGS }, >> { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM }, >> + { "interleaved_read", "Manually interleave between multiple tracks", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM }, >> >> { NULL }, >> }; >> diff --git a/libavformat/version.h b/libavformat/version.h >> index cb67e0a1f8..e41362ac9d 100644 >> --- a/libavformat/version.h >> +++ b/libavformat/version.h >> @@ -32,7 +32,7 @@ >> #include "version_major.h" >> >> #define LIBAVFORMAT_VERSION_MINOR 12 >> -#define LIBAVFORMAT_VERSION_MICRO 100 >> +#define LIBAVFORMAT_VERSION_MICRO 101 >> >> #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ >> LIBAVFORMAT_VERSION_MINOR, \ >> -- >> 2.34.1 >> >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > > lgtm Pushed with a little modification on the option description. Thanks! > > Thanks > Steven > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 2d33b47a56..ca1563abb0 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -779,6 +779,13 @@ cast to int32 are used to adjust onward dts. Unit is the track time scale. Range is 0 to UINT_MAX. Default is @code{UINT_MAX - 48000*10} which allows upto a 10 second dts correction for 48 kHz audio streams while accommodating 99.9% of @code{uint32} range. + +@item interleaved_read +Interleave packets from multiple tracks at demuxer level. For badly interleaved files, this prevents playback issues +caused by large gaps between packets in different tracks, as MOV/MP4 do not have packet placement requirements. +However, this can cause excessive seeking on very badly interleaved files, due to seeking between tracks, so disabling +it may prevent I/O issues, at the expense of playback. + @end table @subsection Audible AAX diff --git a/libavformat/isom.h b/libavformat/isom.h index 4b1cd42f0f..3d375d7a46 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -327,6 +327,7 @@ typedef struct MOVContext { int64_t extent_offset; } *avif_info; int avif_info_size; + int interleaved_read; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index aa1d9e4ccc..8ad5f0b646 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -8780,6 +8780,8 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) AVIndexEntry *sample = NULL; int64_t best_dts = INT64_MAX; int i; + MOVContext *mov = s->priv_data; + int no_interleave = !mov->interleaved_read || !(s->pb->seekable & AVIO_SEEKABLE_NORMAL); for (i = 0; i < s->nb_streams; i++) { AVStream *avst = s->streams[i]; FFStream *const avsti = ffstream(avst); @@ -8788,7 +8790,7 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample]; int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); - if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || + if (!sample || (no_interleave && current_sample->pos < sample->pos) || ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE && ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || @@ -9282,6 +9284,7 @@ static const AVOption mov_options[] = { { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, { "max_stts_delta", "treat offsets above this value as invalid", OFFSET(max_stts_delta), AV_OPT_TYPE_INT, {.i64 = UINT_MAX-48000*10 }, 0, UINT_MAX, .flags = AV_OPT_FLAG_DECODING_PARAM }, + { "interleaved_read", "Manually interleave between multiple tracks", OFFSET(interleaved_read), AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, .flags = AV_OPT_FLAG_DECODING_PARAM }, { NULL }, }; diff --git a/libavformat/version.h b/libavformat/version.h index cb67e0a1f8..e41362ac9d 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 12 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \