From: Lynne <dev@lynne.ee> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH] avcodec/aacdec: add support for AAC SBR with 960 frame length Date: Sat, 20 May 2023 16:17:20 +0200 (CEST) Message-ID: <NVtWPRX--3-9@lynne.ee> (raw) In-Reply-To: <14a406d5-5c56-ef89-bebf-18c205cae59e@walliczek.de> [-- Attachment #1: Type: text/plain, Size: 878 bytes --] May 20, 2023, 15:26 by matthias@walliczek.de: > Supports the european DAB+ digital radio coding > > Fixes: https://trac.ffmpeg.org/ticket/1407 "HE-AAC (v2): 960/120 MDCT window is not implemented" > > Signed-off-by: Matthias Walliczek <matthias@walliczek.de> > --- > libavcodec/aacdec_template.c | 21 ++-------- > libavcodec/aacps.c | 10 +++-- > libavcodec/aacps.h | 7 ++-- > libavcodec/aacps_common.c | 3 +- > libavcodec/aacsbr.h | 4 +- > libavcodec/aacsbr_template.c | 77 ++++++++++++++++++++---------------- > libavcodec/sbr.h | 4 +- > 7 files changed, 61 insertions(+), 65 deletions(-) > Yeah, no, this patch is far from complete. I have a more complete and correct patch I was working on which had a minor issue I didn't get around to fixing. I'll see if I have missed changing a constant that you haven't missed. [-- Attachment #2: 0001-aacdec-add-support-for-960-frame-HE-AAC.patch --] [-- Type: text/x-diff, Size: 13663 bytes --] From 219715305de9cb11a490f140f802533f4b01d100 Mon Sep 17 00:00:00 2001 From: Lynne <dev@lynne.ee> Date: Sat, 20 May 2023 16:09:22 +0200 Subject: [PATCH] aacdec: add support for 960-frame HE-AAC --- libavcodec/aacdec_template.c | 13 ------- libavcodec/aacps.c | 1 + libavcodec/aacps.h | 2 - libavcodec/aacps_common.c | 1 + libavcodec/aacsbr_template.c | 74 +++++++++++++++++++++++------------- libavcodec/sbr.h | 12 ++++-- 6 files changed, 58 insertions(+), 45 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 94aeeb97ab..d6648723fa 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -935,12 +935,6 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, int tags = 0; m4ac->frame_length_short = get_bits1(gb); - if (m4ac->frame_length_short && m4ac->sbr == 1) { - avpriv_report_missing_feature(avctx, "SBR with 960 frame length"); - if (ac) ac->warned_960_sbr = 1; - m4ac->sbr = 0; - m4ac->ps = 0; - } if (get_bits1(gb)) // dependsOnCoreCoder skip_bits(gb, 14); // coreCoderDelay @@ -2553,13 +2547,6 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, if (!che) { av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n"); return res; - } else if (ac->oc[1].m4ac.frame_length_short) { - if (!ac->warned_960_sbr) - avpriv_report_missing_feature(ac->avctx, - "SBR with 960 frame length"); - ac->warned_960_sbr = 1; - skip_bits_long(gb, 8 * cnt - 4); - return res; } else if (!ac->oc[1].m4ac.sbr) { av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n"); skip_bits_long(gb, 8 * cnt - 4); diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 655e8fe5b4..ece3680910 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -406,6 +406,7 @@ static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT INTFLOAT *peak_decay_diff_smooth = ps->peak_decay_diff_smooth; INTFLOAT (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay; INTFLOAT (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay; + const int numQMFSlots = 1 ? 30 : 32; #if !USE_FIXED const float transient_impact = 1.5f; const float a_smooth = 0.25f; ///< Smoothing coefficient diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h index 3efa38ad88..247f5d2e26 100644 --- a/libavcodec/aacps.h +++ b/libavcodec/aacps.h @@ -43,8 +43,6 @@ ///< Baseline implies 10 or 20 stereo bands, ///< mixing mode A, and no ipd/opd -#define numQMFSlots 32 //numTimeSlots * RATE - typedef struct PSCommonContext { int start; int enable_iid; diff --git a/libavcodec/aacps_common.c b/libavcodec/aacps_common.c index c388d5b9bc..7c059f8e52 100644 --- a/libavcodec/aacps_common.c +++ b/libavcodec/aacps_common.c @@ -139,6 +139,7 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, int header; int bits_consumed; GetBitContext gbc = *gb_host, *gb = &gbc; + const int numQMFSlots = 1 ? 30 : 32; header = get_bits1(gb); if (header) { //enable_ps_header diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c index cdca402f04..d6b88fc2ea 100644 --- a/libavcodec/aacsbr_template.c +++ b/libavcodec/aacsbr_template.c @@ -94,7 +94,7 @@ av_cold int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplicat int ret; float scale; - if (sbr->mdct) + if (sbr->mdct60) return 0; sbr->kx[0] = sbr->kx[1]; @@ -106,15 +106,29 @@ av_cold int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplicat * mdct scale factors are adjusted to scale up from +/-1.0 at analysis * and scale back down at synthesis. */ + scale = USE_FIXED ? 1 : 1.0 / (60 * 32768); + ret = av_tx_init(&sbr->mdct60, &sbr->mdct60_fn, + USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT, + 1, 60, &scale, 0); + if (ret < 0) + return ret; + + scale = USE_FIXED ? -1.0 : -2.0 * 32768; + ret = av_tx_init(&sbr->mdct60_ana, &sbr->mdct60_ana_fn, + USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT, + 1, 60, &scale, 0); + if (ret < 0) + return ret; + scale = USE_FIXED ? 1 : 1.0 / (64 * 32768); - ret = av_tx_init(&sbr->mdct, &sbr->mdct_fn, + ret = av_tx_init(&sbr->mdct64, &sbr->mdct64_fn, USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT, 1, 64, &scale, 0); if (ret < 0) return ret; scale = USE_FIXED ? -1.0 : -2.0 * 32768; - ret = av_tx_init(&sbr->mdct_ana, &sbr->mdct_ana_fn, + ret = av_tx_init(&sbr->mdct64_ana, &sbr->mdct64_ana_fn, USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT, 1, 64, &scale, 0); if (ret < 0) @@ -129,8 +143,10 @@ av_cold int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplicat av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr) { - av_tx_uninit(&sbr->mdct); - av_tx_uninit(&sbr->mdct_ana); + av_tx_uninit(&sbr->mdct60); + av_tx_uninit(&sbr->mdct60_ana); + av_tx_uninit(&sbr->mdct64); + av_tx_uninit(&sbr->mdct64_ana); } static int qsort_comparison_function_int16(const void *a, const void *b) @@ -647,8 +663,7 @@ static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr, { int i; int bs_pointer = 0; - // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots - int abs_bord_trail = 16; + int abs_bord_trail = ac->oc[1].m4ac.frame_length_short ? 15 : 16; int num_rel_lead, num_rel_trail; unsigned bs_num_env_old = ch_data->bs_num_env; int bs_frame_class, bs_num_env; @@ -1193,13 +1208,13 @@ static void sbr_qmf_analysis(AVFloatDSPContext *dsp, AVTXContext *mdct, INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx) { int i; + int lp = /*ac->oc[1].m4ac.frame_length_short*/ 1 ? 15*2 : 16*2; #if USE_FIXED int j; #endif memcpy(x , x+1024, (320-32)*sizeof(x[0])); memcpy(x+288, in, 1024*sizeof(x[0])); - for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames - // are not supported + for (i = 0; i < lp; i++) { dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320); sbrdsp->sum64x5(z); sbrdsp->qmf_pre_shuffle(z); @@ -1243,8 +1258,10 @@ static void sbr_qmf_synthesis(AVTXContext *mdct, av_tx_fn mdct_fn, int i, n; const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us; const int step = 128 >> div; + int lp = /*ac->oc[1].m4ac.frame_length_short*/ 1 ? 15*2 : 16*2; + int lf = /*ac->oc[1].m4ac.frame_length_short*/ 1 ? 60 : 64; INTFLOAT *v; - for (i = 0; i < 32; i++) { + for (i = 0; i < lp; i++) { if (*v_off < step) { int saved_samples = (1280 - 128) >> div; memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(INTFLOAT)); @@ -1266,17 +1283,17 @@ static void sbr_qmf_synthesis(AVTXContext *mdct, av_tx_fn mdct_fn, mdct_fn(mdct, mdct_buf[1], X[1][i], sizeof(INTFLOAT)); sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]); } - dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div); - dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div); - dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div); - out += 64 >> div; + dsp->vector_fmul (out, v , sbr_qmf_window , lf >> div); + dsp->vector_fmul_add(out, v + (lf*3 >> div), sbr_qmf_window + (lf*1 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*4 >> div), sbr_qmf_window + (lf*2 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*7 >> div), sbr_qmf_window + (lf*3 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*8 >> div), sbr_qmf_window + (lf*4 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*11 >> div), sbr_qmf_window + (lf*5 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*12 >> div), sbr_qmf_window + (lf*6 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*15 >> div), sbr_qmf_window + (lf*7 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*16 >> div), sbr_qmf_window + (lf*8 >> div), out , lf >> div); + dsp->vector_fmul_add(out, v + (lf*18 >> div), sbr_qmf_window + (lf*9 >> div), out , lf >> div); + out += lf >> div; } } #endif @@ -1288,7 +1305,7 @@ static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr, { int i, k; const int t_HFGen = 8; - const int i_f = 32; + const int i_f = ac->oc[1].m4ac.frame_length_short ? 15*2 : 16*2; memset(X_low, 0, 32*sizeof(*X_low)); for (k = 0; k < sbr->kx[1]; k++) { for (i = t_HFGen; i < i_f + t_HFGen; i++) { @@ -1347,7 +1364,7 @@ static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64], const INTFLOAT X_low[32][40][2], int ch) { int k, i; - const int i_f = 32; + const int i_f = /*ac->oc[1].m4ac.frame_length_short*/ 1 ? 15*2 : 16*2; const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0); memset(X, 0, 2*sizeof(*X)); for (k = 0; k < sbr->kx[0]; k++) { @@ -1498,6 +1515,11 @@ static void sbr_env_estimate(AAC_FLOAT (*e_curr)[48], INTFLOAT X_high[64][40][2] void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac, INTFLOAT* L, INTFLOAT* R) { + AVTXContext *mdct = ac->oc[1].m4ac.frame_length_short ? sbr->mdct60 : sbr->mdct64; + av_tx_fn mdct_fn = ac->oc[1].m4ac.frame_length_short ? sbr->mdct60_fn : sbr->mdct64_fn; + AVTXContext *mdcta = ac->oc[1].m4ac.frame_length_short ? sbr->mdct60_ana : sbr->mdct64_ana; + av_tx_fn mdcta_fn = ac->oc[1].m4ac.frame_length_short ? sbr->mdct60_ana_fn : sbr->mdct64_ana_fn; + int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate; int ch; int nch = (id_aac == TYPE_CPE) ? 2 : 1; @@ -1528,7 +1550,7 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int } for (ch = 0; ch < nch; ch++) { /* decode channel */ - sbr_qmf_analysis(ac->fdsp, sbr->mdct_ana, sbr->mdct_ana_fn, &sbr->dsp, + sbr_qmf_analysis(ac->fdsp, mdcta, mdcta_fn, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples, (INTFLOAT*)sbr->qmf_filter_scratch, sbr->data[ch].W, sbr->data[ch].Ypos); @@ -1576,13 +1598,13 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int nch = 2; } - sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &sbr->dsp, ac->fdsp, + sbr_qmf_synthesis(mdct, mdct_fn, &sbr->dsp, ac->fdsp, L, sbr->X[0], sbr->qmf_filter_scratch, sbr->data[0].synthesis_filterbank_samples, &sbr->data[0].synthesis_filterbank_samples_offset, downsampled); if (nch == 2) - sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &sbr->dsp, ac->fdsp, + sbr_qmf_synthesis(mdct, mdct_fn, &sbr->dsp, ac->fdsp, R, sbr->X[1], sbr->qmf_filter_scratch, sbr->data[1].synthesis_filterbank_samples, &sbr->data[1].synthesis_filterbank_samples_offset, diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h index f949465ef5..b4b8d151c3 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -211,10 +211,14 @@ struct SpectralBandReplication { AAC_FLOAT s_m[7][48]; AAC_FLOAT gain[7][48]; DECLARE_ALIGNED(32, INTFLOAT, qmf_filter_scratch)[5][64]; - AVTXContext *mdct_ana; - av_tx_fn mdct_ana_fn; - AVTXContext *mdct; - av_tx_fn mdct_fn; + AVTXContext *mdct60_ana; + av_tx_fn mdct60_ana_fn; + AVTXContext *mdct60; + av_tx_fn mdct60_fn; + AVTXContext *mdct64_ana; + av_tx_fn mdct64_ana_fn; + AVTXContext *mdct64; + av_tx_fn mdct64_fn; SBRDSPContext dsp; AACSBRContext c; }; -- 2.40.0 [-- Attachment #3: Type: text/plain, Size: 251 bytes --] _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2023-05-20 14:17 UTC|newest] Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-05-20 13:25 Matthias Walliczek 2023-05-20 13:29 ` Paul B Mahol 2023-05-20 14:06 ` Matthias Walliczek 2023-05-20 14:17 ` Lynne [this message] 2023-05-20 14:34 ` Matthias Walliczek
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=NVtWPRX--3-9@lynne.ee \ --to=dev@lynne.ee \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git