diff mbox series

[FFmpeg-devel,v2] avcodec/aacdec: add support for AAC SBR with 960 frame length

Message ID 5fd9b52d-9b88-30f0-0f8e-92e229026636@walliczek.de
State New
Headers show
Series [FFmpeg-devel,v2] avcodec/aacdec: add support for AAC SBR with 960 frame length | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Matthias Walliczek May 20, 2023, 8:17 p.m. UTC
Supports the european DAB+ digital radio coding

Fixes: https://trac.ffmpeg.org/ticket/1407 "HE-AAC (v2): 960/120 MDCT 
window is not implemented"

Co-developed-by: Lynne <dev@lynne.ee>
Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
---
  libavcodec/aacdec_template.c | 17 ++------------
  libavcodec/aacps.c           |  8 ++++---
  libavcodec/aacps.h           |  7 +++---
  libavcodec/aacps_common.c    |  3 ++-
  libavcodec/aacsbr_template.c | 43 +++++++++++++++++++++---------------
  libavcodec/sbr.h             |  2 +-
  6 files changed, 38 insertions(+), 42 deletions(-)

                                    INTFLOAT (*alpha0)[2], INTFLOAT 
(*alpha1)[2],
                                    const INTFLOAT X_low[32][40][2], int 
k0);

Comments

Lynne May 20, 2023, 8:46 p.m. UTC | #1
May 20, 2023, 22:17 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"
>
> Co-developed-by: Lynne <dev@lynne.ee>
> Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
> ---
>  libavcodec/aacdec_template.c | 17 ++------------
>  libavcodec/aacps.c           |  8 ++++---
>  libavcodec/aacps.h           |  7 +++---
>  libavcodec/aacps_common.c    |  3 ++-
>  libavcodec/aacsbr_template.c | 43 +++++++++++++++++++++---------------
>  libavcodec/sbr.h             |  2 +-
>  6 files changed, 38 insertions(+), 42 deletions(-)
>

Patch is malformed, still missing stuff, and I was just about to post
an updated version of mine.
Let's not step on each other's toes and let me take over?
Lynne May 21, 2023, 3:31 a.m. UTC | #2
May 20, 2023, 22:47 by dev@lynne.ee:

> May 20, 2023, 22:17 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"
>>
>> Co-developed-by: Lynne <dev@lynne.ee>
>> Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
>> ---
>>  libavcodec/aacdec_template.c | 17 ++------------
>>  libavcodec/aacps.c           |  8 ++++---
>>  libavcodec/aacps.h           |  7 +++---
>>  libavcodec/aacps_common.c    |  3 ++-
>>  libavcodec/aacsbr_template.c | 43 +++++++++++++++++++++---------------
>>  libavcodec/sbr.h             |  2 +-
>>  6 files changed, 38 insertions(+), 42 deletions(-)
>>
>
> Patch is malformed, still missing stuff, and I was just about to post
> an updated version of mine.
> Let's not step on each other's toes and let me take over?
>

Patch may take slightly longer.
I'm having to make new versions of the DSP functions too,
and the QMF synthesis code is also wrong. It really is not as simple
as changing a few constants, which is why I put it off.
Keep in mind even if it sounds somewhat right, it's still
unacceptable - there is only a single valid way of decoding a file.
diff mbox series

Patch

diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 444dc4fa9d..72446537f1 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -849,12 +849,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
@@ -1047,10 +1041,10 @@  static int 
decode_audio_specific_config_gb(AACContext *ac,
      }
       ff_dlog(avctx,
-            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
+            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d 
frame length %d\n",
              m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
              m4ac->sample_rate, m4ac->sbr,
-            m4ac->ps);
+            m4ac->ps, m4ac->frame_length_short ? 960 : 1024);
       return get_bits_count(gb);
  }
@@ -2467,13 +2461,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..4804722e59 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -397,7 +397,7 @@  static void map_val_20_to_34(INTFLOAT 
par[PS_MAX_NR_IIDICC])
      par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
  }
  -static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], 
const INTFLOAT (*s)[32][2], int is34)
+static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const 
INTFLOAT (*s)[32][2], int is34, int frame_length_short)
  {
      LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
      LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
@@ -414,6 +414,7 @@  static void decorrelation(PSContext *ps, INTFLOAT 
(*out)[32][2], const INTFLOAT
      int i, k, m, n;
      int n0 = 0, nL = 32;
      const INTFLOAT peak_decay_factor = Q31(0.76592833836465f);
+    const int numQMFSlots = frame_length_short ? 30 : 32;
       memset(power, 0, 34 * sizeof(*power));
  @@ -717,7 +718,8 @@ static void stereo_processing(PSContext *ps, 
INTFLOAT (*l)[32][2], INTFLOAT (*r)
      }
  }
  -int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
+int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
+                            int frame_length_short)
  {
      INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
      INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
@@ -730,7 +732,7 @@  int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, 
PSContext *ps, INTFLOAT L[2][
          memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - 
top)*sizeof(ps->ap_delay[0]));
       hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
-    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
+    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34, 
frame_length_short);
      stereo_processing(ps, Lbuf, Rbuf, is34);
      hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
      hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
index 3efa38ad88..c771bfb270 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;
@@ -96,7 +94,8 @@  void ff_ps_init_common(void);
  void AAC_RENAME(ff_ps_init)(void);
  void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
  int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb,
-                     PSCommonContext *ps, int bits_left);
-int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
+                     PSCommonContext *ps, int bits_left, int 
frame_length_short);
+int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
+                            int frame_length_short);
   #endif /* AVCODEC_AACPS_H */
