PR #24903 opened by James Almer (jamrial) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24903 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24903.patch
It was set to a sub-frame value so the caller would then pass such small frames to the encoder, which would then get buffered internally before being processed. Because of this, the actual frame size would not end up being propagated back to the caller, which resulted in said bogus internal value being used by muxers. Set frame_size to the actual final value and adapt the encoder to expect full frames. Fixes issue #24899. >From 5dc8a1e1a440e8fd1564bcd6a5e3f0e6fa01d074 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Tue, 6 Oct 2026 11:28:55 -0300 Subject: [PATCH] avcodec/vorbisenc: fix setting frame_size It was set to a sub-frame value so the caller would then pass such small frames to the encoder, which would then get buffered internally before being processed. Because of this, the actual frame size would not end up being propagated back to the caller, which resulted in said bogus internal value being used by muxers. Set frame_size to the actual final value and adapt the encoder to expect full frames. Fixes issue #24899. Signed-off-by: James Almer <[email protected]> --- libavcodec/vorbisenc.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 7e72c19c5d..c2f2685733 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -107,6 +107,7 @@ typedef struct vorbis_enc_mode { typedef struct vorbis_enc_context { int channels; int sample_rate; + int frame_size; int log2_blocksize[2]; AVTXContext *mdct[2]; av_tx_fn mdct_fn[2]; @@ -1038,6 +1039,7 @@ static int apply_window_and_mdct(vorbis_enc_context *venc) /* Used for padding the last encoded packet */ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) { + vorbis_enc_context *venc = avctx->priv_data; AVFrame *f = av_frame_alloc(); int ch; @@ -1045,7 +1047,7 @@ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) return NULL; f->format = avctx->sample_fmt; - f->nb_samples = avctx->frame_size; + f->nb_samples = venc->frame_size; f->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; f->ch_layout.nb_channels = channels; @@ -1062,11 +1064,10 @@ static AVFrame *spawn_empty_frame(AVCodecContext *avctx, int channels) } /* Set up audio samples for psy analysis and window/mdct */ -static void move_audio(vorbis_enc_context *venc, int sf_size) +static void move_audio(vorbis_enc_context *venc) { AVFrame *cur = NULL; int frame_size = 1 << (venc->log2_blocksize[1] - 1); - int subframes = frame_size / sf_size; int sf, ch; /* Copy samples from last frame into current frame */ @@ -1078,7 +1079,7 @@ static void move_audio(vorbis_enc_context *venc, int sf_size) for (ch = 0; ch < venc->channels; ch++) memset(venc->samples + 2 * ch * frame_size, 0, sizeof(float) * frame_size); - for (sf = 0; sf < subframes; sf++) { + cur = ff_bufqueue_get(&venc->bufqueue); for (ch = 0; ch < venc->channels; ch++) { @@ -1087,11 +1088,11 @@ static void move_audio(vorbis_enc_context *venc, int sf_size) const float *input = (float *) cur->extended_data[ch]; const size_t len = cur->nb_samples * sizeof(float); - memcpy(offset + sf*sf_size, input, len); - memcpy(save + sf*sf_size, input, len); // Move samples for next frame + memcpy(offset, input, len); + memcpy(save, input, len); // Move samples for next frame } av_frame_free(&cur); - } + venc->have_saved = 1; memcpy(venc->scratch, venc->samples, 2 * venc->channels * frame_size); } @@ -1100,7 +1101,7 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { vorbis_enc_context *venc = avctx->priv_data; - int i, ret, need_more; + int i, ret; int frame_size = 1 << (venc->log2_blocksize[1] - 1); vorbis_enc_mode *mode; vorbis_enc_mapping *mapping; @@ -1118,15 +1119,10 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (!venc->afq.remaining_samples) return 0; - need_more = venc->bufqueue.available * avctx->frame_size < frame_size; - need_more = frame && need_more; - if (need_more) - return 0; - /* Pad the bufqueue with empty frames for encoding the last packet. */ if (!frame) { - if (venc->bufqueue.available * avctx->frame_size < frame_size) { - int frames_needed = (frame_size/avctx->frame_size) - venc->bufqueue.available; + if (venc->bufqueue.available * venc->frame_size < frame_size) { + int frames_needed = (frame_size/venc->frame_size) - venc->bufqueue.available; int i; for (i = 0; i < frames_needed; i++) { @@ -1139,7 +1135,7 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } } - move_audio(venc, avctx->frame_size); + move_audio(venc); if (!apply_window_and_mdct(venc)) return 0; @@ -1297,7 +1293,8 @@ static av_cold int vorbis_encode_init(AVCodecContext *avctx) return ret; avctx->extradata_size = ret; - avctx->frame_size = 64; + venc->frame_size = 64; + avctx->frame_size = 1 << (venc->log2_blocksize[1] - 1); avctx->initial_padding = 1 << (venc->log2_blocksize[1] - 1); ff_af_queue_init(avctx, &venc->afq); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
