mirror of https://git.ffmpeg.org/ffmpeg.git
imc: convert to lavu/tx, remove NIH iMDCT and replace with a standard one
This commit is contained in:
parent
b85e106d5f
commit
e6afa61be9
|
@ -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"
|
||||
|
|
100
libavcodec/imc.c
100
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,7 +997,7 @@ static int imc_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||
}
|
||||
|
||||
if (avctx->ch_layout.nb_channels == 2) {
|
||||
q->butterflies_float((float *)frame->extended_data[0],
|
||||
q->fdsp->butterflies_float((float *)frame->extended_data[0],
|
||||
(float *)frame->extended_data[1], COEFFS);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue