Commit 31f9032b added the audio_preload feature; its goal is to interleave audio earlier than the rest. Unfortunately, it has never ever worked, because the check for whether a packet should be interleaved before or after another packet was completely wrong: When audio_preload vanishes, interleave_compare_dts returns 1 if the new packet should be interleaved earlier than the packet it is compared with and that is what the rest of the code expects. But the codepath used when audio_preload is set does the opposite.
Also fixes potential undefined behaviour (namely signed integer overflow). Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com> --- avformat.h contains the following note about audio_preload: "not all formats support this and unpredictable things may happen if it is used when not supported." Has this been added because of unpredictable results caused by the buggy check? This option seems to work fine as long as audio_preload is not in the range of max_interleave_duration. libavformat/mux.c | 22 ++++++++++++++-------- libavformat/version.h | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/libavformat/mux.c b/libavformat/mux.c index 83fe1de78f..5e1ecd8485 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1001,15 +1001,21 @@ static int interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVStream *st2 = s->streams[next->stream_index]; int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts, st->time_base); - if (s->audio_preload && ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))) { - int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO); - int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO); - if (ts == ts2) { - ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den - -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den; - ts2=0; + if (s->audio_preload) { + int preload = st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO; + int preload2 = st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO; + if (preload != preload2) { + preload *= s->audio_preload; + preload2 *= s->audio_preload; + int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - preload; + int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - preload2; + if (ts == ts2) { + ts = ((uint64_t)pkt ->dts*st ->time_base.num*AV_TIME_BASE - (uint64_t)preload *st ->time_base.den)*st2->time_base.den + - ((uint64_t)next->dts*st2->time_base.num*AV_TIME_BASE - (uint64_t)preload2*st2->time_base.den)*st ->time_base.den; + ts2 = 0; + } + comp = (ts2 > ts) - (ts2 < ts); } - comp= (ts>ts2) - (ts<ts2); } if (comp == 0) diff --git a/libavformat/version.h b/libavformat/version.h index 52dd95f5c6..39b00f62ab 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 #define LIBAVFORMAT_VERSION_MINOR 28 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.21.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".