PR #20815 opened by Agent45
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20815
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20815.patch
- Fixes indexing errors in attack detection logic and introduces a state flag
(next_attack0_zero) to stabilize attack[0] prediction across frames. This
reduces vertical line artifacts in periodic signals such as trumpet.
- Changes PSY_LAME_NUM_SUBBLOCKS from 3 to 2 to ensure full coverage of all
1024 MDCT samples, with each subblock containing exactly 64 samples—matching
LAME’s empirical design. And adjust attack threshold presets. This improves the
handling of periodic signals, especially under low bitrate conditions.
- Disables PNS when the per-channel bitrate exceeds 64 kbps. This avoids
unnecessary noise substitution in high-bitrate scenarios where it may degrade
quality.
This resolves issue #20200.
From 458a942481151ede27478e6ac6d9d2866d438b84 Mon Sep 17 00:00:00 2001
From: Agent45
Date: Sat, 1 Nov 2025 19:49:05 +
Subject: [PATCH 1/2] avcodec/aacenc: add bitrate threshold for PNS
---
libavcodec/aaccoder.c | 9 +++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 7f1c4cdcc1..ddebdfd53d 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -58,6 +58,9 @@
* replace low energy non zero bands */
#define NOISE_LAMBDA_REPLACE 1.948f
+/* Bitrate threshold (in bits/sec/channel) above which PNS is disabled. */
+#define PNS_BITRATE_LIMIT 64000.0f
+
#include "libavcodec/aaccoder_trellis.h"
typedef float (*quantize_and_encode_band_func)(struct AACEncContext *s,
PutBitContext *pb,
@@ -513,6 +516,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext
*avctx, SingleChanne
? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
: (avctx->bit_rate / avctx->ch_layout.nb_channels);
+ int pns_at_low_bitrate = frame_bit_rate < PNS_BITRATE_LIMIT;
frame_bit_rate *= 1.15f;
if (avctx->cutoff > 0) {
@@ -536,7 +540,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext
*avctx, SingleChanne
const int start = wstart+sce->ics.swb_offset[g];
const float freq = (start-wstart)*freq_mult;
const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f);
-if (freq < NOISE_LOW_LIMIT || (start-wstart) >= cutoff) {
+if (!pns_at_low_bitrate || freq < NOISE_LOW_LIMIT ||
(start-wstart) >= cutoff) {
if (!sce->zeroes[w*16+g])
prev_sf = sce->sf_idx[w*16+g];
continue;
@@ -649,6 +653,7 @@ static void mark_pns(AACEncContext *s, AVCodecContext
*avctx, SingleChannelEleme
? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024)
: (avctx->bit_rate / avctx->ch_layout.nb_channels);
+ int pns_at_low_bitrate = frame_bit_rate < PNS_BITRATE_LIMIT;
frame_bit_rate *= 1.15f;
if (avctx->cutoff > 0) {
@@ -667,7 +672,7 @@ static void mark_pns(AACEncContext *s, AVCodecContext
*avctx, SingleChannelEleme
const int start = sce->ics.swb_offset[g];
const float freq = start*freq_mult;
const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f);
-if (freq < NOISE_LOW_LIMIT || start >= cutoff) {
+if (!pns_at_low_bitrate || freq < NOISE_LOW_LIMIT || start >=
cutoff) {
sce->can_pns[w*16+g] = 0;
continue;
}
--
2.49.1
From 81a985d6a92eb411ba495fb05a3a962d181649ea Mon Sep 17 00:00:00 2001
From: Agent45
Date: Sat, 1 Nov 2025 20:41:24 +
Subject: [PATCH 2/2] avcodec/aacpsy: fix attack detection logic and subblock
indexing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix several indexing errors in attack detection logic and refine transient
handling in the AAC psychoacoustic model.
- Change PSY_LAME_NUM_SUBBLOCKS from 3 to 2 to ensure full coverage of all 1024
MDCT samples, with each subblock containing exactly 1024 / (8 * 2) = 64
samples—matching LAME’s empirical design.
- Introduce next_attack0_zero state flag to stabilize attack[0] prediction
across frames.
- Adjust attack threshold presets.
These changes improve the handling of periodic signals such as trumpet,
especially under low bitrate conditions.
---
libavcodec/aacpsy.c | 64 +++--
1 file changed, 33 insertions(+), 31 deletions(-)
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index ed03cb68ac..f91ba45a52 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -97,7 +97,7 @@ enum {
#define AAC_BLOCK_SIZE_LONG 1024///< long block size
#define AAC_BLOCK_SIZE_SHORT 128///< short block size
#define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence
-#define PSY_LAME_NUM_SUBBLOCKS 3///< Number of sub-blocks in each short
block
+#define PSY_LAME_NUM_SUBBLOCKS 2///< Num