From patchwork Thu May 16 10:08:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lynne X-Patchwork-Id: 48912 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:3a48:b0:1af:fc2d:ff5a with SMTP id zu8csp2129394pzb; Thu, 16 May 2024 03:09:05 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXmZt2Hc/jdRzlPMEnQLdXSqav6nIoufQwKFJcRnQ6L8nJdRy1bt41j3lfb33vh+/RvT77IOBSNtJbTx2WNK2aZ25qX8WbFTlXOZw== X-Google-Smtp-Source: AGHT+IGzWu6pD2rYqqdLVTd1dlu/5DHGG48dDDtfvuF/DW+av5Jx27ECRvrnqSdbLRLt+xXqKAnQ X-Received: by 2002:a17:906:d972:b0:a5a:1561:ba52 with SMTP id a640c23a62f3a-a5a2d6e2b1cmr1109349366b.7.1715854145116; Thu, 16 May 2024 03:09:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1715854145; cv=none; d=google.com; s=arc-20160816; b=WN+pmfsjghT1V1BEc9rN/MPET1PFxu5zoV5kswOPtowcmwJagQnp/9fob0l/geNTuJ f8llaSIup+lwOHjtvIaqJKJ3VNoBMGdCZXGPTBG3Ny51ekwOruYIuflaWLFkHNKUQNKE XvjBrTZ/tQ+2suWwToPpdrsPebUx3hGq37dy/CFSZW5d3y179fsmEfluBLUFgp9B70OF fr+zx3OEb67xQU/rCdg29cMtUAXecu1M64iEEAZYDUfk+JNE08HzhOg5cdkmRsahJsbl 2rUioMQZ/DpQ9LccnWWyfYU4P1dUTOgz34I2WzX8pRCQiRXdvarIROkHmDnWyWLkim+Q mHig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:delivered-to; bh=wG2vo3Rgft8nTtIKN3RK8aXHdPimfoSj6iNZaQAi3f8=; fh=nenT92/WZoU6unXd3J6UhGUdod4piddKfVtctNBOh6k=; b=pZ5WDIog3m+6dpKd/DFm+MTmxM1gj9ZfQLl3aBNtQ3Eri+htc5qilf/+FSTePHBE1w DdqnfUfMh8IIYIGrH0FAWKgrSkstZnb7iyV5fREfgysDKaFezSWxx2QbumLMIbkE7lys fDHcSmN9OaU2jEVIQACtD4T593jwK7MIDpJ8WHteZOZtJod9w6cAFvFANv2eKxrotJHF u5qq+SFGErKw/+A86RqXqPQojbo0ySGLI8n7laYH9SsdEY3F9Gexk7kgF/CUYXMKzcdq 6KYctv0uAy7WcMiojRkRqBP+4q1GEEtwfsblg6FQnNFSYN3w/CUAIQOGiQB6jZy9keoX T/6w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a5a17be1bcasi842558066b.704.2024.05.16.03.09.04; Thu, 16 May 2024 03:09:05 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4F83968D517; Thu, 16 May 2024 13:08:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vidala.lynne.ee (vidala.pars.ee [116.203.72.101]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 42B8D68D4EC for ; Thu, 16 May 2024 13:08:51 +0300 (EEST) To: ffmpeg-devel@ffmpeg.org Date: Thu, 16 May 2024 12:08:11 +0200 Message-ID: <20240516100818.246162-2-dev@lynne.ee> X-Mailer: git-send-email 2.43.0.381.gb435a96ce8 In-Reply-To: <20240516100818.246162-1-dev@lynne.ee> References: <20240516100818.246162-1-dev@lynne.ee> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/8] aacdec: move from scalefactor ranged arrays to flat arrays X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Lynne via ffmpeg-devel From: Lynne Reply-To: FFmpeg development discussions and patches Cc: Lynne Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 1eMCXRO57O72 AAC uses an unconventional system to send scalefactors (the volume+quantization value for each band). Each window is split into either 1 or 8 blocks (long vs short), and transformed separately from one another, with the coefficients for each being also completely independent. The scalefactors slightly increase from 64 (long) to 128 (short) to accomodate better per-block-per-band volume for each window. To reduce overhead, the codec signals scalefactor sizes in an obtuse way, where each group's scalefactor types are sent via a variable length decoding, with a range. But our decoder was written in a way where those ranges were carried through the entire decoder, and to actually read them you had to use the range. Instead of having a dedicated array with a range for each scalefactor, just let the decoder directly index each scalefactor. This also switches the form of quantized scalefactors to the format the spec uses, where for intensity stereo and regular, scalefactors are stored in a scalefactor - 100 form, rather than as-is. USAC gets rid of the complex scalefactor handling. This commit permits for code sharing between both. --- libavcodec/aac/Makefile | 3 +- libavcodec/aac/aacdec.c | 100 ++++++++++++--------------- libavcodec/aac/aacdec.h | 5 +- libavcodec/aac/aacdec_dsp_template.c | 95 ++++++++++--------------- 4 files changed, 85 insertions(+), 118 deletions(-) diff --git a/libavcodec/aac/Makefile b/libavcodec/aac/Makefile index c3e525d373..8b0bfff3e5 100644 --- a/libavcodec/aac/Makefile +++ b/libavcodec/aac/Makefile @@ -2,6 +2,7 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libavcodec/aac/%) OBJS-$(CONFIG_AAC_DECODER) += aac/aacdec.o aac/aacdec_tab.o \ - aac/aacdec_float.o + aac/aacdec_float.o aac/aacdec_usac.o \ + aac/aacdec_ac.o OBJS-$(CONFIG_AAC_FIXED_DECODER) += aac/aacdec.o aac/aacdec_tab.o \ aac/aacdec_fixed.o diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c index 7457fe6c97..35722f9b9b 100644 --- a/libavcodec/aac/aacdec.c +++ b/libavcodec/aac/aacdec.c @@ -1412,13 +1412,13 @@ fail: * * @return Returns error status. 0 - OK, !0 - error */ -static int decode_band_types(AACDecContext *ac, enum BandType band_type[120], - int band_type_run_end[120], GetBitContext *gb, - IndividualChannelStream *ics) +static int decode_band_types(AACDecContext *ac, SingleChannelElement *sce, + GetBitContext *gb) { - int g, idx = 0; + IndividualChannelStream *ics = &sce->ics; const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5; - for (g = 0; g < ics->num_window_groups; g++) { + + for (int g = 0; g < ics->num_window_groups; g++) { int k = 0; while (k < ics->max_sfb) { uint8_t sect_end = k; @@ -1442,10 +1442,8 @@ static int decode_band_types(AACDecContext *ac, enum BandType band_type[120], return AVERROR_INVALIDDATA; } } while (sect_len_incr == (1 << bits) - 1); - for (; k < sect_end; k++) { - band_type [idx] = sect_band_type; - band_type_run_end[idx++] = sect_end; - } + for (; k < sect_end; k++) + sce->band_type[g*ics->max_sfb + k] = sect_band_type; } } return 0; @@ -1461,69 +1459,59 @@ static int decode_band_types(AACDecContext *ac, enum BandType band_type[120], * * @return Returns error status. 0 - OK, !0 - error */ -static int decode_scalefactors(AACDecContext *ac, int sfo[120], - GetBitContext *gb, - unsigned int global_gain, - IndividualChannelStream *ics, - enum BandType band_type[120], - int band_type_run_end[120]) +static int decode_scalefactors(AACDecContext *ac, SingleChannelElement *sce, + GetBitContext *gb, unsigned int global_gain) { - int g, i, idx = 0; + IndividualChannelStream *ics = &sce->ics; int offset[3] = { global_gain, global_gain - NOISE_OFFSET, 0 }; int clipped_offset; int noise_flag = 1; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb;) { - int run_end = band_type_run_end[idx]; - switch (band_type[idx]) { + + for (int g = 0; g < ics->num_window_groups; g++) { + for (int sfb = 0; sfb < ics->max_sfb; sfb++) { + switch (sce->band_type[g*ics->max_sfb + sfb]) { case ZERO_BT: - for (; i < run_end; i++, idx++) - sfo[idx] = 0; + sce->sfo[g*ics->max_sfb + sfb] = 0; break; case INTENSITY_BT: /* fallthrough */ case INTENSITY_BT2: - for (; i < run_end; i++, idx++) { - offset[2] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; - clipped_offset = av_clip(offset[2], -155, 100); - if (offset[2] != clipped_offset) { - avpriv_request_sample(ac->avctx, - "If you heard an audible artifact, there may be a bug in the decoder. " - "Clipped intensity stereo position (%d -> %d)", - offset[2], clipped_offset); - } - sfo[idx] = clipped_offset; + offset[2] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; + clipped_offset = av_clip(offset[2], -155, 100); + if (offset[2] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped intensity stereo position (%d -> %d)", + offset[2], clipped_offset); } + sce->sfo[g*ics->max_sfb + sfb] = clipped_offset - 100; break; case NOISE_BT: - for (; i < run_end; i++, idx++) { - if (noise_flag-- > 0) - offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE; - else - offset[1] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; - clipped_offset = av_clip(offset[1], -100, 155); - if (offset[1] != clipped_offset) { - avpriv_request_sample(ac->avctx, - "If you heard an audible artifact, there may be a bug in the decoder. " - "Clipped noise gain (%d -> %d)", - offset[1], clipped_offset); - } - sfo[idx] = clipped_offset; + if (noise_flag-- > 0) + offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE; + else + offset[1] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; + clipped_offset = av_clip(offset[1], -100, 155); + if (offset[1] != clipped_offset) { + avpriv_request_sample(ac->avctx, + "If you heard an audible artifact, there may be a bug in the decoder. " + "Clipped noise gain (%d -> %d)", + offset[1], clipped_offset); } + sce->sfo[g*ics->max_sfb + sfb] = clipped_offset; break; default: - for (; i < run_end; i++, idx++) { - offset[0] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; - if (offset[0] > 255U) { - av_log(ac->avctx, AV_LOG_ERROR, - "Scalefactor (%d) out of range.\n", offset[0]); - return AVERROR_INVALIDDATA; - } - sfo[idx] = offset[0]; + offset[0] += get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - SCALE_DIFF_ZERO; + if (offset[0] > 255U) { + av_log(ac->avctx, AV_LOG_ERROR, + "Scalefactor (%d) out of range.\n", offset[0]); + return AVERROR_INVALIDDATA; } + sce->sfo[g*ics->max_sfb + sfb] = offset[0] - 100; break; } } } + return 0; } @@ -1680,11 +1668,9 @@ int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce, goto fail; } - if ((ret = decode_band_types(ac, sce->band_type, - sce->band_type_run_end, gb, ics)) < 0) + if ((ret = decode_band_types(ac, sce, gb)) < 0) goto fail; - if ((ret = decode_scalefactors(ac, sce->sfo, gb, global_gain, ics, - sce->band_type, sce->band_type_run_end)) < 0) + if ((ret = decode_scalefactors(ac, sce, gb, global_gain)) < 0) goto fail; ac->dsp.dequant_scalefactors(sce); diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h index eed53c6c96..7585a4450b 100644 --- a/libavcodec/aac/aacdec.h +++ b/libavcodec/aac/aacdec.h @@ -146,9 +146,8 @@ typedef struct SingleChannelElement { IndividualChannelStream ics; TemporalNoiseShaping tns; enum BandType band_type[128]; ///< band types - int band_type_run_end[120]; ///< band type run end points - int sfo[120]; ///< scalefactor offsets - INTFLOAT_UNION(sf, [120]); ///< scalefactors + int sfo[128]; ///< scalefactor offsets + INTFLOAT_UNION(sf, [512]); ///< scalefactors (8 windows * 16 sfb max) INTFLOAT_ALIGNED_UNION(32, coeffs, 1024); ///< coefficients for IMDCT, maybe processed INTFLOAT_ALIGNED_UNION(32, saved, 1536); ///< overlap INTFLOAT_ALIGNED_UNION(32, ret_buf, 2048); ///< PCM output buffer diff --git a/libavcodec/aac/aacdec_dsp_template.c b/libavcodec/aac/aacdec_dsp_template.c index 621baef8ca..e69970472c 100644 --- a/libavcodec/aac/aacdec_dsp_template.c +++ b/libavcodec/aac/aacdec_dsp_template.c @@ -41,47 +41,37 @@ static void AAC_RENAME(dequant_scalefactors)(SingleChannelElement *sce) { IndividualChannelStream *ics = &sce->ics; - const enum BandType *band_type = sce->band_type; - const int *band_type_run_end = sce->band_type_run_end; const int *sfo = sce->sfo; INTFLOAT *sf = sce->AAC_RENAME(sf); - int g, i, idx = 0; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb;) { - int run_end = band_type_run_end[idx]; - switch (band_type[idx]) { + int idx = 0; + for (int g = 0; g < ics->num_window_groups; g++) { + for (int sfb = 0; sfb < ics->max_sfb; sfb++, idx++) { + switch (sce->band_type[g*ics->max_sfb + sfb]) { case ZERO_BT: - for (; i < run_end; i++, idx++) - sf[idx] = FIXR(0.); + sf[idx] = FIXR(0.); break; case INTENSITY_BT: /* fallthrough */ case INTENSITY_BT2: - for (; i < run_end; i++, idx++) { #if USE_FIXED - sf[idx] = 100 - sfo[idx]; + sf[idx] = 100 - (sfo[idx] + 100); #else - sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] + POW_SF2_ZERO]; + sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] - 100 + POW_SF2_ZERO]; #endif /* USE_FIXED */ - } break; case NOISE_BT: - for (; i < run_end; i++, idx++) { #if USE_FIXED - sf[idx] = -(100 + sfo[idx]); + sf[idx] = -(100 + sfo[idx]); #else - sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO]; + sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO]; #endif /* USE_FIXED */ - } break; default: - for (; i < run_end; i++, idx++) { #if USE_FIXED - sf[idx] = -sfo[idx]; + sf[idx] = -sfo[idx] - 100; #else - sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] - 100 + POW_SF2_ZERO]; + sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO]; #endif /* USE_FIXED */ - } break; } } @@ -96,25 +86,23 @@ static void AAC_RENAME(apply_mid_side_stereo)(AACDecContext *ac, ChannelElement const IndividualChannelStream *ics = &cpe->ch[0].ics; INTFLOAT *ch0 = cpe->ch[0].AAC_RENAME(coeffs); INTFLOAT *ch1 = cpe->ch[1].AAC_RENAME(coeffs); - int g, i, group, idx = 0; const uint16_t *offsets = ics->swb_offset; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb; i++, idx++) { + for (int g = 0; g < ics->num_window_groups; g++) { + for (int sfb = 0; sfb < ics->max_sfb; sfb++) { + const int idx = g*ics->max_sfb + sfb; if (cpe->ms_mask[idx] && cpe->ch[0].band_type[idx] < NOISE_BT && cpe->ch[1].band_type[idx] < NOISE_BT) { + for (int group = 0; group < ics->group_len[g]; group++) #if USE_FIXED - for (group = 0; group < ics->group_len[g]; group++) { - ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[i], - ch1 + group * 128 + offsets[i], - offsets[i+1] - offsets[i]); + ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[sfb], + ch1 + group * 128 + offsets[sfb], + offsets[sfb+1] - offsets[sfb]); #else - for (group = 0; group < ics->group_len[g]; group++) { - ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i], - ch1 + group * 128 + offsets[i], - offsets[i+1] - offsets[i]); + ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[sfb], + ch1 + group * 128 + offsets[sfb], + offsets[sfb+1] - offsets[sfb]); #endif /* USE_FIXED */ - } } } ch0 += ics->group_len[g] * 128; @@ -136,37 +124,30 @@ static void AAC_RENAME(apply_intensity_stereo)(AACDecContext *ac, SingleChannelElement *sce1 = &cpe->ch[1]; INTFLOAT *coef0 = cpe->ch[0].AAC_RENAME(coeffs), *coef1 = cpe->ch[1].AAC_RENAME(coeffs); const uint16_t *offsets = ics->swb_offset; - int g, group, i, idx = 0; int c; INTFLOAT scale; - for (g = 0; g < ics->num_window_groups; g++) { - for (i = 0; i < ics->max_sfb;) { + for (int g = 0; g < ics->num_window_groups; g++) { + for (int sfb = 0; sfb < ics->max_sfb; sfb++) { + const int idx = g*ics->max_sfb + sfb; if (sce1->band_type[idx] == INTENSITY_BT || sce1->band_type[idx] == INTENSITY_BT2) { - const int bt_run_end = sce1->band_type_run_end[idx]; - for (; i < bt_run_end; i++, idx++) { - c = -1 + 2 * (sce1->band_type[idx] - 14); - if (ms_present) - c *= 1 - 2 * cpe->ms_mask[idx]; - scale = c * sce1->AAC_RENAME(sf)[idx]; - for (group = 0; group < ics->group_len[g]; group++) + c = -1 + 2 * (sce1->band_type[idx] - 14); + if (ms_present) + c *= 1 - 2 * cpe->ms_mask[idx]; + scale = c * sce1->AAC_RENAME(sf)[idx]; + for (int group = 0; group < ics->group_len[g]; group++) #if USE_FIXED - subband_scale(coef1 + group * 128 + offsets[i], - coef0 + group * 128 + offsets[i], - scale, - 23, - offsets[i + 1] - offsets[i] ,ac->avctx); + subband_scale(coef1 + group * 128 + offsets[sfb], + coef0 + group * 128 + offsets[sfb], + scale, + 23, + offsets[sfb + 1] - offsets[sfb], ac->avctx); #else - ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i], - coef0 + group * 128 + offsets[i], - scale, - offsets[i + 1] - offsets[i]); + ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[sfb], + coef0 + group * 128 + offsets[sfb], + scale, + offsets[sfb + 1] - offsets[sfb]); #endif /* USE_FIXED */ - } - } else { - int bt_run_end = sce1->band_type_run_end[idx]; - idx += bt_run_end - i; - i = bt_run_end; } } coef0 += ics->group_len[g] * 128;