diff options
author | Rostislav Pehlivanov <atomnuker@gmail.com> | 2017-02-11 00:25:06 +0000 |
---|---|---|
committer | Rostislav Pehlivanov <atomnuker@gmail.com> | 2017-02-14 06:15:36 +0000 |
commit | e538108c219d7b3628a9ec33d85bf252ee70c957 (patch) | |
tree | 796c62422dbc5f3e555d84ce57557729c7a8c900 /libavcodec/opus_celt.h | |
parent | d2119f624d392f53f80c3d36ffaadca23aef8a10 (diff) | |
download | ffmpeg-e538108c219d7b3628a9ec33d85bf252ee70c957.tar.gz |
opus_celt: move quantization and band decoding to opus_pvq.c
A huge amount can be reused by the encoder, as the only thing
which needs to be done would be to add a 10 line celt_icwrsi,
a wrapper around it (celt_alg_quant) and templating the
ff_celt_decode_band to replace entropy decoding functions
with entropy encoding.
There is no performance loss but in fact a performance gain of
around 6% which is caused by the compiler being able to optimize
the decoding more efficiently.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Diffstat (limited to 'libavcodec/opus_celt.h')
-rw-r--r-- | libavcodec/opus_celt.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h new file mode 100644 index 0000000000..e9b5946642 --- /dev/null +++ b/libavcodec/opus_celt.h @@ -0,0 +1,133 @@ +/* + * Opus decoder/demuxer common functions + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_OPUS_CELT_H +#define AVCODEC_OPUS_CELT_H + +#include "opus.h" + +#include "mdct15.h" +#include "libavutil/float_dsp.h" +#include "libavutil/libm.h" + +#define CELT_VECTORS 11 +#define CELT_ALLOC_STEPS 6 +#define CELT_FINE_OFFSET 21 +#define CELT_MAX_FINE_BITS 8 +#define CELT_NORM_SCALE 16384 +#define CELT_QTHETA_OFFSET 4 +#define CELT_QTHETA_OFFSET_TWOPHASE 16 +#define CELT_DEEMPH_COEFF 0.85000610f +#define CELT_POSTFILTER_MINPERIOD 15 +#define CELT_ENERGY_SILENCE (-28.0f) + +enum CeltSpread { + CELT_SPREAD_NONE, + CELT_SPREAD_LIGHT, + CELT_SPREAD_NORMAL, + CELT_SPREAD_AGGRESSIVE +}; + +typedef struct CeltFrame { + float energy[CELT_MAX_BANDS]; + float prev_energy[2][CELT_MAX_BANDS]; + + uint8_t collapse_masks[CELT_MAX_BANDS]; + + /* buffer for mdct output + postfilter */ + DECLARE_ALIGNED(32, float, buf)[2048]; + + /* postfilter parameters */ + int pf_period_new; + float pf_gains_new[3]; + int pf_period; + float pf_gains[3]; + int pf_period_old; + float pf_gains_old[3]; + + float deemph_coeff; +} CeltFrame; + +struct CeltContext { + // constant values that do not change during context lifetime + AVCodecContext *avctx; + MDCT15Context *imdct[4]; + AVFloatDSPContext *dsp; + int output_channels; + + // values that have inter-frame effect and must be reset on flush + CeltFrame frame[2]; + uint32_t seed; + int flushed; + + // values that only affect a single frame + int coded_channels; + int framebits; + int duration; + + /* number of iMDCT blocks in the frame */ + int blocks; + /* size of each block */ + int blocksize; + + int startband; + int endband; + int codedbands; + + int anticollapse_bit; + + int intensitystereo; + int dualstereo; + enum CeltSpread spread; + + int remaining; + int remaining2; + int fine_bits [CELT_MAX_BANDS]; + int fine_priority[CELT_MAX_BANDS]; + int pulses [CELT_MAX_BANDS]; + int tf_change [CELT_MAX_BANDS]; + + DECLARE_ALIGNED(32, float, coeffs)[2][CELT_MAX_FRAME_SIZE]; + DECLARE_ALIGNED(32, float, scratch)[22 * 8]; // MAX(ff_celt_freq_range) * 1<<CELT_MAX_LOG_BLOCKS +}; + +/* LCG for noise generation */ +static av_always_inline uint32_t celt_rng(CeltContext *s) +{ + s->seed = 1664525 * s->seed + 1013904223; + return s->seed; +} + +static av_always_inline void celt_renormalize_vector(float *X, int N, float gain) +{ + int i; + float g = 1e-15f; + for (i = 0; i < N; i++) + g += X[i] * X[i]; + g = gain / sqrtf(g); + + for (i = 0; i < N; i++) + X[i] *= g; +} + +#endif /* AVCODEC_OPUS_CELT_H */ |