[FFmpeg-devel] [PATCH v3 05/10] aacdec_dsp: implement 768-point transform and windowing

Lynne dev at lynne.ee
Sat May 25 05:27:58 EEST 2024


Required for USAC
---
 libavcodec/aac/aacdec.c              |  4 ++
 libavcodec/aac/aacdec.h              |  5 +++
 libavcodec/aac/aacdec_dsp_template.c | 67 ++++++++++++++++++++++++++++
 libavcodec/aac/aacdec_fixed.c        |  2 +
 libavcodec/aac/aacdec_float.c        |  4 ++
 libavcodec/sinewin_fixed_tablegen.c  |  2 +
 libavcodec/sinewin_fixed_tablegen.h  |  4 ++
 7 files changed, 88 insertions(+)

diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c
index a7e5b2a369..6f37ac5361 100644
--- a/libavcodec/aac/aacdec.c
+++ b/libavcodec/aac/aacdec.c
@@ -1113,10 +1113,12 @@ static av_cold int decode_close(AVCodecContext *avctx)
         }
     }
 
+    av_tx_uninit(&ac->mdct96);
     av_tx_uninit(&ac->mdct120);
     av_tx_uninit(&ac->mdct128);
     av_tx_uninit(&ac->mdct480);
     av_tx_uninit(&ac->mdct512);
+    av_tx_uninit(&ac->mdct768);
     av_tx_uninit(&ac->mdct960);
     av_tx_uninit(&ac->mdct1024);
     av_tx_uninit(&ac->mdct_ltp);
@@ -1145,10 +1147,12 @@ static av_cold int init_dsp(AVCodecContext *avctx)
     if (ret < 0)                                                             \
         return ret
 
+    MDCT_INIT(ac->mdct96,   ac->mdct96_fn,     96, 1.0/96);
     MDCT_INIT(ac->mdct120,  ac->mdct120_fn,   120, 1.0/120);
     MDCT_INIT(ac->mdct128,  ac->mdct128_fn,   128, 1.0/128);
     MDCT_INIT(ac->mdct480,  ac->mdct480_fn,   480, 1.0/480);
     MDCT_INIT(ac->mdct512,  ac->mdct512_fn,   512, 1.0/512);
+    MDCT_INIT(ac->mdct768,  ac->mdct768_fn,   768, 1.0/768);
     MDCT_INIT(ac->mdct960,  ac->mdct960_fn,   960, 1.0/960);
     MDCT_INIT(ac->mdct1024, ac->mdct1024_fn, 1024, 1.0/1024);
 #undef MDCT_INIT
diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index 499bd8eefc..8d1eb74066 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -245,6 +245,7 @@ typedef struct AACDecDSP {
                                        ChannelElement *cce, int index);
 
     void (*imdct_and_windowing)(AACDecContext *ac, SingleChannelElement *sce);
+    void (*imdct_and_windowing_768)(AACDecContext *ac, SingleChannelElement *sce);
     void (*imdct_and_windowing_960)(AACDecContext *ac, SingleChannelElement *sce);
     void (*imdct_and_windowing_ld)(AACDecContext *ac, SingleChannelElement *sce);
     void (*imdct_and_windowing_eld)(AACDecContext *ac, SingleChannelElement *sce);
