summaryrefslogtreecommitdiff
path: root/libavcodec/opus_celt.h
diff options
context:
space:
mode:
authorRostislav Pehlivanov <atomnuker@gmail.com>2017-02-11 00:25:06 +0000
committerRostislav Pehlivanov <atomnuker@gmail.com>2017-02-14 06:15:36 +0000
commite538108c219d7b3628a9ec33d85bf252ee70c957 (patch)
tree796c62422dbc5f3e555d84ce57557729c7a8c900 /libavcodec/opus_celt.h
parentd2119f624d392f53f80c3d36ffaadca23aef8a10 (diff)
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.h133
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 */