diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2019-06-24 23:16:18 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2019-06-26 19:05:29 +0200 |
commit | 1889e3166cc5780780d7f40ac2271e5308f32b8e (patch) | |
tree | 8616c5e6ef5a66e858d484e4687f50b33826a495 /libavformat/mux.c | |
parent | bb11584924d6190a9028cbb319891028f44856a9 (diff) | |
download | ffmpeg-1889e3166cc5780780d7f40ac2271e5308f32b8e.tar.gz |
libavformat/mux: Fix audio_preload
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.rheinhardt@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r-- | libavformat/mux.c | 22 |
1 files changed, 14 insertions, 8 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) |