summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2022-11-05 11:35:59 +0100
committerLynne <dev@lynne.ee>2022-11-06 14:39:42 +0100
commite6afa61be97674312e36c9b6f8bb5fba009232e7 (patch)
tree7ab3ec19ccdf970b007cddf77d3ec2f0cf701ad9
parentb85e106d5fe652e9b93b3b14d32bab93cf88a668 (diff)
imc: convert to lavu/tx, remove NIH iMDCT and replace with a standard one
-rwxr-xr-xconfigure2
-rw-r--r--libavcodec/imc.c102
-rw-r--r--tests/fate/audio.mak1
3 files changed, 25 insertions, 80 deletions
diff --git a/configure b/configure
index 590a260e52..52c61e62b2 100755
--- a/configure
+++ b/configure
@@ -2850,7 +2850,7 @@ huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
hymt_decoder_select="huffyuv_decoder"
iac_decoder_select="imc_decoder"
-imc_decoder_select="bswapdsp fft mdct sinewin"
+imc_decoder_select="bswapdsp sinewin"
imm4_decoder_select="bswapdsp idctdsp"
imm5_decoder_select="h264_decoder hevc_decoder"
indeo3_decoder_select="hpeldsp"
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 92f9980ded..174332de4d 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -40,13 +40,13 @@
#include "libavutil/internal.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"
+#include "libavutil/tx.h"
#include "avcodec.h"
#include "bswapdsp.h"
#include "codec_internal.h"
#include "decode.h"
#include "get_bits.h"
-#include "fft.h"
#include "sinewin.h"
#include "imcdata.h"
@@ -64,7 +64,7 @@ typedef struct IMCChannel {
float flcoeffs4[BANDS];
float flcoeffs5[BANDS];
float flcoeffs6[BANDS];
- float CWdecoded[COEFFS];
+ DECLARE_ALIGNED(32, float, CWdecoded)[COEFFS];
int bandWidthT[BANDS]; ///< codewords per band
int bitsBandT[BANDS]; ///< how many bits per codeword in band
@@ -78,31 +78,25 @@ typedef struct IMCChannel {
int skipFlags[COEFFS]; ///< skip coefficient decoding or not
int codewords[COEFFS]; ///< raw codewords read from bitstream
- float last_fft_im[COEFFS];
-
int decoder_reset;
+ DECLARE_ALIGNED(32, float, prev_win)[128];
} IMCChannel;
typedef struct IMCContext {
IMCChannel chctx[2];
/** MDCT tables */
- //@{
- float mdct_sine_window[COEFFS];
- float post_cos[COEFFS];
- float post_sin[COEFFS];
- float pre_coef1[COEFFS];
- float pre_coef2[COEFFS];
- //@}
+ DECLARE_ALIGNED(32, float, mdct_sine_window)[COEFFS];
float sqrt_tab[30];
GetBitContext gb;
+ AVFloatDSPContext *fdsp;
BswapDSPContext bdsp;
- void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
- FFTContext fft;
- DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
+ AVTXContext *mdct;
+ av_tx_fn mdct_fn;
float *out_samples;
+ DECLARE_ALIGNED(32, float, temp)[256];
int coef0_pos;
@@ -196,8 +190,7 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
int i, j, ret;
IMCContext *q = avctx->priv_data;
static AVOnce init_static_once = AV_ONCE_INIT;
- AVFloatDSPContext *fdsp;
- double r1, r2;
+ float scale = 1.0f / (16384);
if (avctx->codec_id == AV_CODEC_ID_IAC && avctx->sample_rate > 96000) {
av_log(avctx, AV_LOG_ERROR,
@@ -222,33 +215,14 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
for (i = 0; i < BANDS; i++)
q->chctx[j].old_floor[i] = 1.0;
-
- for (i = 0; i < COEFFS / 2; i++)
- q->chctx[j].last_fft_im[i] = 0;
}
/* Build mdct window, a simple sine window normalized with sqrt(2) */
ff_sine_window_init(q->mdct_sine_window, COEFFS);
for (i = 0; i < COEFFS; i++)
q->mdct_sine_window[i] *= sqrt(2.0);
- for (i = 0; i < COEFFS / 2; i++) {
- q->post_cos[i] = (1.0f / 32768) * cos(i / 256.0 * M_PI);
- q->post_sin[i] = (1.0f / 32768) * sin(i / 256.0 * M_PI);
-
- r1 = sin((i * 4.0 + 1.0) / 1024.0 * M_PI);
- r2 = cos((i * 4.0 + 1.0) / 1024.0 * M_PI);
-
- if (i & 0x1) {
- q->pre_coef1[i] = (r1 + r2) * sqrt(2.0);
- q->pre_coef2[i] = -(r1 - r2) * sqrt(2.0);
- } else {
- q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0);
- q->pre_coef2[i] = (r1 - r2) * sqrt(2.0);
- }
- }
/* Generate a square root table */
-
for (i = 0; i < 30; i++)
q->sqrt_tab[i] = sqrt(i);
@@ -261,15 +235,14 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
memcpy(q->weights2, imc_weights2, sizeof(imc_weights2));
}
- fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
- if (!fdsp)
+ q->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+ if (!q->fdsp)
return AVERROR(ENOMEM);
- q->butterflies_float = fdsp->butterflies_float;
- av_free(fdsp);
- if ((ret = ff_fft_init(&q->fft, 7, 1))) {
- av_log(avctx, AV_LOG_INFO, "FFT init failed\n");
+
+ ret = av_tx_init(&q->mdct, &q->mdct_fn, AV_TX_FLOAT_MDCT, 1, COEFFS, &scale, 0);
+ if (ret < 0)
return ret;
- }
+
ff_bswapdsp_init(&q->bdsp);
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
@@ -726,39 +699,6 @@ static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx,
}
}
-static void imc_imdct256(IMCContext *q, IMCChannel *chctx, int channels)
-{
- int i;
- float re, im;
- float *dst1 = q->out_samples;
- float *dst2 = q->out_samples + (COEFFS - 1);
-
- /* prerotation */
- for (i = 0; i < COEFFS / 2; i++) {
- q->samples[i].re = -(q->pre_coef1[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
- (q->pre_coef2[i] * chctx->CWdecoded[i * 2]);
- q->samples[i].im = (q->pre_coef2[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) -
- (q->pre_coef1[i] * chctx->CWdecoded[i * 2]);
- }
-
- /* FFT */
- q->fft.fft_permute(&q->fft, q->samples);
- q->fft.fft_calc(&q->fft, q->samples);
-
- /* postrotation, window and reorder */
- for (i = 0; i < COEFFS / 2; i++) {
- re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]);
- im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]);
- *dst1 = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i])
- + (q->mdct_sine_window[i * 2] * re);
- *dst2 = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i])
- - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re);
- dst1 += 2;
- dst2 -= 2;
- chctx->last_fft_im[i] = im;
- }
-}
-
static int inverse_quant_coeff(IMCContext *q, IMCChannel *chctx,
int stream_format_code)
{
@@ -1012,7 +952,10 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags));
- imc_imdct256(q, chctx, avctx->ch_layout.nb_channels);
+ q->mdct_fn(q->mdct, q->temp, chctx->CWdecoded, sizeof(float));
+ q->fdsp->vector_fmul_window(q->out_samples, chctx->prev_win, q->temp,
+ q->mdct_sine_window, 128);
+ memcpy(chctx->prev_win, q->temp + 128, sizeof(float)*128);
return 0;
}
@@ -1054,8 +997,8 @@ static int imc_decode_frame(AVCodecContext *avctx, AVFrame *frame,
}
if (avctx->ch_layout.nb_channels == 2) {
- q->butterflies_float((float *)frame->extended_data[0],
- (float *)frame->extended_data[1], COEFFS);
+ q->fdsp->butterflies_float((float *)frame->extended_data[0],
+ (float *)frame->extended_data[1], COEFFS);
}
*got_frame_ptr = 1;
@@ -1067,7 +1010,8 @@ static av_cold int imc_decode_close(AVCodecContext * avctx)
{
IMCContext *q = avctx->priv_data;
- ff_fft_end(&q->fft);
+ av_free(q->fdsp);
+ av_tx_uninit(&q->mdct);
return 0;
}
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index 9d39eeace3..5d754b1568 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -43,6 +43,7 @@ fate-dsf-dst: REF = $(SAMPLES)/dst/dst-64fs44-2ch.pcm
FATE_SAMPLES_AUDIO-$(call DEMDEC, AVI, IMC) += fate-imc
fate-imc: CMD = pcm -i $(TARGET_SAMPLES)/imc/imc.avi
fate-imc: CMP = oneoff
+fate-imc: CMP_TARGET = 59416
fate-imc: REF = $(SAMPLES)/imc/imc-201706.pcm
FATE_SAMPLES_AUDIO-$(call DEMDEC, FLV, NELLYMOSER) += fate-nellymoser