1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

aacdec_dsp: implement 768-point transform and windowing

Required for USAC
This commit is contained in:
Lynne 2024-03-25 06:13:38 +01:00
parent f8543f3763
commit 0513c5cd25
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
7 changed files with 88 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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;

View File

@ -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);
}