PR #22846 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22846 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22846.patch
This implements support for DRC parameter decoding. Only focused on loudness normalization for now. >From 8ae5e22bc5ff34d29a2881e2d801a9cfb50421b7 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Fri, 17 Apr 2026 18:13:40 +0200 Subject: [PATCH] aacdec_usac: implement basic DRC parameter decoding --- libavcodec/aac/aacdec.h | 13 +++++++ libavcodec/aac/aacdec_usac.c | 74 +++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h index c67246e287..cf55bbe6c0 100644 --- a/libavcodec/aac/aacdec.h +++ b/libavcodec/aac/aacdec.h @@ -98,6 +98,12 @@ enum AACUSACLoudnessExt { UNIDRCLOUDEXT_EQ = 0x1, }; +enum AACUSACDRCExt { + UNIDRCCONFEXT_TERM = 0x0, + UNIDRCCONFEXT_PARAM_DRC = 0x1, + UNIDRCCONFEXT_V1 = 0x2, +}; + // Supposed to be equal to AAC_RENAME() in case of USE_FIXED. #define RENAME_FIXED(name) name ## _fixed @@ -377,6 +383,13 @@ typedef struct AACUsacElemConfig { uint32_t pl_data_offset; uint8_t *pl_buf; } ext; + + struct { + struct { + int lower; + int upper; + } loudness; + } drc; } AACUsacElemConfig; typedef struct AACUSACConfig { diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c index 0f1bb50a99..89f66ba06f 100644 --- a/libavcodec/aac/aacdec_usac.c +++ b/libavcodec/aac/aacdec_usac.c @@ -253,6 +253,76 @@ static int decode_usac_element_pair(AACDecContext *ac, return 0; } +static int decode_drc_config(AACDecContext *ac, AACUsacElemConfig *e, + GetBitContext *gb) +{ + e->drc.loudness.lower = -1; + e->drc.loudness.upper = -1; + + if (get_bits1(gb)) + skip_bits(gb, 18); /* bsSampleRate */ + + skip_bits(gb, 7); /* downmixInstructionsCount */ + + if (get_bits1(gb)) /* drcDescriptionBasicPresent */ + skip_bits(gb, 3); /* drcCoefficientsBasicCount */ + + int nb_coeff_count = get_bits(gb, 3); /* drcCoefficientsUniDrcCount */ + if (nb_coeff_count) { + avpriv_report_missing_feature(ac->avctx, + "AAC USAC DRC coeff/instruction handling"); + return AVERROR_PATCHWELCOME; + } + + int nb_instr_count = get_bits(gb, 6); /* drcInstructionsUniDrcCount */ + for (int i = 0; i < nb_instr_count; i++) { + skip_bits(gb, 6); /* drcSetId */ + skip_bits(gb, 4); /* drcLocation */ + skip_bits(gb, 7); /* downmixId */ + if (get_bits1(gb)) { /* additionalDownmixIdPresent */ + int add_downmix_cnt = get_bits(gb, 3); + for (int i = 0; i < add_downmix_cnt; i++) + skip_bits(gb, 7); + } + + int set_effects = get_bits(gb, 16); + if ((set_effects & (3 << 10)) == 0) { + if (get_bits1(gb)) + skip_bits(gb, 8); /* bsLimiterPeakTarget */ + } + + if (get_bits1(gb)) { /* drcSetTargetLoudnessPresent */ + e->drc.loudness.upper = get_bits(gb, 6); + if (get_bits1(gb)) + e->drc.loudness.lower = get_bits(gb, 6); + } + } + + { + int ch_count = get_bits(gb, 7); /* baseChannelCount */ + if (get_bits1(gb)) { + if (get_bits(gb, 8) == 0) + for (int i = 0; i < ch_count; i++) + skip_bits(gb, 7); /* speakerPosition */ + } + } + + if (get_bits1(gb)) { /* uniDrcConfigExtPresent */ + enum AACUSACDRCExt type; + while ((type = get_bits(gb, 4)) != UNIDRCCONFEXT_TERM) { + uint8_t size_bits = get_bits(gb, 4) + 4; + uint8_t bit_size = get_bits(gb, size_bits) + 1; + switch (type) { + default: + for (int i = 0; i < bit_size; i++) + skip_bits1(gb); + } + } + } + + return 0; +} + static int decode_usac_extension(AACDecContext *ac, AACUsacElemConfig *e, GetBitContext *gb) { @@ -276,9 +346,9 @@ static int decode_usac_extension(AACDecContext *ac, AACUsacElemConfig *e, break; case ID_EXT_ELE_SAOC: break; - case ID_EXT_ELE_UNI_DRC: - break; #endif + case ID_EXT_ELE_UNI_DRC: + return decode_drc_config(ac, e, gb); case ID_EXT_ELE_FILL: break; /* This is what the spec does */ case ID_EXT_ELE_AUDIOPREROLL: -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
