[FFmpeg-devel] [PATCH 7/9] avcodec/opus_rc: Split de/encoder-only parts off OpusRangeContext
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Fri Oct 7 23:25:06 EEST 2022
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 at 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 at 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 at 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 at 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 at 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 at 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 at 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
More information about the ffmpeg-devel
mailing list