PR #25694 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25694 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25694.patch
>From 900ccad16d2f86975094f27d2d99b78ea83fc228 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Fri, 30 Oct 2026 19:31:36 +0100 Subject: [PATCH 1/7] avcodec/pcm-dvdenc: do not encode a frame with fewer samples than a block 24 bit samples are stored in blocks of samples_per_block samples and the sample count of a frame is rounded down to whole blocks. A last frame with fewer samples than a block gives zero blocks, the do/while loops still run and read past the frame until the block count wraps. Return no packet for such a frame. Fixes: out of array read Fixes: ZplUzGvg2XP9 Fixes: AISLE-2026-0150-00112 Out of array read Replicated through UnModified FFmpeg with ASAN Found-by: Joshua Rogers (AISLE) --- libavcodec/pcm-dvdenc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c index 4904eea4ca5..dc5224cc24c 100644 --- a/libavcodec/pcm-dvdenc.c +++ b/libavcodec/pcm-dvdenc.c @@ -123,6 +123,9 @@ static int pcm_dvd_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, PutByteContext pb; int ret; + if (!blocks) + return 0; + if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0) return ret; -- 2.54.0 >From a4530271fdee4e9bc065088f862e3d6174adabd4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:49:47 +0100 Subject: [PATCH 2/7] avcodec/ttaenc: check the packet space for each sample and the CRC Fixes: Assertion failure Fixes: bAfKKmQm4ZDe Fixes: AISLE-2026-0150-00078 Assertion failure Replicated through UnModified FFmpeg Found-by: Joshua Rogers (AISLE) --- libavcodec/ttaenc.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/libavcodec/ttaenc.c b/libavcodec/ttaenc.c index 46751ff3ca6..24f85cade88 100644 --- a/libavcodec/ttaenc.c +++ b/libavcodec/ttaenc.c @@ -90,7 +90,7 @@ static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, TTAEncContext *s = avctx->priv_data; PutBitContext pb; int ret, i, out_bytes, cur_chan, res, samples; - int64_t pkt_size = frame->nb_samples * 2LL * avctx->ch_layout.nb_channels * s->bps; + int64_t pkt_size = frame->nb_samples * 2LL * avctx->ch_layout.nb_channels * s->bps + 4; pkt_alloc: cur_chan = 0, res = 0, samples = 0; @@ -109,7 +109,7 @@ pkt_alloc: TTAChannel *c = &s->ch_ctx[cur_chan]; TTAFilter *filter = &c->filter; TTARice *rice = &c->rice; - uint32_t k, unary, outval; + uint32_t k, unary = 0, outval; int32_t value, temp; value = get_sample(frame, samples++, avctx->sample_fmt); @@ -153,23 +153,24 @@ pkt_alloc: rice->k1++; unary = 1 + (outval >> k); - if (unary + 100LL > put_bits_left(&pb)) { - if (pkt_size < INT_MAX/2) { - pkt_size *= 2; - av_packet_unref(avpkt); - goto pkt_alloc; - } else - return AVERROR(ENOMEM); + } + + if (unary + 1LL + k + 32 > put_bits_left(&pb)) { + if (pkt_size < INT_MAX/2) { + pkt_size *= 2; + av_packet_unref(avpkt); + goto pkt_alloc; + } else + return AVERROR(ENOMEM); + } + while (unary) { + if (unary > 31) { + put_bits(&pb, 31, 0x7FFFFFFF); + unary -= 31; + } else { + put_bits(&pb, unary, (1U << unary) - 1); + unary = 0; } - do { - if (unary > 31) { - put_bits(&pb, 31, 0x7FFFFFFF); - unary -= 31; - } else { - put_bits(&pb, unary, (1U << unary) - 1); - unary = 0; - } - } while (unary); } put_bits(&pb, 1, 0); -- 2.54.0 >From cfb4b77946b8745209fb4439125f5090743fde3a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:49:47 +0100 Subject: [PATCH 3/7] avcodec/roqaudioenc: encode the buffered samples when flushed early Encode the buffered samples once and return no packet when the buffer is empty. Fixes: use of uninitialized memory Fixes: X43TLCpjYK88 Fixes: AISLE-2026-0150-00397 Use of uninitialized memory Replicated through UnModified FFmpeg with Valgrind Found-by: Joshua Rogers (AISLE) The fix was suggested in the report. --- libavcodec/roqaudioenc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index 8a626c0d29f..c0e9967ab44 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -131,7 +131,7 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, stereo = (channels == 2); - if (!in && context->input_frames >= 8) + if (!in && (context->input_frames >= 8 || !context->buffered_samples)) return 0; if (in && context->input_frames < 8) { @@ -153,7 +153,7 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, context->lastSample[1] &= 0xFF00; } - if (context->input_frames == 7) + if (context->input_frames < 8) data_size = channels * context->buffered_samples; else data_size = channels * avctx->frame_size; @@ -181,7 +181,7 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, avpkt->duration = data_size / channels; context->input_frames++; - if (!in) + if (!frame) context->input_frames = FFMAX(context->input_frames, 8); *got_packet_ptr = 1; -- 2.54.0 >From 15860d084159cd829f1083469649c2f0d3c462c2 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:49:47 +0100 Subject: [PATCH 4/7] avcodec/adpcmenc: encode all samples of a mono ADPCM_MS block with trellis Fixes: use of uninitialized memory Fixes: 98u4sU59NEf4 Fixes: AISLE-2026-0150-00113 Use of uninitialized memory Replicated through UnModified FFmpeg with Valgrind Found-by: Joshua Rogers (AISLE) --- libavcodec/adpcmenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index cd6b330554f..fd8ce9e3670 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -782,9 +782,9 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (!buf) return AVERROR(ENOMEM); if (channels == 1) { - adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, + adpcm_compress_trellis(avctx, samples, buf, &c->status[0], 2 * n, channels); - for (int i = 0; i < n; i += 2) + for (int i = 0; i < 2 * n; i += 2) *dst++ = (buf[i] << 4) | buf[i + 1]; } else { adpcm_compress_trellis(avctx, samples, buf, -- 2.54.0 >From 2e353eb0d5ada3d8225ef2b5b12f719439fbafe8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:49:47 +0100 Subject: [PATCH 5/7] avcodec/wavpackenc: compute the default block size in 64 bit Fixes: signed integer overflow Fixes: infinite loop Fixes: dVqGncTUAyg9 Fixes: AISLE-2026-0150-00591 Signed integer overflow and infinite loop Replicated through API with UBSAN Found-by: Joshua Rogers (AISLE) --- libavcodec/wavpackenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c index 17372b74a5f..e1d77b830d1 100644 --- a/libavcodec/wavpackenc.c +++ b/libavcodec/wavpackenc.c @@ -144,10 +144,10 @@ static av_cold int wavpack_encode_init(AVCodecContext *avctx) else block_samples = avctx->sample_rate; - while (block_samples * avctx->ch_layout.nb_channels > WV_MAX_SAMPLES) + while (block_samples * (int64_t)avctx->ch_layout.nb_channels > WV_MAX_SAMPLES) block_samples /= 2; - while (block_samples * avctx->ch_layout.nb_channels < 40000) + while (block_samples * (int64_t)avctx->ch_layout.nb_channels < 40000) block_samples *= 2; avctx->frame_size = block_samples; } else if (avctx->frame_size && (avctx->frame_size < 128 || -- 2.54.0 >From 1129855549e2f6571e17134cecca350ae9ffed37 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:49:47 +0100 Subject: [PATCH 6/7] avcodec/vorbis_parser: parse the extradata only once Fixes: Timeout Fixes: nsq7AyzgMo4U Fixes: AISLE-2026-0150-00507 Timeout Replicated through UnModified FFmpeg Found-by: Joshua Rogers (AISLE) --- libavcodec/vorbis_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c index 8070004e61a..9102ae0bce6 100644 --- a/libavcodec/vorbis_parser.c +++ b/libavcodec/vorbis_parser.c @@ -309,7 +309,7 @@ static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx, AVVorbisParseContext *s = s1->priv_data; int duration; - if (!s->valid_extradata && avctx->extradata && avctx->extradata_size) { + if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size) { ff_vorbis_parse_init(s, avctx->extradata, avctx->extradata_size); } if (!s->valid_extradata) -- 2.54.0 >From d71109664f700c2347c394860d98eacb0fbba5b7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 2 Nov 2026 18:59:21 +0100 Subject: [PATCH 7/7] avcodec/pcm-dvdenc: pad the last frame to a whole block 24 bit samples are stored in blocks of samples_per_block samples and the samples of an incomplete last block were dropped. Let the generic code pad the last frame to a whole block with silence, it signals the padding with skip samples side data so a container can mark the end. --- libavcodec/pcm-dvdenc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c index dc5224cc24c..9d4d0c9e986 100644 --- a/libavcodec/pcm-dvdenc.c +++ b/libavcodec/pcm-dvdenc.c @@ -25,6 +25,7 @@ #include "bytestream.h" #include "codec_internal.h" #include "encode.h" +#include "internal.h" typedef struct PCMDVDContext { uint8_t header[3]; // Header added to every frame @@ -107,6 +108,7 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx) s->header[2] = 0x80; avctx->frame_size = frame_size; + avctx->internal->pad_samples = s->samples_per_block; return 0; } @@ -179,8 +181,7 @@ const FFCodec ff_pcm_dvd_encoder = { CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for DVD-Video media"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_PCM_DVD, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PCMDVDContext), .init = pcm_dvd_encode_init, FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame), -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
