[FFmpeg-devel] [PATCH 4/8] aacdec_dsp: implement 768-point transform and windowing
Lynne
dev at lynne.ee
Thu May 16 13:08:14 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 303e285c81..20545a24d4 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