@@ -290,18 +291,22 @@ struct AACDecContext {
      * @name Computed / set up during initialization
      * @{
      */
+    AVTXContext *mdct96;
     AVTXContext *mdct120;
     AVTXContext *mdct128;
     AVTXContext *mdct480;
     AVTXContext *mdct512;
+    AVTXContext *mdct768;
     AVTXContext *mdct960;
     AVTXContext *mdct1024;
     AVTXContext *mdct_ltp;
 
+    av_tx_fn mdct96_fn;
     av_tx_fn mdct120_fn;
     av_tx_fn mdct128_fn;
     av_tx_fn mdct480_fn;
     av_tx_fn mdct512_fn;
+    av_tx_fn mdct768_fn;
     av_tx_fn mdct960_fn;
     av_tx_fn mdct1024_fn;
     av_tx_fn mdct_ltp_fn;
diff --git a/libavcodec/aac/aacdec_dsp_template.c b/libavcodec/aac/aacdec_dsp_template.c
index e69970472c..59a69d88f3 100644
--- a/libavcodec/aac/aacdec_dsp_template.c
+++ b/libavcodec/aac/aacdec_dsp_template.c
@@ -383,6 +383,71 @@ static void AAC_RENAME(imdct_and_windowing)(AACDecContext *ac, SingleChannelElem
     }
 }
 
+/**
+ * Conduct IMDCT and windowing for 768-point frames.
+ */
+static void AAC_RENAME(imdct_and_windowing_768)(AACDecContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
+    INTFLOAT *out   = sce->AAC_RENAME(output);
+    INTFLOAT *saved = sce->AAC_RENAME(saved);
+    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_96) : AAC_RENAME(sine_96);
+    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_768) : AAC_RENAME(sine_768);
+    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_96) : AAC_RENAME(sine_96);
+    INTFLOAT *buf  = ac->AAC_RENAME(buf_mdct);
+    INTFLOAT *temp = ac->AAC_RENAME(temp);
+    int i;
+
+    // imdct
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        for (i = 0; i < 8; i++)
+            ac->mdct96_fn(ac->mdct96, buf + i * 96, in + i * 96, sizeof(INTFLOAT));
+    } else {
+        ac->mdct768_fn(ac->mdct768, buf, in, sizeof(INTFLOAT));
+    }
+
+    /* window overlapping
+     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+     * and long to short transitions are considered to be short to short
+     * transitions. This leaves just two cases (long to long and short to short)
+     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+     */
+
+    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+        (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+        ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 384);
+    } else {
+        memcpy(                          out,               saved,            336 * sizeof(*out));
+
+        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+            ac->fdsp->vector_fmul_window(out + 336 + 0*96, saved + 336,     buf + 0*96, swindow_prev, 48);
+            ac->fdsp->vector_fmul_window(out + 336 + 1*96, buf + 0*96 + 48, buf + 1*96, swindow,      48);
+            ac->fdsp->vector_fmul_window(out + 336 + 2*96, buf + 1*96 + 48, buf + 2*96, swindow,      48);
+            ac->fdsp->vector_fmul_window(out + 336 + 3*96, buf + 2*96 + 48, buf + 3*96, swindow,      48);
+            ac->fdsp->vector_fmul_window(temp,             buf + 3*96 + 48, buf + 4*96, swindow,      48);
+            memcpy(                      out + 336 + 4*96, temp, 48 * sizeof(*out));
+        } else {
+            ac->fdsp->vector_fmul_window(out + 336,        saved + 336,     buf,        swindow_prev, 48);
+            memcpy(                      out + 432,        buf + 48,        336 * sizeof(*out));
+        }
+    }
+
+    // buffer update
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        memcpy(                      saved,       temp + 48,         48 * sizeof(*saved));
+        ac->fdsp->vector_fmul_window(saved + 48,  buf + 4*96 + 48, buf + 5*96, swindow, 48);
+        ac->fdsp->vector_fmul_window(saved + 144, buf + 5*96 + 48, buf + 6*96, swindow, 48);
+        ac->fdsp->vector_fmul_window(saved + 240, buf + 6*96 + 48, buf + 7*96, swindow, 48);
+        memcpy(                      saved + 336, buf + 7*96 + 48,  48 * sizeof(*saved));
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        memcpy(                      saved,       buf + 384,       336 * sizeof(*saved));
+        memcpy(                      saved + 336, buf + 7*96 + 48,  48 * sizeof(*saved));
+    } else { // LONG_STOP or ONLY_LONG
+        memcpy(                      saved,       buf + 384,       384 * sizeof(*saved));
+    }
+}
+
 /**
  * Conduct IMDCT and windowing.
  */
@@ -447,6 +512,7 @@ static void AAC_RENAME(imdct_and_windowing_960)(AACDecContext *ac, SingleChannel
         memcpy(                      saved,       buf + 480,        480 * sizeof(*saved));
     }
 }
