PR #22234 opened by Daniil Cherednik (dcherednik) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22234 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22234.patch
Commit c3aea7628c changes frame size. But the encoder and psy code expected frame size was 120 samples. >From 2eac3c5ce7a3ea956b8231a6246fcbfd781a4b27 Mon Sep 17 00:00:00 2001 From: Daniil Cherednik <[email protected]> Date: Fri, 20 Feb 2026 00:40:14 +0200 Subject: [PATCH] Fix regration after c3aea7628c Commit c3aea7628c changes frame size. But the encoder and psy code expected frame size was 120 samples. --- libavcodec/opus/enc.c | 7 +++++-- libavcodec/opus/enc_psy.c | 23 ++++++++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libavcodec/opus/enc.c b/libavcodec/opus/enc.c index 587e4ed69d..f1775bc653 100644 --- a/libavcodec/opus/enc.c +++ b/libavcodec/opus/enc.c @@ -130,9 +130,12 @@ static void celt_frame_setup_input(OpusEncContext *s, CeltFrame *f) for (int ch = 0; ch < f->channels; ch++) { CeltBlock *b = &f->block[ch]; - const void *input = cur->extended_data[ch]; + const char *input = cur->extended_data[ch]; size_t bps = av_get_bytes_per_sample(cur->format); - memcpy(b->overlap, input, bps*cur->nb_samples); + /* The MDCT overlap is always CELT_OVERLAP samples taken from the end of + * the previous frame, regardless of the encoder's frame_size. */ + memcpy(b->overlap, input+(cur->nb_samples - CELT_OVERLAP)*bps, + CELT_OVERLAP*bps); } av_frame_free(&cur); diff --git a/libavcodec/opus/enc_psy.c b/libavcodec/opus/enc_psy.c index 250cfb567a..08f1ec57c9 100644 --- a/libavcodec/opus/enc_psy.c +++ b/libavcodec/opus/enc_psy.c @@ -258,7 +258,8 @@ int ff_opus_psy_process(OpusPsyContext *s, OpusPacketInfo *p) void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) { int i, neighbouring_points = 0, start_offset = 0; - int radius = (1 << s->p.framesize), step_offset = radius*index; + int steps_per_frame = OPUS_BLOCK_SIZE(s->p.framesize) / s->avctx->frame_size; + int step_offset = steps_per_frame*index; int silence = 1; f->start_band = (s->p.mode == OPUS_MODE_HYBRID) ? 17 : 0; @@ -266,8 +267,8 @@ void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) f->channels = s->avctx->ch_layout.nb_channels; f->size = s->p.framesize; - for (i = 0; i < (1 << f->size); i++) - silence &= s->steps[index*(1 << f->size) + i]->silence; + for (i = 0; i < steps_per_frame; i++) + silence &= s->steps[index*steps_per_frame + i]->silence; f->silence = silence; if (f->silence) { @@ -282,8 +283,8 @@ void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index) } } - for (i = start_offset; i < FFMIN(radius, s->inflection_points_count - start_offset); i++) { - if (s->inflection_points[i] < (step_offset + radius)) { + for (i = start_offset; i < FFMIN(steps_per_frame, s->inflection_points_count - start_offset); i++) { + if (s->inflection_points[i] < (step_offset + steps_per_frame)) { neighbouring_points++; } } @@ -316,6 +317,7 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, { int i, f, ch; int frame_size = OPUS_BLOCK_SIZE(s->p.framesize); + int steps_per_frame = frame_size / s->avctx->frame_size; float rate, frame_bits = 0; /* Used for the global ROTATE flag */ @@ -329,7 +331,7 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start, for (i = 0; i < CELT_MAX_BANDS; i++) { float weight = 0.0f; float tonal_contrib = 0.0f; - for (f = 0; f < (1 << s->p.framesize); f++) { + for (f = 0; f < steps_per_frame; f++) { weight = start[f]->stereo[i]; for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) { weight += start[f]->change_amp[ch][i] + start[f]->tone[ch][i] + start[f]->energy[ch][i]; @@ -425,6 +427,7 @@ static void celt_search_for_intensity(OpusPsyContext *s, CeltFrame *f) static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame *f) { int i, j, k, cway, config[2][CELT_MAX_BANDS] = { { 0 } }; + int steps_per_frame = OPUS_BLOCK_SIZE(f->size) / s->avctx->frame_size; float score[2] = { 0 }; for (cway = 0; cway < 2; cway++) { @@ -439,7 +442,7 @@ static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame for (i = 0; i < CELT_MAX_BANDS; i++) { float iscore0 = 0.0f; float iscore1 = 0.0f; - for (j = 0; j < (1 << f->size); j++) { + for (j = 0; j < steps_per_frame; j++) { for (k = 0; k < s->avctx->ch_layout.nb_channels; k++) { iscore0 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[0]; iscore1 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[1]; @@ -480,7 +483,7 @@ int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index) void ff_opus_psy_postencode_update(OpusPsyContext *s, CeltFrame *f) { int i, frame_size = OPUS_BLOCK_SIZE(s->p.framesize); - int steps_out = s->p.frames*(frame_size/120); + int steps_out = s->p.frames*(frame_size/s->avctx->frame_size); void *tmp[FF_BUFQUEUE_SIZE]; float ideal_fbits; @@ -522,7 +525,9 @@ av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx, s->options = options; s->avctx = avctx; s->bufqueue = bufqueue; - s->max_steps = ceilf(s->options->max_delay_ms/2.5f); + s->max_steps = ceilf(s->options->max_delay_ms * avctx->sample_rate / + (1000.0f * avctx->frame_size)); + s->bsize_analysis = CELT_BLOCK_960; s->avg_is_band = CELT_MAX_BANDS - 1; s->inflection_points_count = 0; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
