[FFmpeg-cvslog] imc: convert to lavu/tx, remove NIH iMDCT and replace with a standard one

Lynne git at videolan.org
Sun Nov 6 15:42:06 EET 2022


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sat Nov  5 11:35:59 2022 +0100| [e6afa61be97674312e36c9b6f8bb5fba009232e7] | committer: Lynne

imc: convert to lavu/tx, remove NIH iMDCT and replace with a standard one

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e6afa61be97674312e36c9b6f8bb5fba009232e7
---

 configure            |   2 +-
 libavcodec/imc.c     | 102 ++++++++++++---------------------------------------
 tests/fate/audio.mak |   1 +
 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



More information about the ffmpeg-cvslog mailing list