+
 static void AAC_RENAME(imdct_and_windowing_ld)(AACDecContext *ac, SingleChannelElement *sce)
 {
     IndividualChannelStream *ics = &sce->ics;
@@ -609,6 +675,7 @@ static av_cold void AAC_RENAME(aac_dsp_init)(AACDecDSP *aac_dsp)
     SET(apply_prediction);
 
     SET(imdct_and_windowing);
+    SET(imdct_and_windowing_768);
     SET(imdct_and_windowing_960);
     SET(imdct_and_windowing_ld);
     SET(imdct_and_windowing_eld);
diff --git a/libavcodec/aac/aacdec_fixed.c b/libavcodec/aac/aacdec_fixed.c
index de90880884..89f1ea0384 100644
--- a/libavcodec/aac/aacdec_fixed.c
+++ b/libavcodec/aac/aacdec_fixed.c
@@ -47,6 +47,8 @@ DECLARE_ALIGNED(32, static int, aac_kbd_long_1024_fixed)[1024];
 DECLARE_ALIGNED(32, static int, aac_kbd_short_128_fixed)[128];
 DECLARE_ALIGNED(32, static int, aac_kbd_long_960_fixed)[960];
 DECLARE_ALIGNED(32, static int, aac_kbd_short_120_fixed)[120];
+DECLARE_ALIGNED(32, static int, aac_kbd_long_768_fixed)[768];
+DECLARE_ALIGNED(32, static int, aac_kbd_short_96_fixed)[96];
 
 static void init_tables_fixed_fn(void)
 {
diff --git a/libavcodec/aac/aacdec_float.c b/libavcodec/aac/aacdec_float.c
index 03ec264c50..14169e95d8 100644
--- a/libavcodec/aac/aacdec_float.c
+++ b/libavcodec/aac/aacdec_float.c
@@ -44,10 +44,14 @@
 #include "libavutil/mathematics.h"
 #include "libavcodec/aacsbr.h"
 
+DECLARE_ALIGNED(32, static float, sine_96)[96];
 DECLARE_ALIGNED(32, static float, sine_120)[120];
+DECLARE_ALIGNED(32, static float, sine_768)[768];
 DECLARE_ALIGNED(32, static float, sine_960)[960];
 DECLARE_ALIGNED(32, static float, aac_kbd_long_960)[960];
 DECLARE_ALIGNED(32, static float, aac_kbd_short_120)[120];
+DECLARE_ALIGNED(32, static float, aac_kbd_long_768)[768];
+DECLARE_ALIGNED(32, static float, aac_kbd_short_96)[96];
 
 static void init_tables_float_fn(void)
 {
diff --git a/libavcodec/sinewin_fixed_tablegen.c b/libavcodec/sinewin_fixed_tablegen.c
index 15f0cc2072..86e9dfb1e7 100644
--- a/libavcodec/sinewin_fixed_tablegen.c
+++ b/libavcodec/sinewin_fixed_tablegen.c
@@ -35,10 +35,12 @@ int main(void)
     printf("SINETABLE("#size") = {\n");                 \
     write_int32_t_array(sine_ ## size ## _fixed, size); \
     printf("};\n")
+    PRINT_TABLE(96);
     PRINT_TABLE(120);
     PRINT_TABLE(128);
     PRINT_TABLE(480);
     PRINT_TABLE(512);
+    PRINT_TABLE(768);
     PRINT_TABLE(960);
     PRINT_TABLE(1024);
     return 0;
diff --git a/libavcodec/sinewin_fixed_tablegen.h b/libavcodec/sinewin_fixed_tablegen.h
index 056735704c..660c0056b5 100644
--- a/libavcodec/sinewin_fixed_tablegen.h
+++ b/libavcodec/sinewin_fixed_tablegen.h
@@ -44,10 +44,12 @@
 #include "libavutil/attributes.h"
 
 #define SINETABLE_CONST
+SINETABLE( 96);
 SINETABLE( 120);
 SINETABLE( 128);
 SINETABLE( 480);
 SINETABLE( 512);
+SINETABLE( 768);
 SINETABLE( 960);
 SINETABLE(1024);
 
@@ -62,10 +64,12 @@ static av_cold void sine_window_init_fixed(int *window, int n)
 
 static av_cold void init_sine_windows_fixed(void)
 {
+    sine_window_init_fixed(sine_96_fixed,   96);
     sine_window_init_fixed(sine_120_fixed,  120);
     sine_window_init_fixed(sine_128_fixed,  128);
     sine_window_init_fixed(sine_480_fixed,  480);
     sine_window_init_fixed(sine_512_fixed,  512);
+    sine_window_init_fixed(sine_768_fixed,  768);
     sine_window_init_fixed(sine_960_fixed,  960);
     sine_window_init_fixed(sine_1024_fixed, 1024);
 }
-- 
2.43.0.381.gb435a96ce8


More information about the ffmpeg-devel mailing list