* [FFmpeg-devel] [PATCH 7/9] avcodec/opus_rc: Split de/encoder-only parts off OpusRangeContext
2022-10-07 20:20 [FFmpeg-devel] [PATCH 1/9] avcodec/opus_rc: Remove write-only waste from OpusRangeCoder Andreas Rheinhardt
` (4 preceding siblings ...)
2022-10-07 20:25 ` [FFmpeg-devel] [PATCH 6/9] avcodec/opus_pvq: Don't build ppp_pvq_search_c when unused Andreas Rheinhardt
@ 2022-10-07 20:25 ` Andreas Rheinhardt
2022-10-07 20:25 ` [FFmpeg-devel] [PATCH 8/9] avcodec/opus: Rename opus.c->opus_celt.c, opus_celt.c->opusdec_celt.c Andreas Rheinhardt
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Andreas Rheinhardt @ 2022-10-07 20:25 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Andreas Rheinhardt
The decoder currently only uses 72 bytes of 1376; furthermore,
the GetBitContext in OpusRangeCoder is unused by the encoder,
but its existence adds an unnecessary inclusion of get_bits.h
to the encoder-only files. So split OpusRangeContext;
also split opus_rc.c into an encoder- and a decoder-only part.
This necessitated trivial changes in several other files.
The only part where the changes where these changes were involved
was opus_pvq.c, where the quant_band functions are now defined
in a template file instead of being created via an av_always_inline
function.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/Makefile | 8 +-
libavcodec/opus.c | 62 ++++-
libavcodec/opus_celt.c | 39 +--
libavcodec/opus_celt.h | 3 +-
libavcodec/opus_pvq.c | 456 +++------------------------------
libavcodec/opus_pvq_template.c | 432 +++++++++++++++++++++++++++++++
libavcodec/opus_rc.c | 409 -----------------------------
libavcodec/opus_rc.h | 66 ++---
libavcodec/opus_silk.c | 11 +-
libavcodec/opus_silk.h | 4 +-
libavcodec/opusdec.c | 11 +-
libavcodec/opusdec_rc.c | 214 ++++++++++++++++
libavcodec/opusdec_rc.h | 53 ++++
libavcodec/opusenc.c | 39 +--
libavcodec/opusenc_psy.c | 14 +-
libavcodec/opusenc_psy.h | 1 +
libavcodec/opusenc_rc.c | 210 +++++++++++++++
libavcodec/opusenc_rc.h | 64 +++++
18 files changed, 1139 insertions(+), 957 deletions(-)
create mode 100644 libavcodec/opus_pvq_template.c
delete mode 100644 libavcodec/opus_rc.c
create mode 100644 libavcodec/opusdec_rc.c
create mode 100644 libavcodec/opusdec_rc.h
create mode 100644 libavcodec/opusenc_rc.c
create mode 100644 libavcodec/opusenc_rc.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 592d9347f6..b7eb3b1e48 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -554,11 +554,11 @@ OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.o
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
-OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \
+OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o \
opus_pvq.o opus_silk.o opustab.o vorbis_data.o \
- opusdsp.o opus_parse.o
-OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opus_rc.o opustab.o opus_pvq.o \
- opusenc_psy.o
+ opusdec_rc.o opusdsp.o opus_parse.o
+OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opusenc_psy.o \
+ opusenc_rc.o opustab.o opus_pvq.o
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o
diff --git a/libavcodec/opus.c b/libavcodec/opus.c
index a24c38be52..8def5e6e34 100644
--- a/libavcodec/opus.c
+++ b/libavcodec/opus.c
@@ -21,9 +21,45 @@
#include <stdint.h>
+#include "config_components.h"
#include "opus_celt.h"
#include "opus_pvq.h"
#include "opustab.h"
+#include "opus_rc.h"
+#include "opusdec_rc.h"
+#include "opusenc_rc.h"
+
+#if !CONFIG_OPUS_ENCODER
+#define ff_opus_rc_enc_log(...)
+#define ff_opus_rc_enc_cdf(...)
+#define ff_opus_rc_enc_uint(...)
+#endif
+
+#if !CONFIG_OPUS_DECODER
+#define ff_opus_rc_dec_log(...) 0
+#define ff_opus_rc_dec_cdf(...) 0
+#define ff_opus_rc_dec_uint(...) 0
+#endif
+
+static inline void opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits)
+{
+ ff_opus_rc_enc_log((OpusEncRangeCoder*)rc, val, bits);
+}
+
+static inline uint32_t opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits)
+{
+ return ff_opus_rc_dec_log((OpusDecRangeCoder*)rc, bits);
+}
+
+static inline void opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf)
+{
+ ff_opus_rc_enc_cdf((OpusEncRangeCoder*)rc, val, cdf);
+}
+
+static inline uint32_t opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf)
+{
+ return ff_opus_rc_dec_cdf((OpusDecRangeCoder*)rc, cdf);
+}
void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc)
{
@@ -150,12 +186,14 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
int bits1[CELT_MAX_BANDS];
int bits2[CELT_MAX_BANDS];
+ if (!CONFIG_OPUS_DECODER || !CONFIG_OPUS_ENCODER)
+ encode = CONFIG_OPUS_ENCODER;
/* Spread */
if (opus_rc_tell(rc) + 4 <= f->framebits) {
if (encode)
- ff_opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread);
+ opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread);
else
- f->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread);
+ f->spread = opus_rc_dec_cdf(rc, ff_celt_model_spread);
} else {
f->spread = CELT_SPREAD_NORMAL;
}
@@ -176,9 +214,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
int is_boost;
if (encode) {
is_boost = boost_amount--;
- ff_opus_rc_enc_log(rc, is_boost, b_dynalloc);
+ opus_rc_enc_log(rc, is_boost, b_dynalloc);
} else {
- is_boost = ff_opus_rc_dec_log(rc, b_dynalloc);
+ is_boost = opus_rc_dec_log(rc, b_dynalloc);
}
if (!is_boost)
@@ -199,9 +237,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
f->alloc_trim = 5;
if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths)
if (encode)
- ff_opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim);
+ opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim);
else
- f->alloc_trim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
+ f->alloc_trim = opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
/* Anti-collapse bit reservation */
tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1;
@@ -358,9 +396,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
int do_not_skip;
if (encode) {
do_not_skip = f->coded_bands <= f->skip_band_floor;
- ff_opus_rc_enc_log(rc, do_not_skip, 1);
+ opus_rc_enc_log(rc, do_not_skip, 1);
} else {
- do_not_skip = ff_opus_rc_dec_log(rc, 1);
+ do_not_skip = opus_rc_dec_log(rc, 1);
}
if (do_not_skip)
@@ -385,12 +423,12 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
if (encode) {
if (intensitystereo_bit) {
f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands);
- ff_opus_rc_enc_uint(rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band);
+ ff_opus_rc_enc_uint((OpusEncRangeCoder*)rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band);
}
} else {
f->intensity_stereo = f->dual_stereo = 0;
if (intensitystereo_bit)
- f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint(rc, f->coded_bands + 1 - f->start_band);
+ f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint((OpusDecRangeCoder*)rc, f->coded_bands + 1 - f->start_band);
}
/* DS flag */
@@ -398,9 +436,9 @@ void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */
else if (dualstereo_bit)
if (encode)
- ff_opus_rc_enc_log(rc, f->dual_stereo, 1);
+ opus_rc_enc_log(rc, f->dual_stereo, 1);
else
- f->dual_stereo = ff_opus_rc_dec_log(rc, 1);
+ f->dual_stereo = opus_rc_dec_log(rc, 1);
/* Supply the remaining bits in this frame to lower bands */
remaining = tbits_8ths - total;
diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
index c2904cc9e0..a14764ec18 100644
--- a/libavcodec/opus_celt.c
+++ b/libavcodec/opus_celt.c
@@ -28,12 +28,13 @@
#include <float.h>
#include "opus_celt.h"
+#include "opusdec_rc.h"
#include "opustab.h"
#include "opus_pvq.h"
/* Use the 2D z-transform to apply prediction in both the time domain (alpha)
* and the frequency domain (beta) */
-static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_decode_coarse_energy(CeltFrame *f, OpusDecRangeCoder *rc)
{
int i, j;
float prev[2] = { 0 };
@@ -42,7 +43,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0];
/* intra frame */
- if (opus_rc_tell(rc) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
+ if (opus_rc_tell(&rc->c) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
alpha = 0.0f;
beta = 1.0f - (4915.0f/32768.0f);
model = ff_celt_coarse_energy_dist[f->size][1];
@@ -59,7 +60,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
continue;
}
- available = f->framebits - opus_rc_tell(rc);
+ available = f->framebits - opus_rc_tell(&rc->c);
if (available >= 15) {
/* decode using a Laplace distribution */
int k = FFMIN(i, 20) << 1;
@@ -77,7 +78,7 @@ static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
}
}
-static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_decode_fine_energy(CeltFrame *f, OpusDecRangeCoder *rc)
{
int i;
for (i = f->start_band; i < f->end_band; i++) {
@@ -96,10 +97,10 @@ static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc)
}
}
-static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_decode_final_energy(CeltFrame *f, OpusDecRangeCoder *rc)
{
int priority, i, j;
- int bits_left = f->framebits - opus_rc_tell(rc);
+ int bits_left = f->framebits - opus_rc_tell(&rc->c);
for (priority = 0; priority < 2; priority++) {
for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) {
@@ -118,18 +119,18 @@ static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc)
}
}
-static void celt_decode_tf_changes(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_decode_tf_changes(CeltFrame *f, OpusDecRangeCoder *rc)
{
int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
int consumed, bits = f->transient ? 2 : 4;
- consumed = opus_rc_tell(rc);
+ consumed = opus_rc_tell(&rc->c);
tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits);
for (i = f->start_band; i < f->end_band; i++) {
if (consumed+bits+tf_select_bit <= f->framebits) {
diff ^= ff_opus_rc_dec_log(rc, bits);
- consumed = opus_rc_tell(rc);
+ consumed = opus_rc_tell(&rc->c);
tf_changed |= diff;
}
f->tf_change[i] = diff;
@@ -232,7 +233,7 @@ static void celt_postfilter(CeltFrame *f, CeltBlock *block)
memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
}
-static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
+static int parse_postfilter(CeltFrame *f, OpusDecRangeCoder *rc, int consumed)
{
int i;
@@ -248,7 +249,7 @@ static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
octave = ff_opus_rc_dec_uint(rc, 6);
period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1;
gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1);
- tapset = (opus_rc_tell(rc) + 2 <= f->framebits) ?
+ tapset = (opus_rc_tell(&rc->c) + 2 <= f->framebits) ?
ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;
for (i = 0; i < 2; i++) {
@@ -261,7 +262,7 @@ static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
}
}
- consumed = opus_rc_tell(rc);
+ consumed = opus_rc_tell(&rc->c);
}
return consumed;
@@ -319,7 +320,7 @@ static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
}
}
-int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
+int ff_celt_decode_frame(CeltFrame *f, OpusDecRangeCoder *rc,
float **output, int channels, int frame_size,
int start_band, int end_band)
{
@@ -346,7 +347,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
f->channels = channels;
f->start_band = start_band;
f->end_band = end_band;
- f->framebits = rc->rb.bytes * 8;
+ f->framebits = rc->c.rb.bytes * 8;
f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
if (f->size > CELT_MAX_LOG_BLOCKS ||
@@ -364,7 +365,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks));
}
- consumed = opus_rc_tell(rc);
+ consumed = opus_rc_tell(&rc->c);
/* obtain silence flag */
if (consumed >= f->framebits)
@@ -375,7 +376,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
if (f->silence) {
consumed = f->framebits;
- rc->total_bits += f->framebits - opus_rc_tell(rc);
+ rc->c.total_bits += f->framebits - opus_rc_tell(&rc->c);
}
/* obtain post-filter options */
@@ -398,9 +399,9 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
celt_decode_coarse_energy(f, rc);
celt_decode_tf_changes (f, rc);
- ff_celt_bitalloc (f, rc, 0);
+ ff_celt_bitalloc (f, &rc->c, 0);
celt_decode_fine_energy (f, rc);
- ff_celt_quant_bands (f, rc);
+ ff_celt_quant_bands (f, &rc->c);
if (f->anticollapse_needed)
f->anticollapse = ff_opus_rc_get_raw(rc, 1);
@@ -486,7 +487,7 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
}
}
- f->seed = rc->range;
+ f->seed = rc->c.range;
return 0;
}
diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h
index 2dbb79be6c..beb6abd55d 100644
--- a/libavcodec/opus_celt.h
+++ b/libavcodec/opus_celt.h
@@ -171,7 +171,8 @@ void ff_celt_free(CeltFrame **f);
void ff_celt_flush(CeltFrame *f);
-int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output,
+struct OpusDecRangeCoder;
+int ff_celt_decode_frame(CeltFrame *f, struct OpusDecRangeCoder *rc, float **output,
int coded_channels, int frame_size, int startband, int endband);
/* Encode or decode CELT bands */
diff --git a/libavcodec/opus_pvq.c b/libavcodec/opus_pvq.c
index d08dcd7413..8ef0f85a81 100644
--- a/libavcodec/opus_pvq.c
+++ b/libavcodec/opus_pvq.c
@@ -30,6 +30,9 @@
#include "mathops.h"
#include "opustab.h"
#include "opus_pvq.h"
+#include "opus_rc.h"
+#include "opusdec_rc.h"
+#include "opusenc_rc.h"
#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15)
@@ -355,18 +358,12 @@ static inline uint64_t celt_cwrsi(uint32_t N, uint32_t K, uint32_t i, int *y)
return norm;
}
-static inline void celt_encode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K)
+#if CONFIG_OPUS_ENCODER
+static inline void celt_encode_pulses(OpusEncRangeCoder *rc, int *y, uint32_t N, uint32_t K)
{
ff_opus_rc_enc_uint(rc, celt_icwrsi(N, K, y), CELT_PVQ_V(N, K));
}
-static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K)
-{
- const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K));
- return celt_cwrsi(N, K, idx, y);
-}
-
-#if CONFIG_OPUS_ENCODER
/*
* Faster than libopus's search, operates entirely in the signed domain.
* Slightly worse/better depending on N, K and the input vector.
@@ -419,9 +416,8 @@ static float ppp_pvq_search_c(float *X, int *y, int K, int N)
return (float)y_norm;
}
-#endif
-static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K,
+static uint32_t celt_alg_quant(OpusEncRangeCoder *rc, float *X, uint32_t N, uint32_t K,
enum CeltSpread spread, uint32_t blocks, float gain,
CeltPVQ *pvq)
{
@@ -434,10 +430,18 @@ static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_
celt_exp_rotation(X, N, blocks, K, spread, 0);
return celt_extract_collapse_mask(y, N, blocks);
}
+#endif
+
+#if CONFIG_OPUS_DECODER
+static inline float celt_decode_pulses(OpusDecRangeCoder *rc, int *y, uint32_t N, uint32_t K)
+{
+ const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K));
+ return celt_cwrsi(N, K, idx, y);
+}
/** Decode pulse vector and combine the result with the pitch vector to produce
the final normalised signal in the current band. */
-static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K,
+static uint32_t celt_alg_unquant(OpusDecRangeCoder *rc, float *X, uint32_t N, uint32_t K,
enum CeltSpread spread, uint32_t blocks, float gain,
CeltPVQ *pvq)
{
@@ -448,6 +452,7 @@ static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint3
celt_exp_rotation(X, N, blocks, K, spread, 0);
return celt_extract_collapse_mask(y, N, blocks);
}
+#endif
static int celt_calc_theta(const float *X, const float *Y, int coupling, int N)
{
@@ -467,6 +472,7 @@ static int celt_calc_theta(const float *X, const float *Y, int coupling, int N)
return lrintf(32768.0f*atan2f(sqrtf(e[1]), sqrtf(e[0]))/M_PI);
}
+#if CONFIG_OPUS_ENCODER
static void celt_stereo_is_decouple(float *X, float *Y, float e_l, float e_r, int N)
{
int i;
@@ -487,421 +493,15 @@ static void celt_stereo_ms_decouple(float *X, float *Y, int N)
}
}
-static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f,
- OpusRangeCoder *rc,
- const int band, float *X,
- float *Y, int N, int b,
- uint32_t blocks, float *lowband,
- int duration, float *lowband_out,
- int level, float gain,
- float *lowband_scratch,
- int fill, int quant)
-{
- int i;
- const uint8_t *cache;
- int stereo = !!Y, split = stereo;
- int imid = 0, iside = 0;
- uint32_t N0 = N;
- int N_B = N / blocks;
- int N_B0 = N_B;
- int B0 = blocks;
- int time_divide = 0;
- int recombine = 0;
- int inv = 0;
- float mid = 0, side = 0;
- int longblocks = (B0 == 1);
- uint32_t cm = 0;
-
- if (N == 1) {
- float *x = X;
- for (i = 0; i <= stereo; i++) {
- int sign = 0;
- if (f->remaining2 >= 1 << 3) {
- if (quant) {
- sign = x[0] < 0;
- ff_opus_rc_put_raw(rc, sign, 1);
- } else {
- sign = ff_opus_rc_get_raw(rc, 1);
- }
- f->remaining2 -= 1 << 3;
- }
- x[0] = 1.0f - 2.0f*sign;
- x = Y;
- }
- if (lowband_out)
- lowband_out[0] = X[0];
- return 1;
- }
-
- if (!stereo && level == 0) {
- int tf_change = f->tf_change[band];
- int k;
- if (tf_change > 0)
- recombine = tf_change;
- /* Band recombining to increase frequency resolution */
-
- if (lowband &&
- (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) {
- for (i = 0; i < N; i++)
- lowband_scratch[i] = lowband[i];
- lowband = lowband_scratch;
- }
-
- for (k = 0; k < recombine; k++) {
- if (quant || lowband)
- celt_haar1(quant ? X : lowband, N >> k, 1 << k);
- fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2;
- }
- blocks >>= recombine;
- N_B <<= recombine;
-
- /* Increasing the time resolution */
- while ((N_B & 1) == 0 && tf_change < 0) {
- if (quant || lowband)
- celt_haar1(quant ? X : lowband, N_B, blocks);
- fill |= fill << blocks;
- blocks <<= 1;
- N_B >>= 1;
- time_divide++;
- tf_change++;
- }
- B0 = blocks;
- N_B0 = N_B;
-
- /* Reorganize the samples in time order instead of frequency order */
- if (B0 > 1 && (quant || lowband))
- celt_deinterleave_hadamard(pvq->hadamard_tmp, quant ? X : lowband,
- N_B >> recombine, B0 << recombine,
- longblocks);
- }
-
- /* If we need 1.5 more bit than we can produce, split the band in two. */
- cache = ff_celt_cache_bits +
- ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band];
- if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) {
- N >>= 1;
- Y = X + N;
- split = 1;
- duration -= 1;
- if (blocks == 1)
- fill = (fill & 1) | (fill << 1);
- blocks = (blocks + 1) >> 1;
- }
-
- if (split) {
- int qn;
- int itheta = quant ? celt_calc_theta(X, Y, stereo, N) : 0;
- int mbits, sbits, delta;
- int qalloc;
- int pulse_cap;
- int offset;
- int orig_fill;
- int tell;
-
- /* Decide on the resolution to give to the split parameter theta */
- pulse_cap = ff_celt_log_freq_range[band] + duration * 8;
- offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE :
- CELT_QTHETA_OFFSET);
- qn = (stereo && band >= f->intensity_stereo) ? 1 :
- celt_compute_qn(N, b, offset, pulse_cap, stereo);
- tell = opus_rc_tell_frac(rc);
- if (qn != 1) {
- if (quant)
- itheta = (itheta*qn + 8192) >> 14;
- /* Entropy coding of the angle. We use a uniform pdf for the
- * time split, a step for stereo, and a triangular one for the rest. */
- if (quant) {
- if (stereo && N > 2)
- ff_opus_rc_enc_uint_step(rc, itheta, qn / 2);
- else if (stereo || B0 > 1)
- ff_opus_rc_enc_uint(rc, itheta, qn + 1);
- else
- ff_opus_rc_enc_uint_tri(rc, itheta, qn);
- itheta = itheta * 16384 / qn;
- if (stereo) {
- if (itheta == 0)
- celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
- f->block[1].lin_energy[band], N);
- else
- celt_stereo_ms_decouple(X, Y, N);
- }
- } else {
- if (stereo && N > 2)
- itheta = ff_opus_rc_dec_uint_step(rc, qn / 2);
- else if (stereo || B0 > 1)
- itheta = ff_opus_rc_dec_uint(rc, qn+1);
- else
- itheta = ff_opus_rc_dec_uint_tri(rc, qn);
- itheta = itheta * 16384 / qn;
- }
- } else if (stereo) {
- if (quant) {
- inv = f->apply_phase_inv ? itheta > 8192 : 0;
- if (inv) {
- for (i = 0; i < N; i++)
- Y[i] *= -1;
- }
- celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
- f->block[1].lin_energy[band], N);
-
- if (b > 2 << 3 && f->remaining2 > 2 << 3) {
- ff_opus_rc_enc_log(rc, inv, 2);
- } else {
- inv = 0;
- }
- } else {
- inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0;
- inv = f->apply_phase_inv ? inv : 0;
- }
- itheta = 0;
- }
- qalloc = opus_rc_tell_frac(rc) - tell;
- b -= qalloc;
-
- orig_fill = fill;
- if (itheta == 0) {
- imid = 32767;
- iside = 0;
- fill = av_mod_uintp2(fill, blocks);
- delta = -16384;
- } else if (itheta == 16384) {
- imid = 0;
- iside = 32767;
- fill &= ((1 << blocks) - 1) << blocks;
- delta = 16384;
- } else {
- imid = celt_cos(itheta);
- iside = celt_cos(16384-itheta);
- /* This is the mid vs side allocation that minimizes squared error
- in that band. */
- delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid));
- }
-
- mid = imid / 32768.0f;
- side = iside / 32768.0f;
-
- /* This is a special case for N=2 that only works for stereo and takes
- advantage of the fact that mid and side are orthogonal to encode
- the side with just one bit. */
- if (N == 2 && stereo) {
- int c;
- int sign = 0;
- float tmp;
- float *x2, *y2;
- mbits = b;
- /* Only need one bit for the side */
- sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0;
- mbits -= sbits;
- c = (itheta > 8192);
- f->remaining2 -= qalloc+sbits;
-
- x2 = c ? Y : X;
- y2 = c ? X : Y;
- if (sbits) {
- if (quant) {
- sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
- ff_opus_rc_put_raw(rc, sign, 1);
- } else {
- sign = ff_opus_rc_get_raw(rc, 1);
- }
- }
- sign = 1 - 2 * sign;
- /* We use orig_fill here because we want to fold the side, but if
- itheta==16384, we'll have cleared the low bits of fill. */
- cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration,
- lowband_out, level, gain, lowband_scratch, orig_fill);
- /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
- and there's no need to worry about mixing with the other channel. */
- y2[0] = -sign * x2[1];
- y2[1] = sign * x2[0];
- X[0] *= mid;
- X[1] *= mid;
- Y[0] *= side;
- Y[1] *= side;
- tmp = X[0];
- X[0] = tmp - Y[0];
- Y[0] = tmp + Y[0];
- tmp = X[1];
- X[1] = tmp - Y[1];
- Y[1] = tmp + Y[1];
- } else {
- /* "Normal" split code */
- float *next_lowband2 = NULL;
- float *next_lowband_out1 = NULL;
- int next_level = 0;
- int rebalance;
- uint32_t cmt;
-
- /* Give more bits to low-energy MDCTs than they would
- * otherwise deserve */
- if (B0 > 1 && !stereo && (itheta & 0x3fff)) {
- if (itheta > 8192)
- /* Rough approximation for pre-echo masking */
- delta -= delta >> (4 - duration);
- else
- /* Corresponds to a forward-masking slope of
- * 1.5 dB per 10 ms */
- delta = FFMIN(0, delta + (N << 3 >> (5 - duration)));
- }
- mbits = av_clip((b - delta) / 2, 0, b);
- sbits = b - mbits;
- f->remaining2 -= qalloc;
-
- if (lowband && !stereo)
- next_lowband2 = lowband + N; /* >32-bit split case */
-
- /* Only stereo needs to pass on lowband_out.
- * Otherwise, it's handled at the end */
- if (stereo)
- next_lowband_out1 = lowband_out;
- else
- next_level = level + 1;
-
- rebalance = f->remaining2;
- if (mbits >= sbits) {
- /* In stereo mode, we do not apply a scaling to the mid
- * because we need the normalized mid for folding later */
- cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
- lowband, duration, next_lowband_out1, next_level,
- stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
- rebalance = mbits - (rebalance - f->remaining2);
- if (rebalance > 3 << 3 && itheta != 0)
- sbits += rebalance - (3 << 3);
-
- /* For a stereo split, the high bits of fill are always zero,
- * so no folding will be done to the side. */
- cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
- next_lowband2, duration, NULL, next_level,
- gain * side, NULL, fill >> blocks);
- cm |= cmt << ((B0 >> 1) & (stereo - 1));
- } else {
- /* For a stereo split, the high bits of fill are always zero,
- * so no folding will be done to the side. */
- cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
- next_lowband2, duration, NULL, next_level,
- gain * side, NULL, fill >> blocks);
- cm <<= ((B0 >> 1) & (stereo - 1));
- rebalance = sbits - (rebalance - f->remaining2);
- if (rebalance > 3 << 3 && itheta != 16384)
- mbits += rebalance - (3 << 3);
-
- /* In stereo mode, we do not apply a scaling to the mid because
- * we need the normalized mid for folding later */
- cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
- lowband, duration, next_lowband_out1, next_level,
- stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
- }
- }
- } else {
- /* This is the basic no-split case */
- uint32_t q = celt_bits2pulses(cache, b);
- uint32_t curr_bits = celt_pulses2bits(cache, q);
- f->remaining2 -= curr_bits;
-
- /* Ensures we can never bust the budget */
- while (f->remaining2 < 0 && q > 0) {
- f->remaining2 += curr_bits;
- curr_bits = celt_pulses2bits(cache, --q);
- f->remaining2 -= curr_bits;
- }
-
- if (q != 0) {
- /* Finally do the actual (de)quantization */
- if (quant) {
- cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
- f->spread, blocks, gain, pvq);
- } else {
- cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
- f->spread, blocks, gain, pvq);
- }
- } else {
- /* If there's no pulse, fill the band anyway */
- uint32_t cm_mask = (1 << blocks) - 1;
- fill &= cm_mask;
- if (fill) {
- if (!lowband) {
- /* Noise */
- for (i = 0; i < N; i++)
- X[i] = (((int32_t)celt_rng(f)) >> 20);
- cm = cm_mask;
- } else {
- /* Folded spectrum */
- for (i = 0; i < N; i++) {
- /* About 48 dB below the "normal" folding level */
- X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
- }
- cm = fill;
- }
- celt_renormalize_vector(X, N, gain);
- } else {
- memset(X, 0, N*sizeof(float));
- }
- }
- }
-
- /* This code is used by the decoder and by the resynthesis-enabled encoder */
- if (stereo) {
- if (N > 2)
- celt_stereo_merge(X, Y, mid, N);
- if (inv) {
- for (i = 0; i < N; i++)
- Y[i] *= -1;
- }
- } else if (level == 0) {
- int k;
-
- /* Undo the sample reorganization going from time order to frequency order */
- if (B0 > 1)
- celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine,
- B0 << recombine, longblocks);
-
- /* Undo time-freq changes that we did earlier */
- N_B = N_B0;
- blocks = B0;
- for (k = 0; k < time_divide; k++) {
- blocks >>= 1;
- N_B <<= 1;
- cm |= cm >> blocks;
- celt_haar1(X, N_B, blocks);
- }
-
- for (k = 0; k < recombine; k++) {
- cm = ff_celt_bit_deinterleave[cm];
- celt_haar1(X, N0>>k, 1<<k);
- }
- blocks <<= recombine;
-
- /* Scale output for later folding */
- if (lowband_out) {
- float n = sqrtf(N0);
- for (i = 0; i < N0; i++)
- lowband_out[i] = n * X[i];
- }
- cm = av_mod_uintp2(cm, blocks);
- }
-
- return cm;
-}
-
-static QUANT_FN(pvq_decode_band)
-{
-#if CONFIG_OPUS_DECODER
- return quant_band_template(pvq, f, rc, band, X, Y, N, b, blocks, lowband, duration,
- lowband_out, level, gain, lowband_scratch, fill, 0);
-#else
- return 0;
+#define ENCODING 1
+#include "opus_pvq_template.c"
#endif
-}
-static QUANT_FN(pvq_encode_band)
-{
-#if CONFIG_OPUS_ENCODER
- return quant_band_template(pvq, f, rc, band, X, Y, N, b, blocks, lowband, duration,
- lowband_out, level, gain, lowband_scratch, fill, 1);
-#else
- return 0;
+#if CONFIG_OPUS_DECODER
+#undef ENCODING
+#define ENCODING 0
+#include "opus_pvq_template.c"
#endif
-}
int av_cold ff_celt_pvq_init(CeltPVQ **pvq, int encode)
{
@@ -909,13 +509,19 @@ int av_cold ff_celt_pvq_init(CeltPVQ **pvq, int encode)
if (!s)
return AVERROR(ENOMEM);
- s->quant_band = encode ? pvq_encode_band : pvq_decode_band;
-
#if CONFIG_OPUS_ENCODER
+#if CONFIG_OPUS_DECODER
+ s->quant_band = encode ? pvq_quant_band_enc : pvq_quant_band_dec;
+#else
+ s->quant_band = pvq_quant_band_enc;
+#endif
s->pvq_search = ppp_pvq_search_c;
#if ARCH_X86
ff_celt_pvq_init_x86(s);
#endif
+#else
+ s->quant_band = pvq_quant_band_dec;
+ s->pvq_search = NULL;
#endif
*pvq = s;
diff --git a/libavcodec/opus_pvq_template.c b/libavcodec/opus_pvq_template.c
new file mode 100644
index 0000000000..5f03f3d415
--- /dev/null
+++ b/libavcodec/opus_pvq_template.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2007-2008 CSIRO
+ * Copyright (c) 2007-2009 Xiph.Org Foundation
+ * Copyright (c) 2008-2009 Gregory Maxwell
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2017 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
+ */
+
+#undef FUNC
+
+#if ENCODING
+#define FUNC(name) name ## _enc
+#else
+#define FUNC(name) name ## _dec
+#endif
+
+static
+uint32_t FUNC(pvq_quant_band)(CeltPVQ *const pvq, CeltFrame *const f,
+ OpusRangeCoder *const rc,
+ const int band, float *X,
+ float *Y, int N, int b,
+ uint32_t blocks, float *lowband,
+ int duration, float *lowband_out,
+ int level, float gain,
+ float *lowband_scratch,
+ int fill)
+{
+#if ENCODING
+ OpusEncRangeCoder *const rce = (OpusEncRangeCoder*)rc;
+#else
+ OpusDecRangeCoder *const rcd = (OpusDecRangeCoder*)rc;
+#endif
+ const uint8_t *cache;
+ int stereo = !!Y, split = stereo;
+ uint32_t N0 = N;
+ int N_B = N / blocks;
+ int N_B0 = N_B;
+ int B0 = blocks;
+ int time_divide = 0;
+ int recombine = 0;
+ int inv = 0;
+ float mid = 0, side = 0;
+ int longblocks = (B0 == 1);
+ uint32_t cm = 0;
+
+ if (N == 1) {
+ float *x = X;
+ for (int i = 0; i <= stereo; i++) {
+ int sign = 0;
+ if (f->remaining2 >= 1 << 3) {
+#if ENCODING
+ sign = x[0] < 0;
+ ff_opus_rc_put_raw(rce, sign, 1);
+#else
+ sign = ff_opus_rc_get_raw(rcd, 1);
+#endif
+ f->remaining2 -= 1 << 3;
+ }
+ x[0] = 1.0f - 2.0f*sign;
+ x = Y;
+ }
+ if (lowband_out)
+ lowband_out[0] = X[0];
+ return 1;
+ }
+
+ if (!stereo && level == 0) {
+ int tf_change = f->tf_change[band];
+ int k;
+ if (tf_change > 0)
+ recombine = tf_change;
+ /* Band recombining to increase frequency resolution */
+
+ if (lowband &&
+ (recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) {
+ for (int i = 0; i < N; i++)
+ lowband_scratch[i] = lowband[i];
+ lowband = lowband_scratch;
+ }
+
+ for (k = 0; k < recombine; k++) {
+ if (ENCODING || lowband)
+ celt_haar1(ENCODING ? X : lowband, N >> k, 1 << k);
+ fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2;
+ }
+ blocks >>= recombine;
+ N_B <<= recombine;
+
+ /* Increasing the time resolution */
+ while ((N_B & 1) == 0 && tf_change < 0) {
+ if (ENCODING || lowband)
+ celt_haar1(ENCODING ? X : lowband, N_B, blocks);
+ fill |= fill << blocks;
+ blocks <<= 1;
+ N_B >>= 1;
+ time_divide++;
+ tf_change++;
+ }
+ B0 = blocks;
+ N_B0 = N_B;
+
+ /* Reorganize the samples in time order instead of frequency order */
+ if (B0 > 1 && (ENCODING || lowband))
+ celt_deinterleave_hadamard(pvq->hadamard_tmp, ENCODING ? X : lowband,
+ N_B >> recombine, B0 << recombine,
+ longblocks);
+ }
+
+ /* If we need 1.5 more bit than we can produce, split the band in two. */
+ cache = ff_celt_cache_bits +
+ ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band];
+ if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) {
+ N >>= 1;
+ Y = X + N;
+ split = 1;
+ duration -= 1;
+ if (blocks == 1)
+ fill = (fill & 1) | (fill << 1);
+ blocks = (blocks + 1) >> 1;
+ }
+
+ if (split) {
+ int qn;
+ int itheta = ENCODING ? celt_calc_theta(X, Y, stereo, N) : 0;
+ int mbits, sbits, delta;
+ int imid = 0, iside = 0;
+ int qalloc;
+ int pulse_cap;
+ int offset;
+ int orig_fill;
+ int tell;
+
+ /* Decide on the resolution to give to the split parameter theta */
+ pulse_cap = ff_celt_log_freq_range[band] + duration * 8;
+ offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE :
+ CELT_QTHETA_OFFSET);
+ qn = (stereo && band >= f->intensity_stereo) ? 1 :
+ celt_compute_qn(N, b, offset, pulse_cap, stereo);
+ tell = opus_rc_tell_frac(rc);
+ if (qn != 1) {
+#if ENCODING
+ itheta = (itheta * qn + 8192) >> 14;
+ /* Entropy coding of the angle. We use a uniform pdf for the
+ * time split, a step for stereo, and a triangular one for the rest. */
+ if (stereo && N > 2)
+ ff_opus_rc_enc_uint_step(rce, itheta, qn / 2);
+ else if (stereo || B0 > 1)
+ ff_opus_rc_enc_uint(rce, itheta, qn + 1);
+ else
+ ff_opus_rc_enc_uint_tri(rce, itheta, qn);
+ itheta = itheta * 16384 / qn;
+ if (stereo) {
+ if (itheta == 0)
+ celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
+ f->block[1].lin_energy[band], N);
+ else
+ celt_stereo_ms_decouple(X, Y, N);
+ }
+#else
+ if (stereo && N > 2)
+ itheta = ff_opus_rc_dec_uint_step(rcd, qn / 2);
+ else if (stereo || B0 > 1)
+ itheta = ff_opus_rc_dec_uint(rcd, qn+1);
+ else
+ itheta = ff_opus_rc_dec_uint_tri(rcd, qn);
+ itheta = itheta * 16384 / qn;
+#endif
+ } else if (stereo) {
+#if ENCODING
+ inv = f->apply_phase_inv ? itheta > 8192 : 0;
+ if (inv) {
+ for (int i = 0; i < N; i++)
+ Y[i] *= -1;
+ }
+ celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
+ f->block[1].lin_energy[band], N);
+
+ if (b > 2 << 3 && f->remaining2 > 2 << 3) {
+ ff_opus_rc_enc_log(rce, inv, 2);
+ } else {
+ inv = 0;
+ }
+#else
+ inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rcd, 2) : 0;
+ inv = f->apply_phase_inv ? inv : 0;
+#endif
+ itheta = 0;
+ }
+ qalloc = opus_rc_tell_frac(rc) - tell;
+ b -= qalloc;
+
+ orig_fill = fill;
+ if (itheta == 0) {
+ imid = 32767;
+ iside = 0;
+ fill = av_mod_uintp2(fill, blocks);
+ delta = -16384;
+ } else if (itheta == 16384) {
+ imid = 0;
+ iside = 32767;
+ fill &= ((1 << blocks) - 1) << blocks;
+ delta = 16384;
+ } else {
+ imid = celt_cos(itheta);
+ iside = celt_cos(16384 - itheta);
+ /* This is the mid vs side allocation that minimizes squared error
+ in that band. */
+ delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid));
+ }
+
+ mid = imid / 32768.0f;
+ side = iside / 32768.0f;
+
+ /* This is a special case for N=2 that only works for stereo and takes
+ advantage of the fact that mid and side are orthogonal to encode
+ the side with just one bit. */
+ if (N == 2 && stereo) {
+ int c;
+ int sign = 0;
+ float tmp;
+ float *x2, *y2;
+ mbits = b;
+ /* Only need one bit for the side */
+ sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0;
+ mbits -= sbits;
+ c = (itheta > 8192);
+ f->remaining2 -= qalloc + sbits;
+
+ x2 = c ? Y : X;
+ y2 = c ? X : Y;
+ if (sbits) {
+#if ENCODING
+ sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
+ ff_opus_rc_put_raw(rce, sign, 1);
+#else
+ sign = ff_opus_rc_get_raw(rcd, 1);
+#endif
+ }
+ sign = 1 - 2 * sign;
+ /* We use orig_fill here because we want to fold the side, but if
+ itheta==16384, we'll have cleared the low bits of fill. */
+ cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration,
+ lowband_out, level, gain, lowband_scratch, orig_fill);
+ /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
+ and there's no need to worry about mixing with the other channel. */
+ y2[0] = -sign * x2[1];
+ y2[1] = sign * x2[0];
+ X[0] *= mid;
+ X[1] *= mid;
+ Y[0] *= side;
+ Y[1] *= side;
+ tmp = X[0];
+ X[0] = tmp - Y[0];
+ Y[0] = tmp + Y[0];
+ tmp = X[1];
+ X[1] = tmp - Y[1];
+ Y[1] = tmp + Y[1];
+ } else {
+ /* "Normal" split code */
+ float *next_lowband2 = NULL;
+ float *next_lowband_out1 = NULL;
+ int next_level = 0;
+ int rebalance;
+ uint32_t cmt;
+
+ /* Give more bits to low-energy MDCTs than they would
+ * otherwise deserve */
+ if (B0 > 1 && !stereo && (itheta & 0x3fff)) {
+ if (itheta > 8192)
+ /* Rough approximation for pre-echo masking */
+ delta -= delta >> (4 - duration);
+ else
+ /* Corresponds to a forward-masking slope of
+ * 1.5 dB per 10 ms */
+ delta = FFMIN(0, delta + (N << 3 >> (5 - duration)));
+ }
+ mbits = av_clip((b - delta) / 2, 0, b);
+ sbits = b - mbits;
+ f->remaining2 -= qalloc;
+
+ if (lowband && !stereo)
+ next_lowband2 = lowband + N; /* >32-bit split case */
+
+ /* Only stereo needs to pass on lowband_out.
+ * Otherwise, it's handled at the end */
+ if (stereo)
+ next_lowband_out1 = lowband_out;
+ else
+ next_level = level + 1;
+
+ rebalance = f->remaining2;
+ if (mbits >= sbits) {
+ /* In stereo mode, we do not apply a scaling to the mid
+ * because we need the normalized mid for folding later */
+ cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
+ lowband, duration, next_lowband_out1, next_level,
+ stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
+ rebalance = mbits - (rebalance - f->remaining2);
+ if (rebalance > 3 << 3 && itheta != 0)
+ sbits += rebalance - (3 << 3);
+
+ /* For a stereo split, the high bits of fill are always zero,
+ * so no folding will be done to the side. */
+ cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
+ next_lowband2, duration, NULL, next_level,
+ gain * side, NULL, fill >> blocks);
+ cm |= cmt << ((B0 >> 1) & (stereo - 1));
+ } else {
+ /* For a stereo split, the high bits of fill are always zero,
+ * so no folding will be done to the side. */
+ cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
+ next_lowband2, duration, NULL, next_level,
+ gain * side, NULL, fill >> blocks);
+ cm <<= ((B0 >> 1) & (stereo - 1));
+ rebalance = sbits - (rebalance - f->remaining2);
+ if (rebalance > 3 << 3 && itheta != 16384)
+ mbits += rebalance - (3 << 3);
+
+ /* In stereo mode, we do not apply a scaling to the mid because
+ * we need the normalized mid for folding later */
+ cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
+ lowband, duration, next_lowband_out1, next_level,
+ stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
+ }
+ }
+ } else {
+ /* This is the basic no-split case */
+ uint32_t q = celt_bits2pulses(cache, b);
+ uint32_t curr_bits = celt_pulses2bits(cache, q);
+ f->remaining2 -= curr_bits;
+
+ /* Ensures we can never bust the budget */
+ while (f->remaining2 < 0 && q > 0) {
+ f->remaining2 += curr_bits;
+ curr_bits = celt_pulses2bits(cache, --q);
+ f->remaining2 -= curr_bits;
+ }
+
+ if (q != 0) {
+ /* Finally do the actual (de)quantization */
+#if ENCODING
+ cm = celt_alg_quant(rce, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
+ f->spread, blocks, gain, pvq);
+#else
+ cm = celt_alg_unquant(rcd, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
+ f->spread, blocks, gain, pvq);
+#endif
+ } else {
+ /* If there's no pulse, fill the band anyway */
+ uint32_t cm_mask = (1 << blocks) - 1;
+ fill &= cm_mask;
+ if (fill) {
+ if (!lowband) {
+ /* Noise */
+ for (int i = 0; i < N; i++)
+ X[i] = (((int32_t)celt_rng(f)) >> 20);
+ cm = cm_mask;
+ } else {
+ /* Folded spectrum */
+ for (int i = 0; i < N; i++) {
+ /* About 48 dB below the "normal" folding level */
+ X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
+ }
+ cm = fill;
+ }
+ celt_renormalize_vector(X, N, gain);
+ } else {
+ memset(X, 0, N*sizeof(float));
+ }
+ }
+ }
+
+ /* This code is used by the decoder and by the resynthesis-enabled encoder */
+ if (stereo) {
+ if (N > 2)
+ celt_stereo_merge(X, Y, mid, N);
+ if (inv) {
+ for (int i = 0; i < N; i++)
+ Y[i] *= -1;
+ }
+ } else if (level == 0) {
+ int k;
+
+ /* Undo the sample reorganization going from time order to frequency order */
+ if (B0 > 1)
+ celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine,
+ B0 << recombine, longblocks);
+
+ /* Undo time-freq changes that we did earlier */
+ N_B = N_B0;
+ blocks = B0;
+ for (k = 0; k < time_divide; k++) {
+ blocks >>= 1;
+ N_B <<= 1;
+ cm |= cm >> blocks;
+ celt_haar1(X, N_B, blocks);
+ }
+
+ for (k = 0; k < recombine; k++) {
+ cm = ff_celt_bit_deinterleave[cm];
+ celt_haar1(X, N0>>k, 1<<k);
+ }
+ blocks <<= recombine;
+
+ /* Scale output for later folding */
+ if (lowband_out) {
+ float n = sqrtf(N0);
+ for (int i = 0; i < N0; i++)
+ lowband_out[i] = n * X[i];
+ }
+ cm = av_mod_uintp2(cm, blocks);
+ }
+
+ return cm;
+}
diff --git a/libavcodec/opus_rc.c b/libavcodec/opus_rc.c
deleted file mode 100644
index 1a26d889b7..0000000000
--- a/libavcodec/opus_rc.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (c) 2012 Andrew D'Addesio
- * Copyright (c) 2013-2014 Mozilla Corporation
- * Copyright (c) 2017 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
- */
-
-#include "opus_rc.h"
-
-#define OPUS_RC_BITS 32
-#define OPUS_RC_SYM 8
-#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1)
-#define OPUS_RC_TOP (1u << 31)
-#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM)
-#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1)
-
-static av_always_inline void opus_rc_enc_carryout(OpusRangeCoder *rc, int cbuf)
-{
- const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL;
- if (cbuf == OPUS_RC_CEIL) {
- rc->ext++;
- return;
- }
- rc->rng_cur[0] = rc->rem + cb;
- rc->rng_cur += (rc->rem >= 0);
- for (; rc->ext > 0; rc->ext--)
- *rc->rng_cur++ = mb;
- av_assert0(rc->rng_cur < rc->rb.position);
- rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */
-}
-
-static av_always_inline void opus_rc_dec_normalize(OpusRangeCoder *rc)
-{
- while (rc->range <= OPUS_RC_BOT) {
- rc->value = ((rc->value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1);
- rc->range <<= OPUS_RC_SYM;
- rc->total_bits += OPUS_RC_SYM;
- }
-}
-
-static av_always_inline void opus_rc_enc_normalize(OpusRangeCoder *rc)
-{
- while (rc->range <= OPUS_RC_BOT) {
- opus_rc_enc_carryout(rc, rc->value >> OPUS_RC_SHIFT);
- rc->value = (rc->value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
- rc->range <<= OPUS_RC_SYM;
- rc->total_bits += OPUS_RC_SYM;
- }
-}
-
-static av_always_inline void opus_rc_dec_update(OpusRangeCoder *rc, uint32_t scale,
- uint32_t low, uint32_t high,
- uint32_t total)
-{
- rc->value -= scale * (total - high);
- rc->range = low ? scale * (high - low)
- : rc->range - scale * (total - high);
- opus_rc_dec_normalize(rc);
-}
-
-/* Main encoding function, this needs to go fast */
-static av_always_inline void opus_rc_enc_update(OpusRangeCoder *rc, uint32_t b, uint32_t p,
- uint32_t p_tot, const int ptwo)
-{
- uint32_t rscaled, cnd = !!b;
- if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */
- rscaled = rc->range >> ff_log2(p_tot);
- else
- rscaled = rc->range/p_tot;
- rc->value += cnd*(rc->range - rscaled*(p_tot - b));
- rc->range = (!cnd)*(rc->range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b);
- opus_rc_enc_normalize(rc);
-}
-
-uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf)
-{
- unsigned int k, scale, total, symbol, low, high;
-
- total = *cdf++;
-
- scale = rc->range / total;
- symbol = rc->value / scale + 1;
- symbol = total - FFMIN(symbol, total);
-
- for (k = 0; cdf[k] <= symbol; k++);
- high = cdf[k];
- low = k ? cdf[k-1] : 0;
-
- opus_rc_dec_update(rc, scale, low, high, total);
-
- return k;
-}
-
-void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf)
-{
- opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1);
-}
-
-uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits)
-{
- uint32_t k, scale;
- scale = rc->range >> bits; // in this case, scale = symbol
-
- if (rc->value >= scale) {
- rc->value -= scale;
- rc->range -= scale;
- k = 0;
- } else {
- rc->range = scale;
- k = 1;
- }
- opus_rc_dec_normalize(rc);
- return k;
-}
-
-void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits)
-{
- bits = (1 << bits) - 1;
- opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1);
-}
-
-/**
- * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise
- */
-uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count)
-{
- uint32_t value = 0;
-
- while (rc->rb.bytes && rc->rb.cachelen < count) {
- rc->rb.cacheval |= *--rc->rb.position << rc->rb.cachelen;
- rc->rb.cachelen += 8;
- rc->rb.bytes--;
- }
-
- value = av_mod_uintp2(rc->rb.cacheval, count);
- rc->rb.cacheval >>= count;
- rc->rb.cachelen -= count;
- rc->total_bits += count;
-
- return value;
-}
-
-/**
- * CELT: write 0 - 31 bits to the rawbits buffer
- */
-void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count)
-{
- const int to_write = FFMIN(32 - rc->rb.cachelen, count);
-
- rc->total_bits += count;
- rc->rb.cacheval |= av_mod_uintp2(val, to_write) << rc->rb.cachelen;
- rc->rb.cachelen = (rc->rb.cachelen + to_write) % 32;
-
- if (!rc->rb.cachelen && count) {
- AV_WB32((uint8_t *)rc->rb.position, rc->rb.cacheval);
- rc->rb.bytes += 4;
- rc->rb.position -= 4;
- rc->rb.cachelen = count - to_write;
- rc->rb.cacheval = av_mod_uintp2(val >> to_write, rc->rb.cachelen);
- av_assert0(rc->rng_cur < rc->rb.position);
- }
-}
-
-/**
- * CELT: read a uniform distribution
- */
-uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size)
-{
- uint32_t bits, k, scale, total;
-
- bits = opus_ilog(size - 1);
- total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size;
-
- scale = rc->range / total;
- k = rc->value / scale + 1;
- k = total - FFMIN(k, total);
- opus_rc_dec_update(rc, scale, k, k + 1, total);
-
- if (bits > 8) {
- k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8);
- return FFMIN(k, size - 1);
- } else
- return k;
-}
-
-/**
- * CELT: write a uniformly distributed integer
- */
-void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size)
-{
- const int ps = FFMAX(opus_ilog(size - 1) - 8, 0);
- opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0);
- ff_opus_rc_put_raw(rc, val, ps);
-}
-
-uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0)
-{
- /* Use a probability of 3 up to itheta=8192 and then use 1 after */
- uint32_t k, scale, symbol, total = (k0+1)*3 + k0;
- scale = rc->range / total;
- symbol = rc->value / scale + 1;
- symbol = total - FFMIN(symbol, total);
-
- k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2;
-
- opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1),
- (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total);
- return k;
-}
-
-void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0)
-{
- const uint32_t a = val <= k0, b = 2*a + 1;
- k0 = (k0 + 1) << 1;
- val = b*(val + k0) - 3*a*k0;
- opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0);
-}
-
-uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn)
-{
- uint32_t k, scale, symbol, total, low, center;
-
- total = ((qn>>1) + 1) * ((qn>>1) + 1);
- scale = rc->range / total;
- center = rc->value / scale + 1;
- center = total - FFMIN(center, total);
-
- if (center < total >> 1) {
- k = (ff_sqrt(8 * center + 1) - 1) >> 1;
- low = k * (k + 1) >> 1;
- symbol = k + 1;
- } else {
- k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1;
- low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
- symbol = qn + 1 - k;
- }
-
- opus_rc_dec_update(rc, scale, low, low + symbol, total);
-
- return k;
-}
-
-void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn)
-{
- uint32_t symbol, low, total;
-
- total = ((qn>>1) + 1) * ((qn>>1) + 1);
-
- if (k <= qn >> 1) {
- low = k * (k + 1) >> 1;
- symbol = k + 1;
- } else {
- low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
- symbol = qn + 1 - k;
- }
-
- opus_rc_enc_update(rc, low, low + symbol, total, 0);
-}
-
-int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay)
-{
- /* extends the range coder to model a Laplace distribution */
- int value = 0;
- uint32_t scale, low = 0, center;
-
- scale = rc->range >> 15;
- center = rc->value / scale + 1;
- center = (1 << 15) - FFMIN(center, 1 << 15);
-
- if (center >= symbol) {
- value++;
- low = symbol;
- symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15);
-
- while (symbol > 1 && center >= low + 2 * symbol) {
- value++;
- symbol *= 2;
- low += symbol;
- symbol = (((symbol - 2) * decay) >> 15) + 1;
- }
-
- if (symbol <= 1) {
- int distance = (center - low) >> 1;
- value += distance;
- low += 2 * distance;
- }
-
- if (center < low + symbol)
- value *= -1;
- else
- low += symbol;
- }
-
- opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768);
-
- return value;
-}
-
-void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay)
-{
- uint32_t low = symbol;
- int i = 1, val = FFABS(*value), pos = *value > 0;
- if (!val) {
- opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1);
- return;
- }
- symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15;
- for (; i < val && symbol; i++) {
- low += (symbol << 1) + 2;
- symbol = (symbol*decay) >> 14;
- }
- if (symbol) {
- low += (++symbol)*pos;
- } else {
- const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1);
- low += pos + (distance << 1);
- symbol = FFMIN(1, 32768 - low);
- *value = FFSIGN(*value)*(distance + i);
- }
- opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1);
-}
-
-int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size)
-{
- int ret = init_get_bits8(&rc->gb, data, size);
- if (ret < 0)
- return ret;
-
- rc->range = 128;
- rc->value = 127 - get_bits(&rc->gb, 7);
- rc->total_bits = 9;
- opus_rc_dec_normalize(rc);
-
- return 0;
-}
-
-void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes)
-{
- rc->rb.position = rightend;
- rc->rb.bytes = bytes;
- rc->rb.cachelen = 0;
- rc->rb.cacheval = 0;
-}
-
-void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size)
-{
- int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->range);
- uint32_t mask = (OPUS_RC_TOP - 1) >> bits;
- uint32_t end = (rc->value + mask) & ~mask;
-
- if ((end | mask) >= rc->value + rc->range) {
- bits++;
- mask >>= 1;
- end = (rc->value + mask) & ~mask;
- }
-
- /* Finish what's left */
- while (bits > 0) {
- opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT);
- end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
- bits -= OPUS_RC_SYM;
- }
-
- /* Flush out anything left or marked */
- if (rc->rem >= 0 || rc->ext > 0)
- opus_rc_enc_carryout(rc, 0);
-
- rng_bytes = rc->rng_cur - rc->buf;
- memcpy(dst, rc->buf, rng_bytes);
-
- /* Put the rawbits part, if any */
- if (rc->rb.bytes || rc->rb.cachelen) {
- int i, lap;
- uint8_t *rb_src, *rb_dst;
- ff_opus_rc_put_raw(rc, 0, 32 - rc->rb.cachelen);
- rb_src = rc->buf + OPUS_MAX_FRAME_SIZE + 12 - rc->rb.bytes;
- rb_dst = dst + FFMAX(size - rc->rb.bytes, 0);
- lap = &dst[rng_bytes] - rb_dst;
- for (i = 0; i < lap; i++)
- rb_dst[i] |= rb_src[i];
- memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->rb.bytes - lap, 0));
- }
-}
-
-void ff_opus_rc_enc_init(OpusRangeCoder *rc)
-{
- rc->value = 0;
- rc->range = OPUS_RC_TOP;
- rc->total_bits = OPUS_RC_BITS + 1;
- rc->rem = -1;
- rc->ext = 0;
- rc->rng_cur = rc->buf;
- ff_opus_rc_dec_raw_init(rc, rc->buf + OPUS_MAX_FRAME_SIZE + 8, 0);
-}
diff --git a/libavcodec/opus_rc.h b/libavcodec/opus_rc.h
index 72e683b075..332f3fa883 100644
--- a/libavcodec/opus_rc.h
+++ b/libavcodec/opus_rc.h
@@ -24,11 +24,16 @@
#define AVCODEC_OPUS_RC_H
#include <stdint.h>
-#include "get_bits.h"
-#include "opus.h"
+
+#include "libavutil/common.h"
#define opus_ilog(i) (av_log2(i) + !!(i))
+#define OPUS_RC_SYM 8
+#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1)
+#define OPUS_RC_TOP (1u << 31)
+#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM)
+
typedef struct RawBitsContext {
const uint8_t *position;
uint32_t bytes;
@@ -37,19 +42,21 @@ typedef struct RawBitsContext {
} RawBitsContext;
typedef struct OpusRangeCoder {
- GetBitContext gb;
RawBitsContext rb;
uint32_t range;
uint32_t value;
uint32_t total_bits;
-
- /* Encoder */
- uint8_t buf[OPUS_MAX_FRAME_SIZE + 12]; /* memcpy vs (memmove + overreading) */
- uint8_t *rng_cur; /* Current range coded byte */
- int ext; /* Awaiting propagation */
- int rem; /* Carryout flag */
} OpusRangeCoder;
+static inline void ff_opus_rc_raw_init(OpusRangeCoder *rc, const uint8_t *rightend,
+ uint32_t bytes)
+{
+ rc->rb.position = rightend;
+ rc->rb.bytes = bytes;
+ rc->rb.cachelen = 0;
+ rc->rb.cacheval = 0;
+}
+
/**
* CELT: estimate bits of entropy that have thus far been consumed for the
* current CELT frame, to integer and fractional (1/8th bit) precision
@@ -78,45 +85,4 @@ static av_always_inline uint32_t opus_rc_tell_frac(const OpusRangeCoder *rc)
return total_bits - rcbuffer;
}
-uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf);
-void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf);
-
-uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits);
-void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits);
-
-uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0);
-void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0);
-
-uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn);
-void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn);
-
-uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size);
-void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size);
-
-uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count);
-void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count);
-
-int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay);
-void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay);
-
-int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size);
-void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes);
-
-void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size);
-void ff_opus_rc_enc_init(OpusRangeCoder *rc);
-
-#define OPUS_RC_CHECKPOINT_UPDATE(rc) \
- rc_rollback_bits = opus_rc_tell_frac(rc); \
- rc_rollback_ctx = *rc
-
-#define OPUS_RC_CHECKPOINT_SPAWN(rc) \
- uint32_t rc_rollback_bits = opus_rc_tell_frac(rc); \
- OpusRangeCoder rc_rollback_ctx = *rc \
-
-#define OPUS_RC_CHECKPOINT_BITS(rc) \
- (opus_rc_tell_frac(rc) - rc_rollback_bits)
-
-#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \
- memcpy(rc, &rc_rollback_ctx, sizeof(OpusRangeCoder)); \
-
#endif /* AVCODEC_OPUS_RC_H */
diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c
index cf8b16acff..99696e26d2 100644
--- a/libavcodec/opus_silk.c
+++ b/libavcodec/opus_silk.c
@@ -29,6 +29,7 @@
#include "mathops.h"
#include "opus.h"
#include "opus_rc.h"
+#include "opusdec_rc.h"
#include "opus_silk.h"
#include "opustab.h"
@@ -308,7 +309,7 @@ static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order)
}
static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
- OpusRangeCoder *rc,
+ OpusDecRangeCoder *rc,
float lpc_leadin[16], float lpc[16],
int *lpc_order, int *has_lpc_leadin, int voiced)
{
@@ -404,7 +405,7 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
memcpy(frame->lpc, lpc, order * sizeof(lpc[0]));
}
-static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total,
+static inline void silk_count_children(OpusDecRangeCoder *rc, int model, int32_t total,
int32_t child[2])
{
if (total != 0) {
@@ -417,7 +418,7 @@ static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t to
}
}
-static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
+static inline void silk_decode_excitation(SilkContext *s, OpusDecRangeCoder *rc,
float* excitationf,
int qoffset_high, int active, int voiced)
{
@@ -511,7 +512,7 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
/** Order of the LTP filter */
#define LTP_ORDER 5
-static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
+static void silk_decode_frame(SilkContext *s, OpusDecRangeCoder *rc,
int frame_num, int channel, int coded_channels,
int active, int active1, int redundant)
{
@@ -788,7 +789,7 @@ static void silk_flush_frame(SilkFrame *frame)
frame->coded = 0;
}
-int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
+int ff_silk_decode_superframe(SilkContext *s, OpusDecRangeCoder *rc,
float *output[2],
enum OpusBandwidth bandwidth,
int coded_channels,
diff --git a/libavcodec/opus_silk.h b/libavcodec/opus_silk.h
index 6552c166a4..cd6920920e 100644
--- a/libavcodec/opus_silk.h
+++ b/libavcodec/opus_silk.h
@@ -25,7 +25,7 @@
#include "avcodec.h"
#include "opus.h"
-#include "opus_rc.h"
+#include "opusdec_rc.h"
#define SILK_HISTORY 322
#define SILK_MAX_LPC 16
@@ -40,7 +40,7 @@ void ff_silk_flush(SilkContext *s);
* Decode the LP layer of one Opus frame (which may correspond to several SILK
* frames).
*/
-int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
+int ff_silk_decode_superframe(SilkContext *s, OpusDecRangeCoder *rc,
float *output[2],
enum OpusBandwidth bandwidth, int coded_channels,
int duration_ms);
diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c
index c5f06e0600..468bc6ddff 100644
--- a/libavcodec/opusdec.c
+++ b/libavcodec/opusdec.c
@@ -54,6 +54,7 @@
#include "opus_celt.h"
#include "opus_parse.h"
#include "opus_rc.h"
+#include "opusdec_rc.h"
#include "opus_silk.h"
static const uint16_t silk_frame_duration_ms[16] = {
@@ -83,8 +84,8 @@ typedef struct OpusStreamContext {
* the streams when they have different resampling delays */
AVAudioFifo *sync_buffer;
- OpusRangeCoder rc;
- OpusRangeCoder redundancy_rc;
+ OpusDecRangeCoder rc;
+ OpusDecRangeCoder redundancy_rc;
SilkContext *silk;
CeltFrame *celt;
AVFloatDSPContext *fdsp;
@@ -218,7 +219,7 @@ static int opus_decode_redundancy(OpusStreamContext *s, const uint8_t *data, int
int ret = ff_opus_rc_dec_init(&s->redundancy_rc, data, size);
if (ret < 0)
goto fail;
- ff_opus_rc_dec_raw_init(&s->redundancy_rc, data + size, size);
+ ff_opus_rc_raw_init(&s->redundancy_rc.c, data + size, size);
ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc,
s->redundancy_output,
@@ -274,7 +275,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
ff_silk_flush(s->silk);
// decode redundancy information
- consumed = opus_rc_tell(&s->rc);
+ consumed = opus_rc_tell(&s->rc.c);
if (s->packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8)
redundancy = ff_opus_rc_dec_log(&s->rc, 12);
else if (s->packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8)
@@ -328,7 +329,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
}
}
- ff_opus_rc_dec_raw_init(&s->rc, data + size, size);
+ ff_opus_rc_raw_init(&s->rc.c, data + size, size);
ret = ff_celt_decode_frame(s->celt, &s->rc, dst,
s->packet.stereo + 1,
diff --git a/libavcodec/opusdec_rc.c b/libavcodec/opusdec_rc.c
new file mode 100644
index 0000000000..fb2bce0b72
--- /dev/null
+++ b/libavcodec/opusdec_rc.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2017 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
+ */
+
+#include "opus_rc.h"
+#include "opusdec_rc.h"
+
+static av_always_inline void opus_rc_dec_normalize(OpusDecRangeCoder *rc)
+{
+ while (rc->c.range <= OPUS_RC_BOT) {
+ rc->c.value = ((rc->c.value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1);
+ rc->c.range <<= OPUS_RC_SYM;
+ rc->c.total_bits += OPUS_RC_SYM;
+ }
+}
+
+static av_always_inline void opus_rc_dec_update(OpusDecRangeCoder *rc, uint32_t scale,
+ uint32_t low, uint32_t high,
+ uint32_t total)
+{
+ rc->c.value -= scale * (total - high);
+ rc->c.range = low ? scale * (high - low)
+ : rc->c.range - scale * (total - high);
+ opus_rc_dec_normalize(rc);
+}
+
+uint32_t ff_opus_rc_dec_cdf(OpusDecRangeCoder *rc, const uint16_t *cdf)
+{
+ unsigned int k, scale, total, symbol, low, high;
+
+ total = *cdf++;
+
+ scale = rc->c.range / total;
+ symbol = rc->c.value / scale + 1;
+ symbol = total - FFMIN(symbol, total);
+
+ for (k = 0; cdf[k] <= symbol; k++);
+ high = cdf[k];
+ low = k ? cdf[k-1] : 0;
+
+ opus_rc_dec_update(rc, scale, low, high, total);
+
+ return k;
+}
+
+uint32_t ff_opus_rc_dec_log(OpusDecRangeCoder *rc, uint32_t bits)
+{
+ uint32_t k, scale;
+ scale = rc->c.range >> bits; // in this case, scale = symbol
+
+ if (rc->c.value >= scale) {
+ rc->c.value -= scale;
+ rc->c.range -= scale;
+ k = 0;
+ } else {
+ rc->c.range = scale;
+ k = 1;
+ }
+ opus_rc_dec_normalize(rc);
+ return k;
+}
+
+/**
+ * CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise
+ */
+uint32_t ff_opus_rc_get_raw(OpusDecRangeCoder *rc, uint32_t count)
+{
+ uint32_t value = 0;
+
+ while (rc->c.rb.bytes && rc->c.rb.cachelen < count) {
+ rc->c.rb.cacheval |= *--rc->c.rb.position << rc->c.rb.cachelen;
+ rc->c.rb.cachelen += 8;
+ rc->c.rb.bytes--;
+ }
+
+ value = av_mod_uintp2(rc->c.rb.cacheval, count);
+ rc->c.rb.cacheval >>= count;
+ rc->c.rb.cachelen -= count;
+ rc->c.total_bits += count;
+
+ return value;
+}
+
+/**
+ * CELT: read a uniform distribution
+ */
+uint32_t ff_opus_rc_dec_uint(OpusDecRangeCoder *rc, uint32_t size)
+{
+ uint32_t bits, k, scale, total;
+
+ bits = opus_ilog(size - 1);
+ total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size;
+
+ scale = rc->c.range / total;
+ k = rc->c.value / scale + 1;
+ k = total - FFMIN(k, total);
+ opus_rc_dec_update(rc, scale, k, k + 1, total);
+
+ if (bits > 8) {
+ k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8);
+ return FFMIN(k, size - 1);
+ } else
+ return k;
+}
+
+uint32_t ff_opus_rc_dec_uint_step(OpusDecRangeCoder *rc, int k0)
+{
+ /* Use a probability of 3 up to itheta=8192 and then use 1 after */
+ uint32_t k, scale, symbol, total = (k0+1)*3 + k0;
+ scale = rc->c.range / total;
+ symbol = rc->c.value / scale + 1;
+ symbol = total - FFMIN(symbol, total);
+
+ k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2;
+
+ opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1),
+ (k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total);
+ return k;
+}
+
+uint32_t ff_opus_rc_dec_uint_tri(OpusDecRangeCoder *rc, int qn)
+{
+ uint32_t k, scale, symbol, total, low, center;
+
+ total = ((qn>>1) + 1) * ((qn>>1) + 1);
+ scale = rc->c.range / total;
+ center = rc->c.value / scale + 1;
+ center = total - FFMIN(center, total);
+
+ if (center < total >> 1) {
+ k = (ff_sqrt(8 * center + 1) - 1) >> 1;
+ low = k * (k + 1) >> 1;
+ symbol = k + 1;
+ } else {
+ k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1;
+ low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
+ symbol = qn + 1 - k;
+ }
+
+ opus_rc_dec_update(rc, scale, low, low + symbol, total);
+
+ return k;
+}
+
+int ff_opus_rc_dec_laplace(OpusDecRangeCoder *rc, uint32_t symbol, int decay)
+{
+ /* extends the range coder to model a Laplace distribution */
+ int value = 0;
+ uint32_t scale, low = 0, center;
+
+ scale = rc->c.range >> 15;
+ center = rc->c.value / scale + 1;
+ center = (1 << 15) - FFMIN(center, 1 << 15);
+
+ if (center >= symbol) {
+ value++;
+ low = symbol;
+ symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15);
+
+ while (symbol > 1 && center >= low + 2 * symbol) {
+ value++;
+ symbol *= 2;
+ low += symbol;
+ symbol = (((symbol - 2) * decay) >> 15) + 1;
+ }
+
+ if (symbol <= 1) {
+ int distance = (center - low) >> 1;
+ value += distance;
+ low += 2 * distance;
+ }
+
+ if (center < low + symbol)
+ value *= -1;
+ else
+ low += symbol;
+ }
+
+ opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768);
+
+ return value;
+}
+
+int ff_opus_rc_dec_init(OpusDecRangeCoder *rc, const uint8_t *data, int size)
+{
+ int ret = init_get_bits8(&rc->gb, data, size);
+ if (ret < 0)
+ return ret;
+
+ rc->c.range = 128;
+ rc->c.value = 127 - get_bits(&rc->gb, 7);
+ rc->c.total_bits = 9;
+ opus_rc_dec_normalize(rc);
+
+ return 0;
+}
diff --git a/libavcodec/opusdec_rc.h b/libavcodec/opusdec_rc.h
new file mode 100644
index 0000000000..96889e3d7f
--- /dev/null
+++ b/libavcodec/opusdec_rc.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2017 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_OPUSDEC_RC_H
+#define AVCODEC_OPUSDEC_RC_H
+
+#include <stdint.h>
+
+#include "get_bits.h"
+#include "opus_rc.h"
+
+typedef struct OpusDecRangeCoder {
+ OpusRangeCoder c;
+
+ GetBitContext gb;
+} OpusDecRangeCoder;
+
+uint32_t ff_opus_rc_dec_cdf(OpusDecRangeCoder *rc, const uint16_t *cdf);
+
+uint32_t ff_opus_rc_dec_log(OpusDecRangeCoder *rc, uint32_t bits);
+
+uint32_t ff_opus_rc_dec_uint_step(OpusDecRangeCoder *rc, int k0);
+
+uint32_t ff_opus_rc_dec_uint_tri(OpusDecRangeCoder *rc, int qn);
+
+uint32_t ff_opus_rc_dec_uint(OpusDecRangeCoder *rc, uint32_t size);
+
+uint32_t ff_opus_rc_get_raw(OpusDecRangeCoder *rc, uint32_t count);
+
+int ff_opus_rc_dec_laplace(OpusDecRangeCoder *rc, uint32_t symbol, int decay);
+
+int ff_opus_rc_dec_init(OpusDecRangeCoder *rc, const uint8_t *data, int size);
+
+#endif /* AVCODEC_OPUSDEC_RC_H */
diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c
index 280425c74f..f1283827b7 100644
--- a/libavcodec/opusenc.c
+++ b/libavcodec/opusenc.c
@@ -25,6 +25,7 @@
#include "opusenc.h"
#include "opus_pvq.h"
#include "opusenc_psy.h"
+#include "opusenc_rc.h"
#include "opustab.h"
#include "libavutil/channel_layout.h"
@@ -55,7 +56,7 @@ typedef struct OpusEncContext {
int channels;
CeltFrame *frame;
- OpusRangeCoder *rc;
+ OpusEncRangeCoder *rc;
/* Actual energy the decoder will have */
float last_quantized_energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
@@ -258,15 +259,15 @@ static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f)
}
}
-static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_enc_tf(CeltFrame *f, OpusEncRangeCoder *rc)
{
int tf_select = 0, diff = 0, tf_changed = 0, tf_select_needed;
int bits = f->transient ? 2 : 4;
- tf_select_needed = ((f->size && (opus_rc_tell(rc) + bits + 1) <= f->framebits));
+ tf_select_needed = ((f->size && (opus_rc_tell(&rc->c) + bits + 1) <= f->framebits));
for (int i = f->start_band; i < f->end_band; i++) {
- if ((opus_rc_tell(rc) + bits + tf_select_needed) <= f->framebits) {
+ if ((opus_rc_tell(&rc->c) + bits + tf_select_needed) <= f->framebits) {
const int tbit = (diff ^ 1) == f->tf_change[i];
ff_opus_rc_enc_log(rc, tbit, bits);
diff ^= tbit;
@@ -285,7 +286,7 @@ static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc)
f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
}
-static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f)
+static void celt_enc_quant_pfilter(OpusEncRangeCoder *rc, CeltFrame *f)
{
float gain = f->pf_gain;
int txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset;
@@ -307,7 +308,7 @@ static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f)
ff_opus_rc_put_raw(rc, txval, 3);
gain = 0.09375f * (txval + 1);
/* Tapset */
- if ((opus_rc_tell(rc) + 2) <= f->framebits)
+ if ((opus_rc_tell(&rc->c) + 2) <= f->framebits)
ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset);
else
tapset = 0;
@@ -322,14 +323,14 @@ static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f)
}
}
-static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f,
+static void exp_quant_coarse(OpusEncRangeCoder *rc, CeltFrame *f,
float last_energy[][CELT_MAX_BANDS], int intra)
{
float alpha, beta, prev[2] = { 0, 0 };
const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra];
/* Inter is really just differential coding */
- if (opus_rc_tell(rc) + 3 <= f->framebits)
+ if (opus_rc_tell(&rc->c) + 3 <= f->framebits)
ff_opus_rc_enc_log(rc, intra, 3);
else
intra = 0;
@@ -345,7 +346,7 @@ static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f,
for (int i = f->start_band; i < f->end_band; i++) {
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
- const int left = f->framebits - opus_rc_tell(rc);
+ const int left = f->framebits - opus_rc_tell(&rc->c);
const float last = FFMAX(-9.0f, last_energy[ch][i]);
float diff = block->energy[i] - prev[ch] - last*alpha;
int q_en = lrintf(diff);
@@ -365,7 +366,7 @@ static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f,
}
}
-static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc,
+static void celt_quant_coarse(CeltFrame *f, OpusEncRangeCoder *rc,
float last_energy[][CELT_MAX_BANDS])
{
uint32_t inter, intra;
@@ -385,7 +386,7 @@ static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc,
}
}
-static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc)
+static void celt_quant_fine(CeltFrame *f, OpusEncRangeCoder *rc)
{
for (int i = f->start_band; i < f->end_band; i++) {
if (!f->fine_bits[i])
@@ -402,10 +403,10 @@ static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc)
}
}
-static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f)
+static void celt_quant_final(OpusEncContext *s, OpusEncRangeCoder *rc, CeltFrame *f)
{
for (int priority = 0; priority < 2; priority++) {
- for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(rc)) >= f->channels; i++) {
+ for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(&rc->c)) >= f->channels; i++) {
if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
continue;
for (int ch = 0; ch < f->channels; ch++) {
@@ -420,7 +421,7 @@ static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f
}
}
-static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc,
+static void celt_encode_frame(OpusEncContext *s, OpusEncRangeCoder *rc,
CeltFrame *f, int index)
{
ff_opus_rc_enc_init(rc);
@@ -457,19 +458,19 @@ static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc,
ff_opus_rc_enc_log(rc, 0, 15);
/* Pitch filter */
- if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits)
+ if (!f->start_band && opus_rc_tell(&rc->c) + 16 <= f->framebits)
celt_enc_quant_pfilter(rc, f);
/* Transient flag */
- if (f->size && opus_rc_tell(rc) + 3 <= f->framebits)
+ if (f->size && opus_rc_tell(&rc->c) + 3 <= f->framebits)
ff_opus_rc_enc_log(rc, f->transient, 3);
/* Main encoding */
celt_quant_coarse (f, rc, s->last_quantized_energy);
celt_enc_tf (f, rc);
- ff_celt_bitalloc (f, rc, 1);
+ ff_celt_bitalloc (f, &rc->c, 1);
celt_quant_fine (f, rc);
- ff_celt_quant_bands(f, rc);
+ ff_celt_quant_bands(f, &rc->c);
/* Anticollapse bit */
if (f->anticollapse_needed)
@@ -694,7 +695,7 @@ static av_cold int opus_encode_init(AVCodecContext *avctx)
s->frame = av_malloc(max_frames*sizeof(CeltFrame));
if (!s->frame)
return AVERROR(ENOMEM);
- s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder));
+ s->rc = av_malloc_array(max_frames, sizeof(*s->rc));
if (!s->rc)
return AVERROR(ENOMEM);
diff --git a/libavcodec/opusenc_psy.c b/libavcodec/opusenc_psy.c
index 48ccd2ebd0..17a2efd8d5 100644
--- a/libavcodec/opusenc_psy.c
+++ b/libavcodec/opusenc_psy.c
@@ -22,12 +22,13 @@
#include <float.h>
#include "opusenc_psy.h"
+#include "opusenc_rc.h"
#include "opus_celt.h"
#include "opus_pvq.h"
#include "opustab.h"
#include "libavfilter/window_func.h"
-static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band,
+static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusEncRangeCoder *rce, int band,
float *bits, float lambda)
{
int i, b = 0;
@@ -39,7 +40,8 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b
float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size);
float *Y = (f->channels == 2) ? &buf[176] : NULL;
float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size);
- OPUS_RC_CHECKPOINT_SPAWN(rc);
+ OpusRangeCoder *const rc = &rce->c;
+ OPUS_RC_CHECKPOINT_SPAWN(rce);
memcpy(X, X_orig, band_size*sizeof(float));
if (Y)
@@ -69,10 +71,10 @@ static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int b
}
dist = sqrtf(err_x) + sqrtf(err_y);
- cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f;
+ cost = OPUS_RC_CHECKPOINT_BITS(rce)/8.0f;
*bits += cost;
- OPUS_RC_CHECKPOINT_ROLLBACK(rc);
+ OPUS_RC_CHECKPOINT_ROLLBACK(rce);
return lambda*dist*cost;
}
@@ -366,10 +368,10 @@ static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start,
static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist)
{
int i, tdist = 0.0f;
- OpusRangeCoder dump;
+ OpusEncRangeCoder dump;
ff_opus_rc_enc_init(&dump);
- ff_celt_bitalloc(f, &dump, 1);
+ ff_celt_bitalloc(f, &dump.c, 1);
for (i = 0; i < CELT_MAX_BANDS; i++) {
float bits = 0.0f;
diff --git a/libavcodec/opusenc_psy.h b/libavcodec/opusenc_psy.h
index bc1a88c03d..2d35e76d2c 100644
--- a/libavcodec/opusenc_psy.h
+++ b/libavcodec/opusenc_psy.h
@@ -26,6 +26,7 @@
#include "libavutil/mem_internal.h"
#include "opusenc.h"
+#include "opusenc_rc.h"
#include "opus_celt.h"
#include "opusenc_utils.h"
diff --git a/libavcodec/opusenc_rc.c b/libavcodec/opusenc_rc.c
new file mode 100644
index 0000000000..6c749c3a34
--- /dev/null
+++ b/libavcodec/opusenc_rc.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2017 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
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/intreadwrite.h"
+
+#include "opusenc_rc.h"
+
+#define OPUS_RC_BITS 32
+#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1)
+
+static av_always_inline void opus_rc_enc_carryout(OpusEncRangeCoder *rc, int cbuf)
+{
+ const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL;
+ if (cbuf == OPUS_RC_CEIL) {
+ rc->ext++;
+ return;
+ }
+ rc->rng_cur[0] = rc->rem + cb;
+ rc->rng_cur += (rc->rem >= 0);
+ for (; rc->ext > 0; rc->ext--)
+ *rc->rng_cur++ = mb;
+ av_assert0(rc->rng_cur < rc->c.rb.position);
+ rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */
+}
+
+static av_always_inline void opus_rc_enc_normalize(OpusEncRangeCoder *rc)
+{
+ while (rc->c.range <= OPUS_RC_BOT) {
+ opus_rc_enc_carryout(rc, rc->c.value >> OPUS_RC_SHIFT);
+ rc->c.value = (rc->c.value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
+ rc->c.range <<= OPUS_RC_SYM;
+ rc->c.total_bits += OPUS_RC_SYM;
+ }
+}
+
+/* Main encoding function, this needs to go fast */
+static av_always_inline void opus_rc_enc_update(OpusEncRangeCoder *rc, uint32_t b, uint32_t p,
+ uint32_t p_tot, const int ptwo)
+{
+ uint32_t rscaled, cnd = !!b;
+ if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */
+ rscaled = rc->c.range >> ff_log2(p_tot);
+ else
+ rscaled = rc->c.range/p_tot;
+ rc->c.value += cnd*(rc->c.range - rscaled*(p_tot - b));
+ rc->c.range = (!cnd)*(rc->c.range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b);
+ opus_rc_enc_normalize(rc);
+}
+
+void ff_opus_rc_enc_cdf(OpusEncRangeCoder *rc, int val, const uint16_t *cdf)
+{
+ opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1);
+}
+
+void ff_opus_rc_enc_log(OpusEncRangeCoder *rc, int val, uint32_t bits)
+{
+ bits = (1 << bits) - 1;
+ opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1);
+}
+
+/**
+ * CELT: write 0 - 31 bits to the rawbits buffer
+ */
+void ff_opus_rc_put_raw(OpusEncRangeCoder *rc, uint32_t val, uint32_t count)
+{
+ const int to_write = FFMIN(32 - rc->c.rb.cachelen, count);
+
+ rc->c.total_bits += count;
+ rc->c.rb.cacheval |= av_mod_uintp2(val, to_write) << rc->c.rb.cachelen;
+ rc->c.rb.cachelen = (rc->c.rb.cachelen + to_write) % 32;
+
+ if (!rc->c.rb.cachelen && count) {
+ AV_WB32((uint8_t *)rc->c.rb.position, rc->c.rb.cacheval);
+ rc->c.rb.bytes += 4;
+ rc->c.rb.position -= 4;
+ rc->c.rb.cachelen = count - to_write;
+ rc->c.rb.cacheval = av_mod_uintp2(val >> to_write, rc->c.rb.cachelen);
+ av_assert0(rc->rng_cur < rc->c.rb.position);
+ }
+}
+
+/**
+ * CELT: write a uniformly distributed integer
+ */
+void ff_opus_rc_enc_uint(OpusEncRangeCoder *rc, uint32_t val, uint32_t size)
+{
+ const int ps = FFMAX(opus_ilog(size - 1) - 8, 0);
+ opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0);
+ ff_opus_rc_put_raw(rc, val, ps);
+}
+
+void ff_opus_rc_enc_uint_step(OpusEncRangeCoder *rc, uint32_t val, int k0)
+{
+ const uint32_t a = val <= k0, b = 2*a + 1;
+ k0 = (k0 + 1) << 1;
+ val = b*(val + k0) - 3*a*k0;
+ opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0);
+}
+
+void ff_opus_rc_enc_uint_tri(OpusEncRangeCoder *rc, uint32_t k, int qn)
+{
+ uint32_t symbol, low, total;
+
+ total = ((qn>>1) + 1) * ((qn>>1) + 1);
+
+ if (k <= qn >> 1) {
+ low = k * (k + 1) >> 1;
+ symbol = k + 1;
+ } else {
+ low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
+ symbol = qn + 1 - k;
+ }
+
+ opus_rc_enc_update(rc, low, low + symbol, total, 0);
+}
+
+void ff_opus_rc_enc_laplace(OpusEncRangeCoder *rc, int *value, uint32_t symbol, int decay)
+{
+ uint32_t low = symbol;
+ int i = 1, val = FFABS(*value), pos = *value > 0;
+ if (!val) {
+ opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1);
+ return;
+ }
+ symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15;
+ for (; i < val && symbol; i++) {
+ low += (symbol << 1) + 2;
+ symbol = (symbol*decay) >> 14;
+ }
+ if (symbol) {
+ low += (++symbol)*pos;
+ } else {
+ const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1);
+ low += pos + (distance << 1);
+ symbol = FFMIN(1, 32768 - low);
+ *value = FFSIGN(*value)*(distance + i);
+ }
+ opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1);
+}
+
+void ff_opus_rc_enc_end(OpusEncRangeCoder *rc, uint8_t *dst, int size)
+{
+ int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->c.range);
+ uint32_t mask = (OPUS_RC_TOP - 1) >> bits;
+ uint32_t end = (rc->c.value + mask) & ~mask;
+
+ if ((end | mask) >= rc->c.value + rc->c.range) {
+ bits++;
+ mask >>= 1;
+ end = (rc->c.value + mask) & ~mask;
+ }
+
+ /* Finish what's left */
+ while (bits > 0) {
+ opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT);
+ end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
+ bits -= OPUS_RC_SYM;
+ }
+
+ /* Flush out anything left or marked */
+ if (rc->rem >= 0 || rc->ext > 0)
+ opus_rc_enc_carryout(rc, 0);
+
+ rng_bytes = rc->rng_cur - rc->buf;
+ memcpy(dst, rc->buf, rng_bytes);
+
+ /* Put the rawbits part, if any */
+ if (rc->c.rb.bytes || rc->c.rb.cachelen) {
+ int lap;
+ uint8_t *rb_src, *rb_dst;
+ ff_opus_rc_put_raw(rc, 0, 32 - rc->c.rb.cachelen);
+ rb_src = rc->buf + OPUS_MAX_FRAME_SIZE + 12 - rc->c.rb.bytes;
+ rb_dst = dst + FFMAX(size - rc->c.rb.bytes, 0);
+ lap = &dst[rng_bytes] - rb_dst;
+ for (int i = 0; i < lap; i++)
+ rb_dst[i] |= rb_src[i];
+ memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->c.rb.bytes - lap, 0));
+ }
+}
+
+void ff_opus_rc_enc_init(OpusEncRangeCoder *rc)
+{
+ rc->c.value = 0;
+ rc->c.range = OPUS_RC_TOP;
+ rc->c.total_bits = OPUS_RC_BITS + 1;
+ rc->rem = -1;
+ rc->ext = 0;
+ rc->rng_cur = rc->buf;
+ ff_opus_rc_raw_init(&rc->c, rc->buf + OPUS_MAX_FRAME_SIZE + 8, 0);
+}
diff --git a/libavcodec/opusenc_rc.h b/libavcodec/opusenc_rc.h
new file mode 100644
index 0000000000..40c48d04f0
--- /dev/null
+++ b/libavcodec/opusenc_rc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla Corporation
+ * Copyright (c) 2017 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_OPUSENC_RC_H
+#define AVCODEC_OPUSENC_RC_H
+
+#include <stdint.h>
+
+#include "opus.h"
+#include "opus_rc.h"
+
+typedef struct OpusEncRangeCoder {
+ OpusRangeCoder c;
+
+ uint8_t *rng_cur; /* Current range coded byte */
+ int ext; /* Awaiting propagation */
+ int rem; /* Carryout flag */
+ uint8_t buf[OPUS_MAX_FRAME_SIZE + 12]; /* memcpy vs (memmove + overreading) */
+} OpusEncRangeCoder;
+
+void ff_opus_rc_enc_cdf(OpusEncRangeCoder *rc, int val, const uint16_t *cdf);
+void ff_opus_rc_enc_log(OpusEncRangeCoder *rc, int val, uint32_t bits);
+void ff_opus_rc_enc_uint_step(OpusEncRangeCoder *rc, uint32_t val, int k0);
+void ff_opus_rc_enc_uint_tri(OpusEncRangeCoder *rc, uint32_t k, int qn);
+void ff_opus_rc_enc_uint(OpusEncRangeCoder *rc, uint32_t val, uint32_t size);
+void ff_opus_rc_put_raw(OpusEncRangeCoder *rc, uint32_t val, uint32_t count);
+void ff_opus_rc_enc_laplace(OpusEncRangeCoder *rc, int *value, uint32_t symbol, int decay);
+void ff_opus_rc_enc_end(OpusEncRangeCoder *rc, uint8_t *dst, int size);
+void ff_opus_rc_enc_init(OpusEncRangeCoder *rc);
+
+#define OPUS_RC_CHECKPOINT_UPDATE(rc) \
+ rc_rollback_bits = opus_rc_tell_frac(&rc->c); \
+ rc_rollback_ctx = *rc
+
+#define OPUS_RC_CHECKPOINT_SPAWN(rc) \
+ uint32_t rc_rollback_bits = opus_rc_tell_frac(&rc->c); \
+ OpusEncRangeCoder rc_rollback_ctx = *rc \
+
+#define OPUS_RC_CHECKPOINT_BITS(rc) \
+ (opus_rc_tell_frac(&rc->c) - rc_rollback_bits)
+
+#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \
+ memcpy(rc, &rc_rollback_ctx, sizeof(*rc)); \
+
+#endif /* AVCODEC_OPUSENC_RC_H */
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* [FFmpeg-devel] [PATCH 8/9] avcodec/opus: Rename opus.c->opus_celt.c, opus_celt.c->opusdec_celt.c
2022-10-07 20:20 [FFmpeg-devel] [PATCH 1/9] avcodec/opus_rc: Remove write-only waste from OpusRangeCoder Andreas Rheinhardt
` (5 preceding siblings ...)
2022-10-07 20:25 ` [FFmpeg-devel] [PATCH 7/9] avcodec/opus_rc: Split de/encoder-only parts off OpusRangeContext Andreas Rheinhardt
@ 2022-10-07 20:25 ` Andreas Rheinhardt
2022-10-07 20:25 ` [FFmpeg-devel] [PATCH 9/9] avcodec/opus_pvq: Avoid indirection when possible Andreas Rheinhardt
2022-10-08 3:25 ` [FFmpeg-devel] [PATCH 1/9] avcodec/opus_rc: Remove write-only waste from OpusRangeCoder Lynne
8 siblings, 0 replies; 10+ messages in thread
From: Andreas Rheinhardt @ 2022-10-07 20:25 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Andreas Rheinhardt
Since commit 4fc2531fff112836026aad2bdaf128c9d15a72e3 opus.c
contains only the celt stuff shared between decoder and encoder.
meanwhile, opus_celt.c is decoder-only. So the new names
reflect the actual content better than the current ones.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/Makefile | 4 +-
libavcodec/opus.c | 522 ----------------------
libavcodec/opus_celt.c | 899 ++++++++++++++++++--------------------
libavcodec/opusdec_celt.c | 587 +++++++++++++++++++++++++
4 files changed, 1006 insertions(+), 1006 deletions(-)
delete mode 100644 libavcodec/opus.c
create mode 100644 libavcodec/opusdec_celt.c
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index b7eb3b1e48..949c65a0e3 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -554,10 +554,10 @@ OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.o
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
-OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o \
+OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opusdec_celt.o opus_celt.o \
opus_pvq.o opus_silk.o opustab.o vorbis_data.o \
opusdec_rc.o opusdsp.o opus_parse.o
-OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus.o opusenc_psy.o \
+OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opus_celt.o opusenc_psy.o \
opusenc_rc.o opustab.o opus_pvq.o
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
diff --git a/libavcodec/opus.c b/libavcodec/opus.c
deleted file mode 100644
index 8def5e6e34..0000000000
--- a/libavcodec/opus.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright (c) 2012 Andrew D'Addesio
- * Copyright (c) 2013-2014 Mozilla Corporation
- *
- * 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
- */
-
-#include <stdint.h>
-
-#include "config_components.h"
-#include "opus_celt.h"
-#include "opus_pvq.h"
-#include "opustab.h"
-#include "opus_rc.h"
-#include "opusdec_rc.h"
-#include "opusenc_rc.h"
-
-#if !CONFIG_OPUS_ENCODER
-#define ff_opus_rc_enc_log(...)
-#define ff_opus_rc_enc_cdf(...)
-#define ff_opus_rc_enc_uint(...)
-#endif
-
-#if !CONFIG_OPUS_DECODER
-#define ff_opus_rc_dec_log(...) 0
-#define ff_opus_rc_dec_cdf(...) 0
-#define ff_opus_rc_dec_uint(...) 0
-#endif
-
-static inline void opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits)
-{
- ff_opus_rc_enc_log((OpusEncRangeCoder*)rc, val, bits);
-}
-
-static inline uint32_t opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits)
-{
- return ff_opus_rc_dec_log((OpusDecRangeCoder*)rc, bits);
-}
-
-static inline void opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf)
-{
- ff_opus_rc_enc_cdf((OpusEncRangeCoder*)rc, val, cdf);
-}
-
-static inline uint32_t opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf)
-{
- return ff_opus_rc_dec_cdf((OpusDecRangeCoder*)rc, cdf);
-}
-
-void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc)
-{
- float lowband_scratch[8 * 22];
- float norm1[2 * 8 * 100];
- float *norm2 = norm1 + 8 * 100;
-
- int totalbits = (f->framebits << 3) - f->anticollapse_needed;
-
- int update_lowband = 1;
- int lowband_offset = 0;
-
- int i, j;
-
- for (i = f->start_band; i < f->end_band; i++) {
- uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };
- int band_offset = ff_celt_freq_bands[i] << f->size;
- int band_size = ff_celt_freq_range[i] << f->size;
- float *X = f->block[0].coeffs + band_offset;
- float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL;
- float *norm_loc1, *norm_loc2;
-
- int consumed = opus_rc_tell_frac(rc);
- int effective_lowband = -1;
- int b = 0;
-
- /* Compute how many bits we want to allocate to this band */
- if (i != f->start_band)
- f->remaining -= consumed;
- f->remaining2 = totalbits - consumed - 1;
- if (i <= f->coded_bands - 1) {
- int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i);
- b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);
- }
-
- if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] ||
- i == f->start_band + 1) && (update_lowband || lowband_offset == 0))
- lowband_offset = i;
-
- if (i == f->start_band + 1) {
- /* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into
- the second to ensure the second band never has to use the LCG. */
- int count = (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]) << f->size;
-
- memcpy(&norm1[band_offset], &norm1[band_offset - count], count * sizeof(float));
-
- if (f->channels == 2)
- memcpy(&norm2[band_offset], &norm2[band_offset - count], count * sizeof(float));
- }
-
- /* Get a conservative estimate of the collapse_mask's for the bands we're
- going to be folding from. */
- if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||
- f->blocks > 1 || f->tf_change[i] < 0)) {
- int foldstart, foldend;
-
- /* This ensures we never repeat spectral content within one band */
- effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band],
- ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]);
- foldstart = lowband_offset;
- while (ff_celt_freq_bands[--foldstart] > effective_lowband);
- foldend = lowband_offset - 1;
- while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]);
-
- cm[0] = cm[1] = 0;
- for (j = foldstart; j < foldend; j++) {
- cm[0] |= f->block[0].collapse_masks[j];
- cm[1] |= f->block[f->channels - 1].collapse_masks[j];
- }
- }
-
- if (f->dual_stereo && i == f->intensity_stereo) {
- /* Switch off dual stereo to do intensity */
- f->dual_stereo = 0;
- for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++)
- norm1[j] = (norm1[j] + norm2[j]) / 2;
- }
-
- norm_loc1 = effective_lowband != -1 ? norm1 + (effective_lowband << f->size) : NULL;
- norm_loc2 = effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL;
-
- if (f->dual_stereo) {
- cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, NULL, band_size, b >> 1,
- f->blocks, norm_loc1, f->size,
- norm1 + band_offset, 0, 1.0f,
- lowband_scratch, cm[0]);
-
- cm[1] = f->pvq->quant_band(f->pvq, f, rc, i, Y, NULL, band_size, b >> 1,
- f->blocks, norm_loc2, f->size,
- norm2 + band_offset, 0, 1.0f,
- lowband_scratch, cm[1]);
- } else {
- cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, Y, band_size, b >> 0,
- f->blocks, norm_loc1, f->size,
- norm1 + band_offset, 0, 1.0f,
- lowband_scratch, cm[0] | cm[1]);
- cm[1] = cm[0];
- }
-
- f->block[0].collapse_masks[i] = (uint8_t)cm[0];
- f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1];
- f->remaining += f->pulses[i] + consumed;
-
- /* Update the folding position only as long as we have 1 bit/sample depth */
- update_lowband = (b > band_size << 3);
- }
-}
-
-#define NORMC(bits) ((bits) << (f->channels - 1) << f->size >> 2)
-
-void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
-{
- int i, j, low, high, total, done, bandbits, remaining, tbits_8ths;
- int skip_startband = f->start_band;
- int skip_bit = 0;
- int intensitystereo_bit = 0;
- int dualstereo_bit = 0;
- int dynalloc = 6;
- int extrabits = 0;
-
- int boost[CELT_MAX_BANDS] = { 0 };
- int trim_offset[CELT_MAX_BANDS];
- int threshold[CELT_MAX_BANDS];
- int bits1[CELT_MAX_BANDS];
- int bits2[CELT_MAX_BANDS];
-
- if (!CONFIG_OPUS_DECODER || !CONFIG_OPUS_ENCODER)
- encode = CONFIG_OPUS_ENCODER;
- /* Spread */
- if (opus_rc_tell(rc) + 4 <= f->framebits) {
- if (encode)
- opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread);
- else
- f->spread = opus_rc_dec_cdf(rc, ff_celt_model_spread);
- } else {
- f->spread = CELT_SPREAD_NORMAL;
- }
-
- /* Initialize static allocation caps */
- for (i = 0; i < CELT_MAX_BANDS; i++)
- f->caps[i] = NORMC((ff_celt_static_caps[f->size][f->channels - 1][i] + 64) * ff_celt_freq_range[i]);
-
- /* Band boosts */
- tbits_8ths = f->framebits << 3;
- for (i = f->start_band; i < f->end_band; i++) {
- int quanta = ff_celt_freq_range[i] << (f->channels - 1) << f->size;
- int b_dynalloc = dynalloc;
- int boost_amount = f->alloc_boost[i];
- quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
-
- while (opus_rc_tell_frac(rc) + (b_dynalloc << 3) < tbits_8ths && boost[i] < f->caps[i]) {
- int is_boost;
- if (encode) {
- is_boost = boost_amount--;
- opus_rc_enc_log(rc, is_boost, b_dynalloc);
- } else {
- is_boost = opus_rc_dec_log(rc, b_dynalloc);
- }
-
- if (!is_boost)
- break;
-
- boost[i] += quanta;
- tbits_8ths -= quanta;
-
- b_dynalloc = 1;
- }
-
- if (boost[i])
- dynalloc = FFMAX(dynalloc - 1, 2);
- }
-
- /* Allocation trim */
- if (!encode)
- f->alloc_trim = 5;
- if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths)
- if (encode)
- opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim);
- else
- f->alloc_trim = opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
-
- /* Anti-collapse bit reservation */
- tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1;
- f->anticollapse_needed = 0;
- if (f->transient && f->size >= 2 && tbits_8ths >= ((f->size + 2) << 3))
- f->anticollapse_needed = 1 << 3;
- tbits_8ths -= f->anticollapse_needed;
-
- /* Band skip bit reservation */
- if (tbits_8ths >= 1 << 3)
- skip_bit = 1 << 3;
- tbits_8ths -= skip_bit;
-
- /* Intensity/dual stereo bit reservation */
- if (f->channels == 2) {
- intensitystereo_bit = ff_celt_log2_frac[f->end_band - f->start_band];
- if (intensitystereo_bit <= tbits_8ths) {
- tbits_8ths -= intensitystereo_bit;
- if (tbits_8ths >= 1 << 3) {
- dualstereo_bit = 1 << 3;
- tbits_8ths -= 1 << 3;
- }
- } else {
- intensitystereo_bit = 0;
- }
- }
-
- /* Trim offsets */
- for (i = f->start_band; i < f->end_band; i++) {
- int trim = f->alloc_trim - 5 - f->size;
- int band = ff_celt_freq_range[i] * (f->end_band - i - 1);
- int duration = f->size + 3;
- int scale = duration + f->channels - 1;
-
- /* PVQ minimum allocation threshold, below this value the band is
- * skipped */
- threshold[i] = FFMAX(3 * ff_celt_freq_range[i] << duration >> 4,
- f->channels << 3);
-
- trim_offset[i] = trim * (band << scale) >> 6;
-
- if (ff_celt_freq_range[i] << f->size == 1)
- trim_offset[i] -= f->channels << 3;
- }
-
- /* Bisection */
- low = 1;
- high = CELT_VECTORS - 1;
- while (low <= high) {
- int center = (low + high) >> 1;
- done = total = 0;
-
- for (i = f->end_band - 1; i >= f->start_band; i--) {
- bandbits = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[center][i]);
-
- if (bandbits)
- bandbits = FFMAX(bandbits + trim_offset[i], 0);
- bandbits += boost[i];
-
- if (bandbits >= threshold[i] || done) {
- done = 1;
- total += FFMIN(bandbits, f->caps[i]);
- } else if (bandbits >= f->channels << 3) {
- total += f->channels << 3;
- }
- }
-
- if (total > tbits_8ths)
- high = center - 1;
- else
- low = center + 1;
- }
- high = low--;
-
- /* Bisection */
- for (i = f->start_band; i < f->end_band; i++) {
- bits1[i] = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[low][i]);
- bits2[i] = high >= CELT_VECTORS ? f->caps[i] :
- NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[high][i]);
-
- if (bits1[i])
- bits1[i] = FFMAX(bits1[i] + trim_offset[i], 0);
- if (bits2[i])
- bits2[i] = FFMAX(bits2[i] + trim_offset[i], 0);
-
- if (low)
- bits1[i] += boost[i];
- bits2[i] += boost[i];
-
- if (boost[i])
- skip_startband = i;
- bits2[i] = FFMAX(bits2[i] - bits1[i], 0);
- }
-
- /* Bisection */
- low = 0;
- high = 1 << CELT_ALLOC_STEPS;
- for (i = 0; i < CELT_ALLOC_STEPS; i++) {
- int center = (low + high) >> 1;
- done = total = 0;
-
- for (j = f->end_band - 1; j >= f->start_band; j--) {
- bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS);
-
- if (bandbits >= threshold[j] || done) {
- done = 1;
- total += FFMIN(bandbits, f->caps[j]);
- } else if (bandbits >= f->channels << 3)
- total += f->channels << 3;
- }
- if (total > tbits_8ths)
- high = center;
- else
- low = center;
- }
-
- /* Bisection */
- done = total = 0;
- for (i = f->end_band - 1; i >= f->start_band; i--) {
- bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS);
-
- if (bandbits >= threshold[i] || done)
- done = 1;
- else
- bandbits = (bandbits >= f->channels << 3) ?
- f->channels << 3 : 0;
-
- bandbits = FFMIN(bandbits, f->caps[i]);
- f->pulses[i] = bandbits;
- total += bandbits;
- }
-
- /* Band skipping */
- for (f->coded_bands = f->end_band; ; f->coded_bands--) {
- int allocation;
- j = f->coded_bands - 1;
-
- if (j == skip_startband) {
- /* all remaining bands are not skipped */
- tbits_8ths += skip_bit;
- break;
- }
-
- /* determine the number of bits available for coding "do not skip" markers */
- remaining = tbits_8ths - total;
- bandbits = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
- remaining -= bandbits * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
- allocation = f->pulses[j] + bandbits * ff_celt_freq_range[j];
- allocation += FFMAX(remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[f->start_band]), 0);
-
- /* a "do not skip" marker is only coded if the allocation is
- * above the chosen threshold */
- if (allocation >= FFMAX(threshold[j], (f->channels + 1) << 3)) {
- int do_not_skip;
- if (encode) {
- do_not_skip = f->coded_bands <= f->skip_band_floor;
- opus_rc_enc_log(rc, do_not_skip, 1);
- } else {
- do_not_skip = opus_rc_dec_log(rc, 1);
- }
-
- if (do_not_skip)
- break;
-
- total += 1 << 3;
- allocation -= 1 << 3;
- }
-
- /* the band is skipped, so reclaim its bits */
- total -= f->pulses[j];
- if (intensitystereo_bit) {
- total -= intensitystereo_bit;
- intensitystereo_bit = ff_celt_log2_frac[j - f->start_band];
- total += intensitystereo_bit;
- }
-
- total += f->pulses[j] = (allocation >= f->channels << 3) ? f->channels << 3 : 0;
- }
-
- /* IS start band */
- if (encode) {
- if (intensitystereo_bit) {
- f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands);
- ff_opus_rc_enc_uint((OpusEncRangeCoder*)rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band);
- }
- } else {
- f->intensity_stereo = f->dual_stereo = 0;
- if (intensitystereo_bit)
- f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint((OpusDecRangeCoder*)rc, f->coded_bands + 1 - f->start_band);
- }
-
- /* DS flag */
- if (f->intensity_stereo <= f->start_band)
- tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */
- else if (dualstereo_bit)
- if (encode)
- opus_rc_enc_log(rc, f->dual_stereo, 1);
- else
- f->dual_stereo = opus_rc_dec_log(rc, 1);
-
- /* Supply the remaining bits in this frame to lower bands */
- remaining = tbits_8ths - total;
- bandbits = remaining / (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
- remaining -= bandbits * (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
- for (i = f->start_band; i < f->coded_bands; i++) {
- const int bits = FFMIN(remaining, ff_celt_freq_range[i]);
- f->pulses[i] += bits + bandbits * ff_celt_freq_range[i];
- remaining -= bits;
- }
-
- /* Finally determine the allocation */
- for (i = f->start_band; i < f->coded_bands; i++) {
- int N = ff_celt_freq_range[i] << f->size;
- int prev_extra = extrabits;
- f->pulses[i] += extrabits;
-
- if (N > 1) {
- int dof; /* degrees of freedom */
- int temp; /* dof * channels * log(dof) */
- int fine_bits;
- int max_bits;
- int offset; /* fine energy quantization offset, i.e.
- * extra bits assigned over the standard
- * totalbits/dof */
-
- extrabits = FFMAX(f->pulses[i] - f->caps[i], 0);
- f->pulses[i] -= extrabits;
-
- /* intensity stereo makes use of an extra degree of freedom */
- dof = N * f->channels + (f->channels == 2 && N > 2 && !f->dual_stereo && i < f->intensity_stereo);
- temp = dof * (ff_celt_log_freq_range[i] + (f->size << 3));
- offset = (temp >> 1) - dof * CELT_FINE_OFFSET;
- if (N == 2) /* dof=2 is the only case that doesn't fit the model */
- offset += dof << 1;
-
- /* grant an additional bias for the first and second pulses */
- if (f->pulses[i] + offset < 2 * (dof << 3))
- offset += temp >> 2;
- else if (f->pulses[i] + offset < 3 * (dof << 3))
- offset += temp >> 3;
-
- fine_bits = (f->pulses[i] + offset + (dof << 2)) / (dof << 3);
- max_bits = FFMIN((f->pulses[i] >> 3) >> (f->channels - 1), CELT_MAX_FINE_BITS);
- max_bits = FFMAX(max_bits, 0);
- f->fine_bits[i] = av_clip(fine_bits, 0, max_bits);
-
- /* If fine_bits was rounded down or capped,
- * give priority for the final fine energy pass */
- f->fine_priority[i] = (f->fine_bits[i] * (dof << 3) >= f->pulses[i] + offset);
-
- /* the remaining bits are assigned to PVQ */
- f->pulses[i] -= f->fine_bits[i] << (f->channels - 1) << 3;
- } else {
- /* all bits go to fine energy except for the sign bit */
- extrabits = FFMAX(f->pulses[i] - (f->channels << 3), 0);
- f->pulses[i] -= extrabits;
- f->fine_bits[i] = 0;
- f->fine_priority[i] = 1;
- }
-
- /* hand back a limited number of extra fine energy bits to this band */
- if (extrabits > 0) {
- int fineextra = FFMIN(extrabits >> (f->channels + 2),
- CELT_MAX_FINE_BITS - f->fine_bits[i]);
- f->fine_bits[i] += fineextra;
-
- fineextra <<= f->channels + 2;
- f->fine_priority[i] = (fineextra >= extrabits - prev_extra);
- extrabits -= fineextra;
- }
- }
- f->remaining = extrabits;
-
- /* skipped bands dedicate all of their bits for fine energy */
- for (; i < f->end_band; i++) {
- f->fine_bits[i] = f->pulses[i] >> (f->channels - 1) >> 3;
- f->pulses[i] = 0;
- f->fine_priority[i] = f->fine_bits[i] < 1;
- }
-}
diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c
index a14764ec18..8def5e6e34 100644
--- a/libavcodec/opus_celt.c
+++ b/libavcodec/opus_celt.c
@@ -1,7 +1,6 @@
/*
* 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.
*
@@ -20,568 +19,504 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file
- * Opus CELT decoder
- */
-
-#include <float.h>
+#include <stdint.h>
+#include "config_components.h"
#include "opus_celt.h"
-#include "opusdec_rc.h"
-#include "opustab.h"
#include "opus_pvq.h"
+#include "opustab.h"
+#include "opus_rc.h"
+#include "opusdec_rc.h"
+#include "opusenc_rc.h"
-/* Use the 2D z-transform to apply prediction in both the time domain (alpha)
- * and the frequency domain (beta) */
-static void celt_decode_coarse_energy(CeltFrame *f, OpusDecRangeCoder *rc)
-{
- int i, j;
- float prev[2] = { 0 };
- float alpha = ff_celt_alpha_coef[f->size];
- float beta = ff_celt_beta_coef[f->size];
- const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0];
-
- /* intra frame */
- if (opus_rc_tell(&rc->c) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
- alpha = 0.0f;
- beta = 1.0f - (4915.0f/32768.0f);
- model = ff_celt_coarse_energy_dist[f->size][1];
- }
-
- for (i = 0; i < CELT_MAX_BANDS; i++) {
- for (j = 0; j < f->channels; j++) {
- CeltBlock *block = &f->block[j];
- float value;
- int available;
-
- if (i < f->start_band || i >= f->end_band) {
- block->energy[i] = 0.0;
- continue;
- }
+#if !CONFIG_OPUS_ENCODER
+#define ff_opus_rc_enc_log(...)
+#define ff_opus_rc_enc_cdf(...)
+#define ff_opus_rc_enc_uint(...)
+#endif
- available = f->framebits - opus_rc_tell(&rc->c);
- if (available >= 15) {
- /* decode using a Laplace distribution */
- int k = FFMIN(i, 20) << 1;
- value = ff_opus_rc_dec_laplace(rc, model[k] << 7, model[k+1] << 6);
- } else if (available >= 2) {
- int x = ff_opus_rc_dec_cdf(rc, ff_celt_model_energy_small);
- value = (x>>1) ^ -(x&1);
- } else if (available >= 1) {
- value = -(float)ff_opus_rc_dec_log(rc, 1);
- } else value = -1;
-
- block->energy[i] = FFMAX(-9.0f, block->energy[i]) * alpha + prev[j] + value;
- prev[j] += beta * value;
- }
- }
-}
+#if !CONFIG_OPUS_DECODER
+#define ff_opus_rc_dec_log(...) 0
+#define ff_opus_rc_dec_cdf(...) 0
+#define ff_opus_rc_dec_uint(...) 0
+#endif
-static void celt_decode_fine_energy(CeltFrame *f, OpusDecRangeCoder *rc)
+static inline void opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits)
{
- int i;
- for (i = f->start_band; i < f->end_band; i++) {
- int j;
- if (!f->fine_bits[i])
- continue;
-
- for (j = 0; j < f->channels; j++) {
- CeltBlock *block = &f->block[j];
- int q2;
- float offset;
- q2 = ff_opus_rc_get_raw(rc, f->fine_bits[i]);
- offset = (q2 + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f - 0.5f;
- block->energy[i] += offset;
- }
- }
+ ff_opus_rc_enc_log((OpusEncRangeCoder*)rc, val, bits);
}
-static void celt_decode_final_energy(CeltFrame *f, OpusDecRangeCoder *rc)
+static inline uint32_t opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits)
{
- int priority, i, j;
- int bits_left = f->framebits - opus_rc_tell(&rc->c);
-
- for (priority = 0; priority < 2; priority++) {
- for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) {
- if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
- continue;
-
- for (j = 0; j < f->channels; j++) {
- int q2;
- float offset;
- q2 = ff_opus_rc_get_raw(rc, 1);
- offset = (q2 - 0.5f) * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
- f->block[j].energy[i] += offset;
- bits_left--;
- }
- }
- }
+ return ff_opus_rc_dec_log((OpusDecRangeCoder*)rc, bits);
}
-static void celt_decode_tf_changes(CeltFrame *f, OpusDecRangeCoder *rc)
+static inline void opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf)
{
- int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
- int consumed, bits = f->transient ? 2 : 4;
-
- consumed = opus_rc_tell(&rc->c);
- tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits);
-
- for (i = f->start_band; i < f->end_band; i++) {
- if (consumed+bits+tf_select_bit <= f->framebits) {
- diff ^= ff_opus_rc_dec_log(rc, bits);
- consumed = opus_rc_tell(&rc->c);
- tf_changed |= diff;
- }
- f->tf_change[i] = diff;
- bits = f->transient ? 4 : 5;
- }
-
- if (tf_select_bit && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
- ff_celt_tf_select[f->size][f->transient][1][tf_changed])
- tf_select = ff_opus_rc_dec_log(rc, 1);
-
- for (i = f->start_band; i < f->end_band; i++) {
- f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
- }
+ ff_opus_rc_enc_cdf((OpusEncRangeCoder*)rc, val, cdf);
}
-static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data)
+static inline uint32_t opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf)
{
- int i, j;
-
- for (i = f->start_band; i < f->end_band; i++) {
- float *dst = data + (ff_celt_freq_bands[i] << f->size);
- float log_norm = block->energy[i] + ff_celt_mean_energy[i];
- float norm = exp2f(FFMIN(log_norm, 32.0f));
-
- for (j = 0; j < ff_celt_freq_range[i] << f->size; j++)
- dst[j] *= norm;
- }
+ return ff_opus_rc_dec_cdf((OpusDecRangeCoder*)rc, cdf);
}
-static void celt_postfilter_apply_transition(CeltBlock *block, float *data)
+void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc)
{
- const int T0 = block->pf_period_old;
- const int T1 = block->pf_period;
-
- float g00, g01, g02;
- float g10, g11, g12;
-
- float x0, x1, x2, x3, x4;
-
- int i;
-
- if (block->pf_gains[0] == 0.0 &&
- block->pf_gains_old[0] == 0.0)
- return;
-
- g00 = block->pf_gains_old[0];
- g01 = block->pf_gains_old[1];
- g02 = block->pf_gains_old[2];
- g10 = block->pf_gains[0];
- g11 = block->pf_gains[1];
- g12 = block->pf_gains[2];
-
- x1 = data[-T1 + 1];
- x2 = data[-T1];
- x3 = data[-T1 - 1];
- x4 = data[-T1 - 2];
-
- for (i = 0; i < CELT_OVERLAP; i++) {
- float w = ff_celt_window2[i];
- x0 = data[i - T1 + 2];
-
- data[i] += (1.0 - w) * g00 * data[i - T0] +
- (1.0 - w) * g01 * (data[i - T0 - 1] + data[i - T0 + 1]) +
- (1.0 - w) * g02 * (data[i - T0 - 2] + data[i - T0 + 2]) +
- w * g10 * x2 +
- w * g11 * (x1 + x3) +
- w * g12 * (x0 + x4);
- x4 = x3;
- x3 = x2;
- x2 = x1;
- x1 = x0;
- }
-}
+ float lowband_scratch[8 * 22];
+ float norm1[2 * 8 * 100];
+ float *norm2 = norm1 + 8 * 100;
-static void celt_postfilter(CeltFrame *f, CeltBlock *block)
-{
- int len = f->blocksize * f->blocks;
- const int filter_len = len - 2 * CELT_OVERLAP;
+ int totalbits = (f->framebits << 3) - f->anticollapse_needed;
- celt_postfilter_apply_transition(block, block->buf + 1024);
+ int update_lowband = 1;
+ int lowband_offset = 0;
- block->pf_period_old = block->pf_period;
- memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
+ int i, j;
- block->pf_period = block->pf_period_new;
- memcpy(block->pf_gains, block->pf_gains_new, sizeof(block->pf_gains));
+ for (i = f->start_band; i < f->end_band; i++) {
+ uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };
+ int band_offset = ff_celt_freq_bands[i] << f->size;
+ int band_size = ff_celt_freq_range[i] << f->size;
+ float *X = f->block[0].coeffs + band_offset;
+ float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL;
+ float *norm_loc1, *norm_loc2;
+
+ int consumed = opus_rc_tell_frac(rc);
+ int effective_lowband = -1;
+ int b = 0;
+
+ /* Compute how many bits we want to allocate to this band */
+ if (i != f->start_band)
+ f->remaining -= consumed;
+ f->remaining2 = totalbits - consumed - 1;
+ if (i <= f->coded_bands - 1) {
+ int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i);
+ b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);
+ }
- if (len > CELT_OVERLAP) {
- celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP);
+ if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] ||
+ i == f->start_band + 1) && (update_lowband || lowband_offset == 0))
+ lowband_offset = i;
- if (block->pf_gains[0] > FLT_EPSILON && filter_len > 0)
- f->opusdsp.postfilter(block->buf + 1024 + 2 * CELT_OVERLAP,
- block->pf_period, block->pf_gains,
- filter_len);
+ if (i == f->start_band + 1) {
+ /* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into
+ the second to ensure the second band never has to use the LCG. */
+ int count = (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]) << f->size;
- block->pf_period_old = block->pf_period;
- memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
- }
+ memcpy(&norm1[band_offset], &norm1[band_offset - count], count * sizeof(float));
- memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
-}
+ if (f->channels == 2)
+ memcpy(&norm2[band_offset], &norm2[band_offset - count], count * sizeof(float));
+ }
-static int parse_postfilter(CeltFrame *f, OpusDecRangeCoder *rc, int consumed)
-{
- int i;
-
- memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new));
- memset(f->block[1].pf_gains_new, 0, sizeof(f->block[1].pf_gains_new));
-
- if (f->start_band == 0 && consumed + 16 <= f->framebits) {
- int has_postfilter = ff_opus_rc_dec_log(rc, 1);
- if (has_postfilter) {
- float gain;
- int tapset, octave, period;
-
- octave = ff_opus_rc_dec_uint(rc, 6);
- period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1;
- gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1);
- tapset = (opus_rc_tell(&rc->c) + 2 <= f->framebits) ?
- ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;
-
- for (i = 0; i < 2; i++) {
- CeltBlock *block = &f->block[i];
-
- block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
- block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
- block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
- block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
+ /* Get a conservative estimate of the collapse_mask's for the bands we're
+ going to be folding from. */
+ if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||
+ f->blocks > 1 || f->tf_change[i] < 0)) {
+ int foldstart, foldend;
+
+ /* This ensures we never repeat spectral content within one band */
+ effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band],
+ ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]);
+ foldstart = lowband_offset;
+ while (ff_celt_freq_bands[--foldstart] > effective_lowband);
+ foldend = lowband_offset - 1;
+ while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]);
+
+ cm[0] = cm[1] = 0;
+ for (j = foldstart; j < foldend; j++) {
+ cm[0] |= f->block[0].collapse_masks[j];
+ cm[1] |= f->block[f->channels - 1].collapse_masks[j];
}
}
- consumed = opus_rc_tell(&rc->c);
- }
+ if (f->dual_stereo && i == f->intensity_stereo) {
+ /* Switch off dual stereo to do intensity */
+ f->dual_stereo = 0;
+ for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++)
+ norm1[j] = (norm1[j] + norm2[j]) / 2;
+ }
- return consumed;
-}
+ norm_loc1 = effective_lowband != -1 ? norm1 + (effective_lowband << f->size) : NULL;
+ norm_loc2 = effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL;
-static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
-{
- int i, j, k;
+ if (f->dual_stereo) {
+ cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, NULL, band_size, b >> 1,
+ f->blocks, norm_loc1, f->size,
+ norm1 + band_offset, 0, 1.0f,
+ lowband_scratch, cm[0]);
- for (i = f->start_band; i < f->end_band; i++) {
- int renormalize = 0;
- float *xptr;
- float prev[2];
- float Ediff, r;
- float thresh, sqrt_1;
- int depth;
-
- /* depth in 1/8 bits */
- depth = (1 + f->pulses[i]) / (ff_celt_freq_range[i] << f->size);
- thresh = exp2f(-1.0 - 0.125f * depth);
- sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << f->size);
-
- xptr = X + (ff_celt_freq_bands[i] << f->size);
-
- prev[0] = block->prev_energy[0][i];
- prev[1] = block->prev_energy[1][i];
- if (f->channels == 1) {
- CeltBlock *block1 = &f->block[1];
-
- prev[0] = FFMAX(prev[0], block1->prev_energy[0][i]);
- prev[1] = FFMAX(prev[1], block1->prev_energy[1][i]);
- }
- Ediff = block->energy[i] - FFMIN(prev[0], prev[1]);
- Ediff = FFMAX(0, Ediff);
-
- /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
- short blocks don't have the same energy as long */
- r = exp2f(1 - Ediff);
- if (f->size == 3)
- r *= M_SQRT2;
- r = FFMIN(thresh, r) * sqrt_1;
- for (k = 0; k < 1 << f->size; k++) {
- /* Detect collapse */
- if (!(block->collapse_masks[i] & 1 << k)) {
- /* Fill with noise */
- for (j = 0; j < ff_celt_freq_range[i]; j++)
- xptr[(j << f->size) + k] = (celt_rng(f) & 0x8000) ? r : -r;
- renormalize = 1;
- }
+ cm[1] = f->pvq->quant_band(f->pvq, f, rc, i, Y, NULL, band_size, b >> 1,
+ f->blocks, norm_loc2, f->size,
+ norm2 + band_offset, 0, 1.0f,
+ lowband_scratch, cm[1]);
+ } else {
+ cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, Y, band_size, b >> 0,
+ f->blocks, norm_loc1, f->size,
+ norm1 + band_offset, 0, 1.0f,
+ lowband_scratch, cm[0] | cm[1]);
+ cm[1] = cm[0];
}
- /* We just added some energy, so we need to renormalize */
- if (renormalize)
- celt_renormalize_vector(xptr, ff_celt_freq_range[i] << f->size, 1.0f);
+ f->block[0].collapse_masks[i] = (uint8_t)cm[0];
+ f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1];
+ f->remaining += f->pulses[i] + consumed;
+
+ /* Update the folding position only as long as we have 1 bit/sample depth */
+ update_lowband = (b > band_size << 3);
}
}
-int ff_celt_decode_frame(CeltFrame *f, OpusDecRangeCoder *rc,
- float **output, int channels, int frame_size,
- int start_band, int end_band)
-{
- int i, j, downmix = 0;
- int consumed; // bits of entropy consumed thus far for this frame
- AVTXContext *imdct;
- av_tx_fn imdct_fn;
-
- if (channels != 1 && channels != 2) {
- av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
- channels);
- return AVERROR_INVALIDDATA;
- }
- if (start_band < 0 || start_band > end_band || end_band > CELT_MAX_BANDS) {
- av_log(f->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n",
- start_band, end_band);
- return AVERROR_INVALIDDATA;
- }
+#define NORMC(bits) ((bits) << (f->channels - 1) << f->size >> 2)
- f->silence = 0;
- f->transient = 0;
- f->anticollapse = 0;
- f->flushed = 0;
- f->channels = channels;
- f->start_band = start_band;
- f->end_band = end_band;
- f->framebits = rc->c.rb.bytes * 8;
-
- f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
- if (f->size > CELT_MAX_LOG_BLOCKS ||
- frame_size != CELT_SHORT_BLOCKSIZE * (1 << f->size)) {
- av_log(f->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n",
- frame_size);
- return AVERROR_INVALIDDATA;
+void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
+{
+ int i, j, low, high, total, done, bandbits, remaining, tbits_8ths;
+ int skip_startband = f->start_band;
+ int skip_bit = 0;
+ int intensitystereo_bit = 0;
+ int dualstereo_bit = 0;
+ int dynalloc = 6;
+ int extrabits = 0;
+
+ int boost[CELT_MAX_BANDS] = { 0 };
+ int trim_offset[CELT_MAX_BANDS];
+ int threshold[CELT_MAX_BANDS];
+ int bits1[CELT_MAX_BANDS];
+ int bits2[CELT_MAX_BANDS];
+
+ if (!CONFIG_OPUS_DECODER || !CONFIG_OPUS_ENCODER)
+ encode = CONFIG_OPUS_ENCODER;
+ /* Spread */
+ if (opus_rc_tell(rc) + 4 <= f->framebits) {
+ if (encode)
+ opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread);
+ else
+ f->spread = opus_rc_dec_cdf(rc, ff_celt_model_spread);
+ } else {
+ f->spread = CELT_SPREAD_NORMAL;
}
- if (!f->output_channels)
- f->output_channels = channels;
+ /* Initialize static allocation caps */
+ for (i = 0; i < CELT_MAX_BANDS; i++)
+ f->caps[i] = NORMC((ff_celt_static_caps[f->size][f->channels - 1][i] + 64) * ff_celt_freq_range[i]);
- for (i = 0; i < f->channels; i++) {
- memset(f->block[i].coeffs, 0, sizeof(f->block[i].coeffs));
- memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks));
- }
+ /* Band boosts */
+ tbits_8ths = f->framebits << 3;
+ for (i = f->start_band; i < f->end_band; i++) {
+ int quanta = ff_celt_freq_range[i] << (f->channels - 1) << f->size;
+ int b_dynalloc = dynalloc;
+ int boost_amount = f->alloc_boost[i];
+ quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
+
+ while (opus_rc_tell_frac(rc) + (b_dynalloc << 3) < tbits_8ths && boost[i] < f->caps[i]) {
+ int is_boost;
+ if (encode) {
+ is_boost = boost_amount--;
+ opus_rc_enc_log(rc, is_boost, b_dynalloc);
+ } else {
+ is_boost = opus_rc_dec_log(rc, b_dynalloc);
+ }
- consumed = opus_rc_tell(&rc->c);
+ if (!is_boost)
+ break;
- /* obtain silence flag */
- if (consumed >= f->framebits)
- f->silence = 1;
- else if (consumed == 1)
- f->silence = ff_opus_rc_dec_log(rc, 15);
+ boost[i] += quanta;
+ tbits_8ths -= quanta;
+ b_dynalloc = 1;
+ }
- if (f->silence) {
- consumed = f->framebits;
- rc->c.total_bits += f->framebits - opus_rc_tell(&rc->c);
+ if (boost[i])
+ dynalloc = FFMAX(dynalloc - 1, 2);
}
- /* obtain post-filter options */
- consumed = parse_postfilter(f, rc, consumed);
-
- /* obtain transient flag */
- if (f->size != 0 && consumed+3 <= f->framebits)
- f->transient = ff_opus_rc_dec_log(rc, 3);
-
- f->blocks = f->transient ? 1 << f->size : 1;
- f->blocksize = frame_size / f->blocks;
-
- imdct = f->tx[f->transient ? 0 : f->size];
- imdct_fn = f->tx_fn[f->transient ? 0 : f->size];
-
- if (channels == 1) {
- for (i = 0; i < CELT_MAX_BANDS; i++)
- f->block[0].energy[i] = FFMAX(f->block[0].energy[i], f->block[1].energy[i]);
+ /* Allocation trim */
+ if (!encode)
+ f->alloc_trim = 5;
+ if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths)
+ if (encode)
+ opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim);
+ else
+ f->alloc_trim = opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
+
+ /* Anti-collapse bit reservation */
+ tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1;
+ f->anticollapse_needed = 0;
+ if (f->transient && f->size >= 2 && tbits_8ths >= ((f->size + 2) << 3))
+ f->anticollapse_needed = 1 << 3;
+ tbits_8ths -= f->anticollapse_needed;
+
+ /* Band skip bit reservation */
+ if (tbits_8ths >= 1 << 3)
+ skip_bit = 1 << 3;
+ tbits_8ths -= skip_bit;
+
+ /* Intensity/dual stereo bit reservation */
+ if (f->channels == 2) {
+ intensitystereo_bit = ff_celt_log2_frac[f->end_band - f->start_band];
+ if (intensitystereo_bit <= tbits_8ths) {
+ tbits_8ths -= intensitystereo_bit;
+ if (tbits_8ths >= 1 << 3) {
+ dualstereo_bit = 1 << 3;
+ tbits_8ths -= 1 << 3;
+ }
+ } else {
+ intensitystereo_bit = 0;
+ }
}
- celt_decode_coarse_energy(f, rc);
- celt_decode_tf_changes (f, rc);
- ff_celt_bitalloc (f, &rc->c, 0);
- celt_decode_fine_energy (f, rc);
- ff_celt_quant_bands (f, &rc->c);
-
- if (f->anticollapse_needed)
- f->anticollapse = ff_opus_rc_get_raw(rc, 1);
-
- celt_decode_final_energy(f, rc);
+ /* Trim offsets */
+ for (i = f->start_band; i < f->end_band; i++) {
+ int trim = f->alloc_trim - 5 - f->size;
+ int band = ff_celt_freq_range[i] * (f->end_band - i - 1);
+ int duration = f->size + 3;
+ int scale = duration + f->channels - 1;
- /* apply anti-collapse processing and denormalization to
- * each coded channel */
- for (i = 0; i < f->channels; i++) {
- CeltBlock *block = &f->block[i];
+ /* PVQ minimum allocation threshold, below this value the band is
+ * skipped */
+ threshold[i] = FFMAX(3 * ff_celt_freq_range[i] << duration >> 4,
+ f->channels << 3);
- if (f->anticollapse)
- process_anticollapse(f, block, f->block[i].coeffs);
+ trim_offset[i] = trim * (band << scale) >> 6;
- celt_denormalize(f, block, f->block[i].coeffs);
+ if (ff_celt_freq_range[i] << f->size == 1)
+ trim_offset[i] -= f->channels << 3;
}
- /* stereo -> mono downmix */
- if (f->output_channels < f->channels) {
- f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16));
- downmix = 1;
- } else if (f->output_channels > f->channels)
- memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float));
-
- if (f->silence) {
- for (i = 0; i < 2; i++) {
- CeltBlock *block = &f->block[i];
-
- for (j = 0; j < FF_ARRAY_ELEMS(block->energy); j++)
- block->energy[j] = CELT_ENERGY_SILENCE;
+ /* Bisection */
+ low = 1;
+ high = CELT_VECTORS - 1;
+ while (low <= high) {
+ int center = (low + high) >> 1;
+ done = total = 0;
+
+ for (i = f->end_band - 1; i >= f->start_band; i--) {
+ bandbits = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[center][i]);
+
+ if (bandbits)
+ bandbits = FFMAX(bandbits + trim_offset[i], 0);
+ bandbits += boost[i];
+
+ if (bandbits >= threshold[i] || done) {
+ done = 1;
+ total += FFMIN(bandbits, f->caps[i]);
+ } else if (bandbits >= f->channels << 3) {
+ total += f->channels << 3;
+ }
}
- memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs));
- memset(f->block[1].coeffs, 0, sizeof(f->block[1].coeffs));
- }
- /* transform and output for each output channel */
- for (i = 0; i < f->output_channels; i++) {
- CeltBlock *block = &f->block[i];
+ if (total > tbits_8ths)
+ high = center - 1;
+ else
+ low = center + 1;
+ }
+ high = low--;
- /* iMDCT and overlap-add */
- for (j = 0; j < f->blocks; j++) {
- float *dst = block->buf + 1024 + j * f->blocksize;
+ /* Bisection */
+ for (i = f->start_band; i < f->end_band; i++) {
+ bits1[i] = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[low][i]);
+ bits2[i] = high >= CELT_VECTORS ? f->caps[i] :
+ NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[high][i]);
+
+ if (bits1[i])
+ bits1[i] = FFMAX(bits1[i] + trim_offset[i], 0);
+ if (bits2[i])
+ bits2[i] = FFMAX(bits2[i] + trim_offset[i], 0);
+
+ if (low)
+ bits1[i] += boost[i];
+ bits2[i] += boost[i];
+
+ if (boost[i])
+ skip_startband = i;
+ bits2[i] = FFMAX(bits2[i] - bits1[i], 0);
+ }
- imdct_fn(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j,
- sizeof(float)*f->blocks);
- f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
- ff_celt_window, CELT_OVERLAP / 2);
+ /* Bisection */
+ low = 0;
+ high = 1 << CELT_ALLOC_STEPS;
+ for (i = 0; i < CELT_ALLOC_STEPS; i++) {
+ int center = (low + high) >> 1;
+ done = total = 0;
+
+ for (j = f->end_band - 1; j >= f->start_band; j--) {
+ bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS);
+
+ if (bandbits >= threshold[j] || done) {
+ done = 1;
+ total += FFMIN(bandbits, f->caps[j]);
+ } else if (bandbits >= f->channels << 3)
+ total += f->channels << 3;
}
-
- if (downmix)
- f->dsp->vector_fmul_scalar(&block->buf[1024], &block->buf[1024], 0.5f, frame_size);
-
- /* postfilter */
- celt_postfilter(f, block);
-
- /* deemphasis */
- block->emph_coeff = f->opusdsp.deemphasis(output[i],
- &block->buf[1024 - frame_size],
- block->emph_coeff, frame_size);
+ if (total > tbits_8ths)
+ high = center;
+ else
+ low = center;
}
- if (channels == 1)
- memcpy(f->block[1].energy, f->block[0].energy, sizeof(f->block[0].energy));
+ /* Bisection */
+ done = total = 0;
+ for (i = f->end_band - 1; i >= f->start_band; i--) {
+ bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS);
- for (i = 0; i < 2; i++ ) {
- CeltBlock *block = &f->block[i];
+ if (bandbits >= threshold[i] || done)
+ done = 1;
+ else
+ bandbits = (bandbits >= f->channels << 3) ?
+ f->channels << 3 : 0;
- if (!f->transient) {
- memcpy(block->prev_energy[1], block->prev_energy[0], sizeof(block->prev_energy[0]));
- memcpy(block->prev_energy[0], block->energy, sizeof(block->prev_energy[0]));
- } else {
- for (j = 0; j < CELT_MAX_BANDS; j++)
- block->prev_energy[0][j] = FFMIN(block->prev_energy[0][j], block->energy[j]);
- }
-
- for (j = 0; j < f->start_band; j++) {
- block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
- block->energy[j] = 0.0;
- }
- for (j = f->end_band; j < CELT_MAX_BANDS; j++) {
- block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
- block->energy[j] = 0.0;
- }
+ bandbits = FFMIN(bandbits, f->caps[i]);
+ f->pulses[i] = bandbits;
+ total += bandbits;
}
- f->seed = rc->c.range;
+ /* Band skipping */
+ for (f->coded_bands = f->end_band; ; f->coded_bands--) {
+ int allocation;
+ j = f->coded_bands - 1;
- return 0;
-}
-
-void ff_celt_flush(CeltFrame *f)
-{
- int i, j;
-
- if (f->flushed)
- return;
+ if (j == skip_startband) {
+ /* all remaining bands are not skipped */
+ tbits_8ths += skip_bit;
+ break;
+ }
- for (i = 0; i < 2; i++) {
- CeltBlock *block = &f->block[i];
+ /* determine the number of bits available for coding "do not skip" markers */
+ remaining = tbits_8ths - total;
+ bandbits = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
+ remaining -= bandbits * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
+ allocation = f->pulses[j] + bandbits * ff_celt_freq_range[j];
+ allocation += FFMAX(remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[f->start_band]), 0);
+
+ /* a "do not skip" marker is only coded if the allocation is
+ * above the chosen threshold */
+ if (allocation >= FFMAX(threshold[j], (f->channels + 1) << 3)) {
+ int do_not_skip;
+ if (encode) {
+ do_not_skip = f->coded_bands <= f->skip_band_floor;
+ opus_rc_enc_log(rc, do_not_skip, 1);
+ } else {
+ do_not_skip = opus_rc_dec_log(rc, 1);
+ }
- for (j = 0; j < CELT_MAX_BANDS; j++)
- block->prev_energy[0][j] = block->prev_energy[1][j] = CELT_ENERGY_SILENCE;
+ if (do_not_skip)
+ break;
- memset(block->energy, 0, sizeof(block->energy));
- memset(block->buf, 0, sizeof(block->buf));
+ total += 1 << 3;
+ allocation -= 1 << 3;
+ }
- memset(block->pf_gains, 0, sizeof(block->pf_gains));
- memset(block->pf_gains_old, 0, sizeof(block->pf_gains_old));
- memset(block->pf_gains_new, 0, sizeof(block->pf_gains_new));
+ /* the band is skipped, so reclaim its bits */
+ total -= f->pulses[j];
+ if (intensitystereo_bit) {
+ total -= intensitystereo_bit;
+ intensitystereo_bit = ff_celt_log2_frac[j - f->start_band];
+ total += intensitystereo_bit;
+ }
- /* libopus uses CELT_EMPH_COEFF on init, but 0 is better since there's
- * a lesser discontinuity when seeking.
- * The deemphasis functions differ from libopus in that they require
- * an initial state divided by the coefficient. */
- block->emph_coeff = 0.0f / CELT_EMPH_COEFF;
+ total += f->pulses[j] = (allocation >= f->channels << 3) ? f->channels << 3 : 0;
}
- f->seed = 0;
-
- f->flushed = 1;
-}
-
-void ff_celt_free(CeltFrame **f)
-{
- CeltFrame *frm = *f;
- int i;
-
- if (!frm)
- return;
- for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++)
- av_tx_uninit(&frm->tx[i]);
-
- ff_celt_pvq_uninit(&frm->pvq);
-
- av_freep(&frm->dsp);
- av_freep(f);
-}
-
-int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels,
- int apply_phase_inv)
-{
- CeltFrame *frm;
- int i, ret;
+ /* IS start band */
+ if (encode) {
+ if (intensitystereo_bit) {
+ f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands);
+ ff_opus_rc_enc_uint((OpusEncRangeCoder*)rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band);
+ }
+ } else {
+ f->intensity_stereo = f->dual_stereo = 0;
+ if (intensitystereo_bit)
+ f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint((OpusDecRangeCoder*)rc, f->coded_bands + 1 - f->start_band);
+ }
- if (output_channels != 1 && output_channels != 2) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
- output_channels);
- return AVERROR(EINVAL);
+ /* DS flag */
+ if (f->intensity_stereo <= f->start_band)
+ tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */
+ else if (dualstereo_bit)
+ if (encode)
+ opus_rc_enc_log(rc, f->dual_stereo, 1);
+ else
+ f->dual_stereo = opus_rc_dec_log(rc, 1);
+
+ /* Supply the remaining bits in this frame to lower bands */
+ remaining = tbits_8ths - total;
+ bandbits = remaining / (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
+ remaining -= bandbits * (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
+ for (i = f->start_band; i < f->coded_bands; i++) {
+ const int bits = FFMIN(remaining, ff_celt_freq_range[i]);
+ f->pulses[i] += bits + bandbits * ff_celt_freq_range[i];
+ remaining -= bits;
}
- frm = av_mallocz(sizeof(*frm));
- if (!frm)
- return AVERROR(ENOMEM);
+ /* Finally determine the allocation */
+ for (i = f->start_band; i < f->coded_bands; i++) {
+ int N = ff_celt_freq_range[i] << f->size;
+ int prev_extra = extrabits;
+ f->pulses[i] += extrabits;
+
+ if (N > 1) {
+ int dof; /* degrees of freedom */
+ int temp; /* dof * channels * log(dof) */
+ int fine_bits;
+ int max_bits;
+ int offset; /* fine energy quantization offset, i.e.
+ * extra bits assigned over the standard
+ * totalbits/dof */
+
+ extrabits = FFMAX(f->pulses[i] - f->caps[i], 0);
+ f->pulses[i] -= extrabits;
+
+ /* intensity stereo makes use of an extra degree of freedom */
+ dof = N * f->channels + (f->channels == 2 && N > 2 && !f->dual_stereo && i < f->intensity_stereo);
+ temp = dof * (ff_celt_log_freq_range[i] + (f->size << 3));
+ offset = (temp >> 1) - dof * CELT_FINE_OFFSET;
+ if (N == 2) /* dof=2 is the only case that doesn't fit the model */
+ offset += dof << 1;
+
+ /* grant an additional bias for the first and second pulses */
+ if (f->pulses[i] + offset < 2 * (dof << 3))
+ offset += temp >> 2;
+ else if (f->pulses[i] + offset < 3 * (dof << 3))
+ offset += temp >> 3;
+
+ fine_bits = (f->pulses[i] + offset + (dof << 2)) / (dof << 3);
+ max_bits = FFMIN((f->pulses[i] >> 3) >> (f->channels - 1), CELT_MAX_FINE_BITS);
+ max_bits = FFMAX(max_bits, 0);
+ f->fine_bits[i] = av_clip(fine_bits, 0, max_bits);
+
+ /* If fine_bits was rounded down or capped,
+ * give priority for the final fine energy pass */
+ f->fine_priority[i] = (f->fine_bits[i] * (dof << 3) >= f->pulses[i] + offset);
+
+ /* the remaining bits are assigned to PVQ */
+ f->pulses[i] -= f->fine_bits[i] << (f->channels - 1) << 3;
+ } else {
+ /* all bits go to fine energy except for the sign bit */
+ extrabits = FFMAX(f->pulses[i] - (f->channels << 3), 0);
+ f->pulses[i] -= extrabits;
+ f->fine_bits[i] = 0;
+ f->fine_priority[i] = 1;
+ }
- frm->avctx = avctx;
- frm->output_channels = output_channels;
- frm->apply_phase_inv = apply_phase_inv;
+ /* hand back a limited number of extra fine energy bits to this band */
+ if (extrabits > 0) {
+ int fineextra = FFMIN(extrabits >> (f->channels + 2),
+ CELT_MAX_FINE_BITS - f->fine_bits[i]);
+ f->fine_bits[i] += fineextra;
- for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++) {
- const float scale = -1.0f/32768;
- if ((ret = av_tx_init(&frm->tx[i], &frm->tx_fn[i], AV_TX_FLOAT_MDCT, 1, 15 << (i + 3), &scale, 0)) < 0)
- goto fail;
+ fineextra <<= f->channels + 2;
+ f->fine_priority[i] = (fineextra >= extrabits - prev_extra);
+ extrabits -= fineextra;
+ }
}
+ f->remaining = extrabits;
- if ((ret = ff_celt_pvq_init(&frm->pvq, 0)) < 0)
- goto fail;
-
- frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
- if (!frm->dsp) {
- ret = AVERROR(ENOMEM);
- goto fail;
+ /* skipped bands dedicate all of their bits for fine energy */
+ for (; i < f->end_band; i++) {
+ f->fine_bits[i] = f->pulses[i] >> (f->channels - 1) >> 3;
+ f->pulses[i] = 0;
+ f->fine_priority[i] = f->fine_bits[i] < 1;
}
-
- ff_opus_dsp_init(&frm->opusdsp);
- ff_celt_flush(frm);
-
- *f = frm;
-
- return 0;
-fail:
- ff_celt_free(&frm);
- return ret;
}
diff --git a/libavcodec/opusdec_celt.c b/libavcodec/opusdec_celt.c
new file mode 100644
index 0000000000..a14764ec18
--- /dev/null
+++ b/libavcodec/opusdec_celt.c
@@ -0,0 +1,587 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * Opus CELT decoder
+ */
+
+#include <float.h>
+
+#include "opus_celt.h"
+#include "opusdec_rc.h"
+#include "opustab.h"
+#include "opus_pvq.h"
+
+/* Use the 2D z-transform to apply prediction in both the time domain (alpha)
+ * and the frequency domain (beta) */
+static void celt_decode_coarse_energy(CeltFrame *f, OpusDecRangeCoder *rc)
+{
+ int i, j;
+ float prev[2] = { 0 };
+ float alpha = ff_celt_alpha_coef[f->size];
+ float beta = ff_celt_beta_coef[f->size];
+ const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0];
+
+ /* intra frame */
+ if (opus_rc_tell(&rc->c) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
+ alpha = 0.0f;
+ beta = 1.0f - (4915.0f/32768.0f);
+ model = ff_celt_coarse_energy_dist[f->size][1];
+ }
+
+ for (i = 0; i < CELT_MAX_BANDS; i++) {
+ for (j = 0; j < f->channels; j++) {
+ CeltBlock *block = &f->block[j];
+ float value;
+ int available;
+
+ if (i < f->start_band || i >= f->end_band) {
+ block->energy[i] = 0.0;
+ continue;
+ }
+
+ available = f->framebits - opus_rc_tell(&rc->c);
+ if (available >= 15) {
+ /* decode using a Laplace distribution */
+ int k = FFMIN(i, 20) << 1;
+ value = ff_opus_rc_dec_laplace(rc, model[k] << 7, model[k+1] << 6);
+ } else if (available >= 2) {
+ int x = ff_opus_rc_dec_cdf(rc, ff_celt_model_energy_small);
+ value = (x>>1) ^ -(x&1);
+ } else if (available >= 1) {
+ value = -(float)ff_opus_rc_dec_log(rc, 1);
+ } else value = -1;
+
+ block->energy[i] = FFMAX(-9.0f, block->energy[i]) * alpha + prev[j] + value;
+ prev[j] += beta * value;
+ }
+ }
+}
+
+static void celt_decode_fine_energy(CeltFrame *f, OpusDecRangeCoder *rc)
+{
+ int i;
+ for (i = f->start_band; i < f->end_band; i++) {
+ int j;
+ if (!f->fine_bits[i])
+ continue;
+
+ for (j = 0; j < f->channels; j++) {
+ CeltBlock *block = &f->block[j];
+ int q2;
+ float offset;
+ q2 = ff_opus_rc_get_raw(rc, f->fine_bits[i]);
+ offset = (q2 + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f - 0.5f;
+ block->energy[i] += offset;
+ }
+ }
+}
+
+static void celt_decode_final_energy(CeltFrame *f, OpusDecRangeCoder *rc)
+{
+ int priority, i, j;
+ int bits_left = f->framebits - opus_rc_tell(&rc->c);
+
+ for (priority = 0; priority < 2; priority++) {
+ for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) {
+ if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
+ continue;
+
+ for (j = 0; j < f->channels; j++) {
+ int q2;
+ float offset;
+ q2 = ff_opus_rc_get_raw(rc, 1);
+ offset = (q2 - 0.5f) * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
+ f->block[j].energy[i] += offset;
+ bits_left--;
+ }
+ }
+ }
+}
+
+static void celt_decode_tf_changes(CeltFrame *f, OpusDecRangeCoder *rc)
+{
+ int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
+ int consumed, bits = f->transient ? 2 : 4;
+
+ consumed = opus_rc_tell(&rc->c);
+ tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits);
+
+ for (i = f->start_band; i < f->end_band; i++) {
+ if (consumed+bits+tf_select_bit <= f->framebits) {
+ diff ^= ff_opus_rc_dec_log(rc, bits);
+ consumed = opus_rc_tell(&rc->c);
+ tf_changed |= diff;
+ }
+ f->tf_change[i] = diff;
+ bits = f->transient ? 4 : 5;
+ }
+
+ if (tf_select_bit && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
+ ff_celt_tf_select[f->size][f->transient][1][tf_changed])
+ tf_select = ff_opus_rc_dec_log(rc, 1);
+
+ for (i = f->start_band; i < f->end_band; i++) {
+ f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
+ }
+}
+
+static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data)
+{
+ int i, j;
+
+ for (i = f->start_band; i < f->end_band; i++) {
+ float *dst = data + (ff_celt_freq_bands[i] << f->size);
+ float log_norm = block->energy[i] + ff_celt_mean_energy[i];
+ float norm = exp2f(FFMIN(log_norm, 32.0f));
+
+ for (j = 0; j < ff_celt_freq_range[i] << f->size; j++)
+ dst[j] *= norm;
+ }
+}
+
+static void celt_postfilter_apply_transition(CeltBlock *block, float *data)
+{
+ const int T0 = block->pf_period_old;
+ const int T1 = block->pf_period;
+
+ float g00, g01, g02;
+ float g10, g11, g12;
+
+ float x0, x1, x2, x3, x4;
+
+ int i;
+
+ if (block->pf_gains[0] == 0.0 &&
+ block->pf_gains_old[0] == 0.0)
+ return;
+
+ g00 = block->pf_gains_old[0];
+ g01 = block->pf_gains_old[1];
+ g02 = block->pf_gains_old[2];
+ g10 = block->pf_gains[0];
+ g11 = block->pf_gains[1];
+ g12 = block->pf_gains[2];
+
+ x1 = data[-T1 + 1];
+ x2 = data[-T1];
+ x3 = data[-T1 - 1];
+ x4 = data[-T1 - 2];
+
+ for (i = 0; i < CELT_OVERLAP; i++) {
+ float w = ff_celt_window2[i];
+ x0 = data[i - T1 + 2];
+
+ data[i] += (1.0 - w) * g00 * data[i - T0] +
+ (1.0 - w) * g01 * (data[i - T0 - 1] + data[i - T0 + 1]) +
+ (1.0 - w) * g02 * (data[i - T0 - 2] + data[i - T0 + 2]) +
+ w * g10 * x2 +
+ w * g11 * (x1 + x3) +
+ w * g12 * (x0 + x4);
+ x4 = x3;
+ x3 = x2;
+ x2 = x1;
+ x1 = x0;
+ }
+}
+
+static void celt_postfilter(CeltFrame *f, CeltBlock *block)
+{
+ int len = f->blocksize * f->blocks;
+ const int filter_len = len - 2 * CELT_OVERLAP;
+
+ celt_postfilter_apply_transition(block, block->buf + 1024);
+
+ block->pf_period_old = block->pf_period;
+ memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
+
+ block->pf_period = block->pf_period_new;
+ memcpy(block->pf_gains, block->pf_gains_new, sizeof(block->pf_gains));
+
+ if (len > CELT_OVERLAP) {
+ celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP);
+
+ if (block->pf_gains[0] > FLT_EPSILON && filter_len > 0)
+ f->opusdsp.postfilter(block->buf + 1024 + 2 * CELT_OVERLAP,
+ block->pf_period, block->pf_gains,
+ filter_len);
+
+ block->pf_period_old = block->pf_period;
+ memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
+ }
+
+ memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
+}
+
+static int parse_postfilter(CeltFrame *f, OpusDecRangeCoder *rc, int consumed)
+{
+ int i;
+
+ memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new));
+ memset(f->block[1].pf_gains_new, 0, sizeof(f->block[1].pf_gains_new));
+
+ if (f->start_band == 0 && consumed + 16 <= f->framebits) {
+ int has_postfilter = ff_opus_rc_dec_log(rc, 1);
+ if (has_postfilter) {
+ float gain;
+ int tapset, octave, period;
+
+ octave = ff_opus_rc_dec_uint(rc, 6);
+ period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1;
+ gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1);
+ tapset = (opus_rc_tell(&rc->c) + 2 <= f->framebits) ?
+ ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;
+
+ for (i = 0; i < 2; i++) {
+ CeltBlock *block = &f->block[i];
+
+ block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
+ block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
+ block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
+ block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
+ }
+ }
+
+ consumed = opus_rc_tell(&rc->c);
+ }
+
+ return consumed;
+}
+
+static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
+{
+ int i, j, k;
+
+ for (i = f->start_band; i < f->end_band; i++) {
+ int renormalize = 0;
+ float *xptr;
+ float prev[2];
+ float Ediff, r;
+ float thresh, sqrt_1;
+ int depth;
+
+ /* depth in 1/8 bits */
+ depth = (1 + f->pulses[i]) / (ff_celt_freq_range[i] << f->size);
+ thresh = exp2f(-1.0 - 0.125f * depth);
+ sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << f->size);
+
+ xptr = X + (ff_celt_freq_bands[i] << f->size);
+
+ prev[0] = block->prev_energy[0][i];
+ prev[1] = block->prev_energy[1][i];
+ if (f->channels == 1) {
+ CeltBlock *block1 = &f->block[1];
+
+ prev[0] = FFMAX(prev[0], block1->prev_energy[0][i]);
+ prev[1] = FFMAX(prev[1], block1->prev_energy[1][i]);
+ }
+ Ediff = block->energy[i] - FFMIN(prev[0], prev[1]);
+ Ediff = FFMAX(0, Ediff);
+
+ /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
+ short blocks don't have the same energy as long */
+ r = exp2f(1 - Ediff);
+ if (f->size == 3)
+ r *= M_SQRT2;
+ r = FFMIN(thresh, r) * sqrt_1;
+ for (k = 0; k < 1 << f->size; k++) {
+ /* Detect collapse */
+ if (!(block->collapse_masks[i] & 1 << k)) {
+ /* Fill with noise */
+ for (j = 0; j < ff_celt_freq_range[i]; j++)
+ xptr[(j << f->size) + k] = (celt_rng(f) & 0x8000) ? r : -r;
+ renormalize = 1;
+ }
+ }
+
+ /* We just added some energy, so we need to renormalize */
+ if (renormalize)
+ celt_renormalize_vector(xptr, ff_celt_freq_range[i] << f->size, 1.0f);
+ }
+}
+
+int ff_celt_decode_frame(CeltFrame *f, OpusDecRangeCoder *rc,
+ float **output, int channels, int frame_size,
+ int start_band, int end_band)
+{
+ int i, j, downmix = 0;
+ int consumed; // bits of entropy consumed thus far for this frame
+ AVTXContext *imdct;
+ av_tx_fn imdct_fn;
+
+ if (channels != 1 && channels != 2) {
+ av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
+ channels);
+ return AVERROR_INVALIDDATA;
+ }
+ if (start_band < 0 || start_band > end_band || end_band > CELT_MAX_BANDS) {
+ av_log(f->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n",
+ start_band, end_band);
+ return AVERROR_INVALIDDATA;
+ }
+
+ f->silence = 0;
+ f->transient = 0;
+ f->anticollapse = 0;
+ f->flushed = 0;
+ f->channels = channels;
+ f->start_band = start_band;
+ f->end_band = end_band;
+ f->framebits = rc->c.rb.bytes * 8;
+
+ f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
+ if (f->size > CELT_MAX_LOG_BLOCKS ||
+ frame_size != CELT_SHORT_BLOCKSIZE * (1 << f->size)) {
+ av_log(f->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n",
+ frame_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!f->output_channels)
+ f->output_channels = channels;
+
+ for (i = 0; i < f->channels; i++) {
+ memset(f->block[i].coeffs, 0, sizeof(f->block[i].coeffs));
+ memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks));
+ }
+
+ consumed = opus_rc_tell(&rc->c);
+
+ /* obtain silence flag */
+ if (consumed >= f->framebits)
+ f->silence = 1;
+ else if (consumed == 1)
+ f->silence = ff_opus_rc_dec_log(rc, 15);
+
+
+ if (f->silence) {
+ consumed = f->framebits;
+ rc->c.total_bits += f->framebits - opus_rc_tell(&rc->c);
+ }
+
+ /* obtain post-filter options */
+ consumed = parse_postfilter(f, rc, consumed);
+
+ /* obtain transient flag */
+ if (f->size != 0 && consumed+3 <= f->framebits)
+ f->transient = ff_opus_rc_dec_log(rc, 3);
+
+ f->blocks = f->transient ? 1 << f->size : 1;
+ f->blocksize = frame_size / f->blocks;
+
+ imdct = f->tx[f->transient ? 0 : f->size];
+ imdct_fn = f->tx_fn[f->transient ? 0 : f->size];
+
+ if (channels == 1) {
+ for (i = 0; i < CELT_MAX_BANDS; i++)
+ f->block[0].energy[i] = FFMAX(f->block[0].energy[i], f->block[1].energy[i]);
+ }
+
+ celt_decode_coarse_energy(f, rc);
+ celt_decode_tf_changes (f, rc);
+ ff_celt_bitalloc (f, &rc->c, 0);
+ celt_decode_fine_energy (f, rc);
+ ff_celt_quant_bands (f, &rc->c);
+
+ if (f->anticollapse_needed)
+ f->anticollapse = ff_opus_rc_get_raw(rc, 1);
+
+ celt_decode_final_energy(f, rc);
+
+ /* apply anti-collapse processing and denormalization to
+ * each coded channel */
+ for (i = 0; i < f->channels; i++) {
+ CeltBlock *block = &f->block[i];
+
+ if (f->anticollapse)
+ process_anticollapse(f, block, f->block[i].coeffs);
+
+ celt_denormalize(f, block, f->block[i].coeffs);
+ }
+
+ /* stereo -> mono downmix */
+ if (f->output_channels < f->channels) {
+ f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16));
+ downmix = 1;
+ } else if (f->output_channels > f->channels)
+ memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float));
+
+ if (f->silence) {
+ for (i = 0; i < 2; i++) {
+ CeltBlock *block = &f->block[i];
+
+ for (j = 0; j < FF_ARRAY_ELEMS(block->energy); j++)
+ block->energy[j] = CELT_ENERGY_SILENCE;
+ }
+ memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs));
+ memset(f->block[1].coeffs, 0, sizeof(f->block[1].coeffs));
+ }
+
+ /* transform and output for each output channel */
+ for (i = 0; i < f->output_channels; i++) {
+ CeltBlock *block = &f->block[i];
+
+ /* iMDCT and overlap-add */
+ for (j = 0; j < f->blocks; j++) {
+ float *dst = block->buf + 1024 + j * f->blocksize;
+
+ imdct_fn(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j,
+ sizeof(float)*f->blocks);
+ f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
+ ff_celt_window, CELT_OVERLAP / 2);
+ }
+
+ if (downmix)
+ f->dsp->vector_fmul_scalar(&block->buf[1024], &block->buf[1024], 0.5f, frame_size);
+
+ /* postfilter */
+ celt_postfilter(f, block);
+
+ /* deemphasis */
+ block->emph_coeff = f->opusdsp.deemphasis(output[i],
+ &block->buf[1024 - frame_size],
+ block->emph_coeff, frame_size);
+ }
+
+ if (channels == 1)
+ memcpy(f->block[1].energy, f->block[0].energy, sizeof(f->block[0].energy));
+
+ for (i = 0; i < 2; i++ ) {
+ CeltBlock *block = &f->block[i];
+
+ if (!f->transient) {
+ memcpy(block->prev_energy[1], block->prev_energy[0], sizeof(block->prev_energy[0]));
+ memcpy(block->prev_energy[0], block->energy, sizeof(block->prev_energy[0]));
+ } else {
+ for (j = 0; j < CELT_MAX_BANDS; j++)
+ block->prev_energy[0][j] = FFMIN(block->prev_energy[0][j], block->energy[j]);
+ }
+
+ for (j = 0; j < f->start_band; j++) {
+ block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
+ block->energy[j] = 0.0;
+ }
+ for (j = f->end_band; j < CELT_MAX_BANDS; j++) {
+ block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
+ block->energy[j] = 0.0;
+ }
+ }
+
+ f->seed = rc->c.range;
+
+ return 0;
+}
+
+void ff_celt_flush(CeltFrame *f)
+{
+ int i, j;
+
+ if (f->flushed)
+ return;
+
+ for (i = 0; i < 2; i++) {
+ CeltBlock *block = &f->block[i];
+
+ for (j = 0; j < CELT_MAX_BANDS; j++)
+ block->prev_energy[0][j] = block->prev_energy[1][j] = CELT_ENERGY_SILENCE;
+
+ memset(block->energy, 0, sizeof(block->energy));
+ memset(block->buf, 0, sizeof(block->buf));
+
+ memset(block->pf_gains, 0, sizeof(block->pf_gains));
+ memset(block->pf_gains_old, 0, sizeof(block->pf_gains_old));
+ memset(block->pf_gains_new, 0, sizeof(block->pf_gains_new));
+
+ /* libopus uses CELT_EMPH_COEFF on init, but 0 is better since there's
+ * a lesser discontinuity when seeking.
+ * The deemphasis functions differ from libopus in that they require
+ * an initial state divided by the coefficient. */
+ block->emph_coeff = 0.0f / CELT_EMPH_COEFF;
+ }
+ f->seed = 0;
+
+ f->flushed = 1;
+}
+
+void ff_celt_free(CeltFrame **f)
+{
+ CeltFrame *frm = *f;
+ int i;
+
+ if (!frm)
+ return;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++)
+ av_tx_uninit(&frm->tx[i]);
+
+ ff_celt_pvq_uninit(&frm->pvq);
+
+ av_freep(&frm->dsp);
+ av_freep(f);
+}
+
+int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels,
+ int apply_phase_inv)
+{
+ CeltFrame *frm;
+ int i, ret;
+
+ if (output_channels != 1 && output_channels != 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
+ output_channels);
+ return AVERROR(EINVAL);
+ }
+
+ frm = av_mallocz(sizeof(*frm));
+ if (!frm)
+ return AVERROR(ENOMEM);
+
+ frm->avctx = avctx;
+ frm->output_channels = output_channels;
+ frm->apply_phase_inv = apply_phase_inv;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++) {
+ const float scale = -1.0f/32768;
+ if ((ret = av_tx_init(&frm->tx[i], &frm->tx_fn[i], AV_TX_FLOAT_MDCT, 1, 15 << (i + 3), &scale, 0)) < 0)
+ goto fail;
+ }
+
+ if ((ret = ff_celt_pvq_init(&frm->pvq, 0)) < 0)
+ goto fail;
+
+ frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+ if (!frm->dsp) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ff_opus_dsp_init(&frm->opusdsp);
+ ff_celt_flush(frm);
+
+ *f = frm;
+
+ return 0;
+fail:
+ ff_celt_free(&frm);
+ return ret;
+}
--
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread