Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
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".

  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