diff --git a/libavcodec/aacps_common.c b/libavcodec/aacps_common.c
index c388d5b9bc..87521c52e3 100644
--- a/libavcodec/aacps_common.c
+++ b/libavcodec/aacps_common.c
@@ -132,13 +132,14 @@  static int ps_read_extension_data(GetBitContext 
*gb, PSCommonContext *ps,
  }
   int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
-                    PSCommonContext *ps, int bits_left)
+                    PSCommonContext *ps, int bits_left, int 
frame_length_short)
  {
      int e;
      int bit_count_start = get_bits_count(gb_host);
      int header;
      int bits_consumed;
      GetBitContext gbc = *gb_host, *gb = &gbc;
+    int numQMFSlots = frame_length_short ? 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..fc64b1de4a 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -647,8 +647,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;
@@ -972,7 +971,8 @@  static void read_sbr_extension(AACContext *ac, 
SpectralBandReplication *sbr,
              skip_bits_long(gb, *num_bits_left); // bs_fill_bits
              *num_bits_left = 0;
          } else {
-            *num_bits_left -= ff_ps_read_data(ac->avctx, gb, 
&sbr->ps.common, *num_bits_left);
+            *num_bits_left -= ff_ps_read_data(ac->avctx, gb, 
&sbr->ps.common, *num_bits_left, + 
        ac->oc[1].m4ac.frame_length_short);
              ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
              // ensure the warning is not printed if PS extension is 
present
              ac->warned_he_aac_mono = 1;
@@ -1190,16 +1190,20 @@  static void sbr_qmf_analysis(AVFloatDSPContext 
*dsp, AVTXContext *mdct,
                               av_tx_fn mdct_fn,
  #endif /* USE_FIXED */
                               SBRDSPContext *sbrdsp, const INTFLOAT 
*in, INTFLOAT *x,
-                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx)
+                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx,
+                             int frame_length_short)
  {
      int i;
+    const int frameLength = frame_length_short ? 960 : 1024;
+    const int lp = frame_length_short ? 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
+    +    memcpy(x    , x+frameLength, (320-32)*sizeof(x[0]));
+    memcpy(x+288, in,         frameLength*sizeof(x[0]));
+    +    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);
@@ -1238,13 +1242,15 @@  static void sbr_qmf_synthesis(AVTXContext *mdct, 
av_tx_fn mdct_fn,
  #endif /* USE_FIXED */
                                INTFLOAT *out, INTFLOAT X[2][38][64],
                                INTFLOAT mdct_buf[2][64],
-                              INTFLOAT *v0, int *v_off, const unsigned 
int div)
+                              INTFLOAT *v0, int *v_off, const unsigned 
int div,
+                              int frame_length_short)
  {
      int i, n;
      const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : 
sbr_qmf_window_us;
      const int step = 128 >> div;
+    const int lp = frame_length_short ? 15*2 : 16*2;
      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));
@@ -1288,7 +1294,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++) {
@@ -1344,10 +1350,10 @@  static int sbr_hf_gen(AACContext *ac, 
SpectralBandReplication *sbr,
  /// Generate the subband filtered lowband
  static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
                       const INTFLOAT Y0[38][64][2], const INTFLOAT 
Y1[38][64][2],
-                     const INTFLOAT X_low[32][40][2], int ch)
+                     const INTFLOAT X_low[32][40][2], int ch, int 
frame_length_short)
  {
      int k, i;
-    const int i_f = 32;
+    const int i_f = frame_length_short ? 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++) {
@@ -1531,7 +1537,7 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
          sbr_qmf_analysis(ac->fdsp, sbr->mdct_ana, sbr->mdct_ana_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);
+                         sbr->data[ch].W, sbr->data[ch].Ypos, 
ac->oc[1].m4ac.frame_length_short);
          sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
                            (const INTFLOAT (*)[32][32][2]) sbr->data[ch].W,
                            sbr->data[ch].Ypos);
@@ -1564,12 +1570,13 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
          sbr->c.sbr_x_gen(sbr, sbr->X[ch],
                    (const INTFLOAT (*)[64][2]) 
sbr->data[ch].Y[1-sbr->data[ch].Ypos],
                    (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ 
sbr->data[ch].Ypos],
-                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch);
+                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch, 
ac->oc[1].m4ac.frame_length_short);
      }
       if (ac->oc[1].m4ac.ps == 1) {
          if (sbr->ps.common.start) {
-            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], 
sbr->X[1], sbr->kx[1] + sbr->m[1]);
+            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], 
sbr->X[1], sbr->kx[1] + sbr->m[1], + 
ac->oc[1].m4ac.frame_length_short);
          } else {
              memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0]));
          }
@@ -1580,13 +1587,13 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
                        L, sbr->X[0], sbr->qmf_filter_scratch,
                        sbr->data[0].synthesis_filterbank_samples,
                        &sbr->data[0].synthesis_filterbank_samples_offset,
-                      downsampled);
+                      downsampled, ac->oc[1].m4ac.frame_length_short);
      if (nch == 2)
          sbr_qmf_synthesis(sbr->mdct, sbr->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,
-                          downsampled);
+                          downsampled, ac->oc[1].m4ac.frame_length_short);
  }
   static void aacsbr_func_ptr_init(AACSBRContext *c)
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index f949465ef5..5a03b1597f 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -130,7 +130,7 @@  typedef struct AACSBRContext {
                              const int e_a[2]);
      int (*sbr_x_gen)(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
                       const INTFLOAT Y0[38][64][2], const INTFLOAT 
Y1[38][64][2],
-                     const INTFLOAT X_low[32][40][2], int ch);
+                     const INTFLOAT X_low[32][40][2], int ch, int 
frame_length_short);
      void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp,