Browse Source

opus: move the entropy decoding functions to opus_rc.c

The intention is to have both encoding and decoding functions
in opus_rc.c.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
tags/n3.3
Rostislav Pehlivanov 8 years ago
parent
commit
317be31eaf
7 changed files with 380 additions and 320 deletions
  1. +1
    -1
      libavcodec/Makefile
  2. +1
    -221
      libavcodec/opus.h
  3. +29
    -29
      libavcodec/opus_celt.c
  4. +221
    -0
      libavcodec/opus_rc.c
  5. +85
    -0
      libavcodec/opus_rc.h
  6. +36
    -36
      libavcodec/opus_silk.c
  7. +7
    -33
      libavcodec/opusdec.c

+ 1
- 1
libavcodec/Makefile View File

@@ -436,7 +436,7 @@ OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o
OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.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 opus.o opus_celt.o opus_rc.o \
opus_silk.o opustab.o vorbis_data.o opus_silk.o opustab.o vorbis_data.o
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o


+ 1
- 221
libavcodec/opus.h View File

@@ -32,7 +32,7 @@
#include "libswresample/swresample.h" #include "libswresample/swresample.h"


#include "avcodec.h" #include "avcodec.h"
#include "get_bits.h"
#include "opus_rc.h"


#define MAX_FRAME_SIZE 1275 #define MAX_FRAME_SIZE 1275
#define MAX_FRAMES 48 #define MAX_FRAMES 48
@@ -59,7 +59,6 @@


#define ROUND_MULL(a,b,s) (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1) #define ROUND_MULL(a,b,s) (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1)
#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15) #define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15)
#define opus_ilog(i) (av_log2(i) + !!(i))


#define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits) #define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits)
#define OPUS_TS_MASK 0xFFE0 // top 11 bits #define OPUS_TS_MASK 0xFFE0 // top 11 bits
@@ -84,21 +83,6 @@ enum OpusBandwidth {
OPUS_BANDWIDTH_FULLBAND OPUS_BANDWIDTH_FULLBAND
}; };


typedef struct RawBitsContext {
const uint8_t *position;
unsigned int bytes;
unsigned int cachelen;
unsigned int cacheval;
} RawBitsContext;

typedef struct OpusRangeCoder {
GetBitContext gb;
RawBitsContext rb;
unsigned int range;
unsigned int value;
unsigned int total_read_bits;
} OpusRangeCoder;

typedef struct SilkContext SilkContext; typedef struct SilkContext SilkContext;


typedef struct CeltContext CeltContext; typedef struct CeltContext CeltContext;
@@ -193,210 +177,6 @@ typedef struct OpusContext {
ChannelMap *channel_maps; ChannelMap *channel_maps;
} OpusContext; } OpusContext;


static av_always_inline void opus_rc_normalize(OpusRangeCoder *rc)
{
while (rc->range <= 1<<23) {
rc->value = ((rc->value << 8) | (get_bits(&rc->gb, 8) ^ 0xFF)) & ((1u << 31) - 1);
rc->range <<= 8;
rc->total_read_bits += 8;
}
}

static av_always_inline void opus_rc_update(OpusRangeCoder *rc, unsigned int scale,
unsigned int low, unsigned int high,
unsigned int total)
{
rc->value -= scale * (total - high);
rc->range = low ? scale * (high - low)
: rc->range - scale * (total - high);
opus_rc_normalize(rc);
}

static av_always_inline unsigned int opus_rc_getsymbol(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_update(rc, scale, low, high, total);

return k;
}

static av_always_inline unsigned int opus_rc_p2model(OpusRangeCoder *rc, unsigned int bits)
{
unsigned int 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_normalize(rc);
return k;
}

/**
* CELT: estimate bits of entropy that have thus far been consumed for the
* current CELT frame, to integer and fractional (1/8th bit) precision
*/
static av_always_inline unsigned int opus_rc_tell(const OpusRangeCoder *rc)
{
return rc->total_read_bits - av_log2(rc->range) - 1;
}

static av_always_inline unsigned int opus_rc_tell_frac(const OpusRangeCoder *rc)
{
unsigned int i, total_bits, rcbuffer, range;

total_bits = rc->total_read_bits << 3;
rcbuffer = av_log2(rc->range) + 1;
range = rc->range >> (rcbuffer-16);

for (i = 0; i < 3; i++) {
int bit;
range = range * range >> 15;
bit = range >> 16;
rcbuffer = rcbuffer << 1 | bit;
range >>= bit;
}

return total_bits - rcbuffer;
}

/**
* CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise
*/
static av_always_inline unsigned int opus_getrawbits(OpusRangeCoder *rc, unsigned int count)
{
unsigned int 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_read_bits += count;

return value;
}

/**
* CELT: read a uniform distribution
*/
static av_always_inline unsigned int opus_rc_unimodel(OpusRangeCoder *rc, unsigned int size)
{
unsigned int 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_update(rc, scale, k, k + 1, total);

if (bits > 8) {
k = k << (bits - 8) | opus_getrawbits(rc, bits - 8);
return FFMIN(k, size - 1);
} else
return k;
}

static av_always_inline int opus_rc_laplace(OpusRangeCoder *rc, unsigned int symbol, int decay)
{
/* extends the range coder to model a Laplace distribution */
int value = 0;
unsigned int 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_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768);

return value;
}

static av_always_inline unsigned int opus_rc_stepmodel(OpusRangeCoder *rc, int k0)
{
/* Use a probability of 3 up to itheta=8192 and then use 1 after */
unsigned int 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_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;
}

static av_always_inline unsigned int opus_rc_trimodel(OpusRangeCoder *rc, int qn)
{
unsigned int 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_update(rc, scale, low, low + symbol, total);

return k;
}

int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size, int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size,
int self_delimited); int self_delimited);




+ 29
- 29
libavcodec/opus_celt.c View File

@@ -138,7 +138,7 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
/* use the 2D z-transform to apply prediction in both */ /* use the 2D z-transform to apply prediction in both */
/* the time domain (alpha) and the frequency domain (beta) */ /* the time domain (alpha) and the frequency domain (beta) */


if (opus_rc_tell(rc)+3 <= s->framebits && opus_rc_p2model(rc, 3)) {
if (opus_rc_tell(rc)+3 <= s->framebits && ff_opus_rc_dec_log(rc, 3)) {
/* intra frame */ /* intra frame */
alpha = 0; alpha = 0;
beta = 1.0f - 4915.0f/32768.0f; beta = 1.0f - 4915.0f/32768.0f;
@@ -164,12 +164,12 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc)
if (available >= 15) { if (available >= 15) {
/* decode using a Laplace distribution */ /* decode using a Laplace distribution */
int k = FFMIN(i, 20) << 1; int k = FFMIN(i, 20) << 1;
value = opus_rc_laplace(rc, model[k] << 7, model[k+1] << 6);
value = ff_opus_rc_dec_laplace(rc, model[k] << 7, model[k+1] << 6);
} else if (available >= 2) { } else if (available >= 2) {
int x = opus_rc_getsymbol(rc, ff_celt_model_energy_small);
int x = ff_opus_rc_dec_cdf(rc, ff_celt_model_energy_small);
value = (x>>1) ^ -(x&1); value = (x>>1) ^ -(x&1);
} else if (available >= 1) { } else if (available >= 1) {
value = -(float)opus_rc_p2model(rc, 1);
value = -(float)ff_opus_rc_dec_log(rc, 1);
} else value = -1; } else value = -1;


frame->energy[i] = FFMAX(-9.0f, frame->energy[i]) * alpha + prev[j] + value; frame->energy[i] = FFMAX(-9.0f, frame->energy[i]) * alpha + prev[j] + value;
@@ -190,7 +190,7 @@ static void celt_decode_fine_energy(CeltContext *s, OpusRangeCoder *rc)
CeltFrame *frame = &s->frame[j]; CeltFrame *frame = &s->frame[j];
int q2; int q2;
float offset; float offset;
q2 = opus_getrawbits(rc, s->fine_bits[i]);
q2 = ff_opus_rc_get_raw(rc, s->fine_bits[i]);
offset = (q2 + 0.5f) * (1 << (14 - s->fine_bits[i])) / 16384.0f - 0.5f; offset = (q2 + 0.5f) * (1 << (14 - s->fine_bits[i])) / 16384.0f - 0.5f;
frame->energy[i] += offset; frame->energy[i] += offset;
} }
@@ -210,7 +210,7 @@ static void celt_decode_final_energy(CeltContext *s, OpusRangeCoder *rc,
for (j = 0; j < s->coded_channels; j++) { for (j = 0; j < s->coded_channels; j++) {
int q2; int q2;
float offset; float offset;
q2 = opus_getrawbits(rc, 1);
q2 = ff_opus_rc_get_raw(rc, 1);
offset = (q2 - 0.5f) * (1 << (14 - s->fine_bits[i] - 1)) / 16384.0f; offset = (q2 - 0.5f) * (1 << (14 - s->fine_bits[i] - 1)) / 16384.0f;
s->frame[j].energy[i] += offset; s->frame[j].energy[i] += offset;
bits_left--; bits_left--;
@@ -230,7 +230,7 @@ static void celt_decode_tf_changes(CeltContext *s, OpusRangeCoder *rc,


for (i = s->startband; i < s->endband; i++) { for (i = s->startband; i < s->endband; i++) {
if (consumed+bits+tf_select_bit <= s->framebits) { if (consumed+bits+tf_select_bit <= s->framebits) {
diff ^= opus_rc_p2model(rc, bits);
diff ^= ff_opus_rc_dec_log(rc, bits);
consumed = opus_rc_tell(rc); consumed = opus_rc_tell(rc);
tf_changed |= diff; tf_changed |= diff;
} }
@@ -240,7 +240,7 @@ static void celt_decode_tf_changes(CeltContext *s, OpusRangeCoder *rc,


if (tf_select_bit && ff_celt_tf_select[s->duration][transient][0][tf_changed] != if (tf_select_bit && ff_celt_tf_select[s->duration][transient][0][tf_changed] !=
ff_celt_tf_select[s->duration][transient][1][tf_changed]) ff_celt_tf_select[s->duration][transient][1][tf_changed])
tf_select = opus_rc_p2model(rc, 1);
tf_select = ff_opus_rc_dec_log(rc, 1);


for (i = s->startband; i < s->endband; i++) { for (i = s->startband; i < s->endband; i++) {
s->tf_change[i] = ff_celt_tf_select[s->duration][transient][tf_select][s->tf_change[i]]; s->tf_change[i] = ff_celt_tf_select[s->duration][transient][tf_select][s->tf_change[i]];
@@ -277,7 +277,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
/* obtain spread flag */ /* obtain spread flag */
s->spread = CELT_SPREAD_NORMAL; s->spread = CELT_SPREAD_NORMAL;
if (consumed + 4 <= s->framebits) if (consumed + 4 <= s->framebits)
s->spread = opus_rc_getsymbol(rc, ff_celt_model_spread);
s->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread);


/* generate static allocation caps */ /* generate static allocation caps */
for (i = 0; i < CELT_MAX_BANDS; i++) { for (i = 0; i < CELT_MAX_BANDS; i++) {
@@ -297,7 +297,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta)); quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
band_dynalloc = dynalloc; band_dynalloc = dynalloc;
while (consumed + (band_dynalloc<<3) < totalbits && boost[i] < cap[i]) { while (consumed + (band_dynalloc<<3) < totalbits && boost[i] < cap[i]) {
int add = opus_rc_p2model(rc, band_dynalloc);
int add = ff_opus_rc_dec_log(rc, band_dynalloc);
consumed = opus_rc_tell_frac(rc); consumed = opus_rc_tell_frac(rc);
if (!add) if (!add)
break; break;
@@ -313,7 +313,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)


/* obtain allocation trim */ /* obtain allocation trim */
if (consumed + (6 << 3) <= totalbits) if (consumed + (6 << 3) <= totalbits)
alloctrim = opus_rc_getsymbol(rc, ff_celt_model_alloc_trim);
alloctrim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);


/* anti-collapse bit reservation */ /* anti-collapse bit reservation */
totalbits = (s->framebits << 3) - opus_rc_tell_frac(rc) - 1; totalbits = (s->framebits << 3) - opus_rc_tell_frac(rc) - 1;
@@ -465,7 +465,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
/* a "do not skip" marker is only coded if the allocation is /* a "do not skip" marker is only coded if the allocation is
above the chosen threshold */ above the chosen threshold */
if (allocation >= FFMAX(threshold[j], (s->coded_channels + 1) <<3 )) { if (allocation >= FFMAX(threshold[j], (s->coded_channels + 1) <<3 )) {
if (opus_rc_p2model(rc, 1))
if (ff_opus_rc_dec_log(rc, 1))
break; break;


total += 1 << 3; total += 1 << 3;
@@ -489,11 +489,11 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc)
s->dualstereo = 0; s->dualstereo = 0;
if (intensitystereo_bit) if (intensitystereo_bit)
s->intensitystereo = s->startband + s->intensitystereo = s->startband +
opus_rc_unimodel(rc, s->codedbands + 1 - s->startband);
ff_opus_rc_dec_uint(rc, s->codedbands + 1 - s->startband);
if (s->intensitystereo <= s->startband) if (s->intensitystereo <= s->startband)
totalbits += dualstereo_bit; /* no intensity stereo means no dual stereo */ totalbits += dualstereo_bit; /* no intensity stereo means no dual stereo */
else if (dualstereo_bit) else if (dualstereo_bit)
s->dualstereo = opus_rc_p2model(rc, 1);
s->dualstereo = ff_opus_rc_dec_log(rc, 1);


/* supply the remaining bits in this frame to lower bands */ /* supply the remaining bits in this frame to lower bands */
remaining = totalbits - total; remaining = totalbits - total;
@@ -909,7 +909,7 @@ static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, unsigned int
unsigned int idx; unsigned int idx;
#define CELT_PVQ_U(n, k) (ff_celt_pvq_u_row[FFMIN(n, k)][FFMAX(n, k)]) #define CELT_PVQ_U(n, k) (ff_celt_pvq_u_row[FFMIN(n, k)][FFMAX(n, k)])
#define CELT_PVQ_V(n, k) (CELT_PVQ_U(n, k) + CELT_PVQ_U(n, (k) + 1)) #define CELT_PVQ_V(n, k) (CELT_PVQ_U(n, k) + CELT_PVQ_U(n, (k) + 1))
idx = opus_rc_unimodel(rc, CELT_PVQ_V(N, K));
idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K));
return celt_cwrsi(N, K, idx, y); return celt_cwrsi(N, K, idx, y);
} }


@@ -960,7 +960,7 @@ static unsigned int celt_decode_band(CeltContext *s, OpusRangeCoder *rc,
for (i = 0; i <= dualstereo; i++) { for (i = 0; i <= dualstereo; i++) {
int sign = 0; int sign = 0;
if (s->remaining2 >= 1<<3) { if (s->remaining2 >= 1<<3) {
sign = opus_getrawbits(rc, 1);
sign = ff_opus_rc_get_raw(rc, 1);
s->remaining2 -= 1 << 3; s->remaining2 -= 1 << 3;
b -= 1 << 3; b -= 1 << 3;
} }
@@ -1048,16 +1048,16 @@ static unsigned int celt_decode_band(CeltContext *s, OpusRangeCoder *rc,
/* Entropy coding of the angle. We use a uniform pdf for the /* 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. */ time split, a step for stereo, and a triangular one for the rest. */
if (dualstereo && N > 2) if (dualstereo && N > 2)
itheta = opus_rc_stepmodel(rc, qn/2);
itheta = ff_opus_rc_dec_uint_step(rc, qn/2);
else if (dualstereo || B0 > 1) else if (dualstereo || B0 > 1)
itheta = opus_rc_unimodel(rc, qn+1);
itheta = ff_opus_rc_dec_uint(rc, qn+1);
else else
itheta = opus_rc_trimodel(rc, qn);
itheta = ff_opus_rc_dec_uint_tri(rc, qn);
itheta = itheta * 16384 / qn; itheta = itheta * 16384 / qn;
/* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
Let's do that at higher complexity */ Let's do that at higher complexity */
} else if (dualstereo) { } else if (dualstereo) {
inv = (b > 2 << 3 && s->remaining2 > 2 << 3) ? opus_rc_p2model(rc, 2) : 0;
inv = (b > 2 << 3 && s->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0;
itheta = 0; itheta = 0;
} }
qalloc = opus_rc_tell_frac(rc) - tell; qalloc = opus_rc_tell_frac(rc) - tell;
@@ -1103,7 +1103,7 @@ static unsigned int celt_decode_band(CeltContext *s, OpusRangeCoder *rc,
x2 = c ? Y : X; x2 = c ? Y : X;
y2 = c ? X : Y; y2 = c ? X : Y;
if (sbits) if (sbits)
sign = opus_getrawbits(rc, 1);
sign = ff_opus_rc_get_raw(rc, 1);
sign = 1 - 2 * sign; sign = 1 - 2 * sign;
/* We use orig_fill here because we want to fold the side, but if /* 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. */ itheta==16384, we'll have cleared the low bits of fill. */
@@ -1411,16 +1411,16 @@ static int parse_postfilter(CeltContext *s, OpusRangeCoder *rc, int consumed)
memset(s->frame[1].pf_gains_new, 0, sizeof(s->frame[1].pf_gains_new)); memset(s->frame[1].pf_gains_new, 0, sizeof(s->frame[1].pf_gains_new));


if (s->startband == 0 && consumed + 16 <= s->framebits) { if (s->startband == 0 && consumed + 16 <= s->framebits) {
int has_postfilter = opus_rc_p2model(rc, 1);
int has_postfilter = ff_opus_rc_dec_log(rc, 1);
if (has_postfilter) { if (has_postfilter) {
float gain; float gain;
int tapset, octave, period; int tapset, octave, period;


octave = opus_rc_unimodel(rc, 6);
period = (16 << octave) + opus_getrawbits(rc, 4 + octave) - 1;
gain = 0.09375f * (opus_getrawbits(rc, 3) + 1);
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 <= s->framebits) ? tapset = (opus_rc_tell(rc) + 2 <= s->framebits) ?
opus_rc_getsymbol(rc, ff_celt_model_tapset) : 0;
ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;


for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
CeltFrame *frame = &s->frame[i]; CeltFrame *frame = &s->frame[i];
@@ -1636,7 +1636,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,
if (consumed >= s->framebits) if (consumed >= s->framebits)
silence = 1; silence = 1;
else if (consumed == 1) else if (consumed == 1)
silence = opus_rc_p2model(rc, 15);
silence = ff_opus_rc_dec_log(rc, 15);




if (silence) { if (silence) {
@@ -1649,7 +1649,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,


/* obtain transient flag */ /* obtain transient flag */
if (s->duration != 0 && consumed+3 <= s->framebits) if (s->duration != 0 && consumed+3 <= s->framebits)
transient = opus_rc_p2model(rc, 3);
transient = ff_opus_rc_dec_log(rc, 3);


s->blocks = transient ? 1 << s->duration : 1; s->blocks = transient ? 1 << s->duration : 1;
s->blocksize = frame_size / s->blocks; s->blocksize = frame_size / s->blocks;
@@ -1668,7 +1668,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc,
celt_decode_bands (s, rc); celt_decode_bands (s, rc);


if (s->anticollapse_bit) if (s->anticollapse_bit)
anticollapse = opus_getrawbits(rc, 1);
anticollapse = ff_opus_rc_get_raw(rc, 1);


celt_decode_final_energy(s, rc, s->framebits - opus_rc_tell(rc)); celt_decode_final_energy(s, rc, s->framebits - opus_rc_tell(rc));




+ 221
- 0
libavcodec/opus_rc.c View File

@@ -0,0 +1,221 @@
/*
* 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
*/

#include "opus_rc.h"

static av_always_inline void opus_rc_dec_normalize(OpusRangeCoder *rc)
{
while (rc->range <= 1<<23) {
rc->value = ((rc->value << 8) | (get_bits(&rc->gb, 8) ^ 0xFF)) & ((1u << 31) - 1);
rc->range <<= 8;
rc->total_read_bits += 8;
}
}

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);
}

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;
}

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;
}

/**
* 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_read_bits += count;

return value;
}

/**
* 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;
}

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;
}

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;
}

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;
}

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_read_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;
}

+ 85
- 0
libavcodec/opus_rc.h View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef AVCODEC_OPUS_RC_H
#define AVCODEC_OPUS_RC_H

#include <stdint.h>
#include "get_bits.h"

#define opus_ilog(i) (av_log2(i) + !!(i))

typedef struct RawBitsContext {
const uint8_t *position;
uint32_t bytes;
uint32_t cachelen;
uint32_t cacheval;
} RawBitsContext;

typedef struct OpusRangeCoder {
GetBitContext gb;
RawBitsContext rb;
uint32_t range;
uint32_t value;
uint32_t total_read_bits;
} OpusRangeCoder;

/**
* CELT: estimate bits of entropy that have thus far been consumed for the
* current CELT frame, to integer and fractional (1/8th bit) precision
*/
static av_always_inline uint32_t opus_rc_tell(const OpusRangeCoder *rc)
{
return rc->total_read_bits - av_log2(rc->range) - 1;
}

static av_always_inline uint32_t opus_rc_tell_frac(const OpusRangeCoder *rc)
{
uint32_t i, total_bits, rcbuffer, range;

total_bits = rc->total_read_bits << 3;
rcbuffer = av_log2(rc->range) + 1;
range = rc->range >> (rcbuffer-16);

for (i = 0; i < 3; i++) {
int bit;
range = range * range >> 15;
bit = range >> 16;
rcbuffer = rcbuffer << 1 | bit;
range >>= bit;
}

return total_bits - rcbuffer;
}

uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf);
uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits);
uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size);
uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0);
uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn);
uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count);
int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, 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);

#endif /* AVCODEC_OPUS_RC_H */

+ 36
- 36
libavcodec/opus_silk.c View File

@@ -307,15 +307,15 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
*lpc_order = order = s->wb ? 16 : 10; *lpc_order = order = s->wb ? 16 : 10;


/* obtain LSF stage-1 and stage-2 indices */ /* obtain LSF stage-1 and stage-2 indices */
lsf_i1 = opus_rc_getsymbol(rc, ff_silk_model_lsf_s1[s->wb][voiced]);
lsf_i1 = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s1[s->wb][voiced]);
for (i = 0; i < order; i++) { for (i = 0; i < order; i++) {
int index = s->wb ? ff_silk_lsf_s2_model_sel_wb [lsf_i1][i] : int index = s->wb ? ff_silk_lsf_s2_model_sel_wb [lsf_i1][i] :
ff_silk_lsf_s2_model_sel_nbmb[lsf_i1][i]; ff_silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
lsf_i2[i] = opus_rc_getsymbol(rc, ff_silk_model_lsf_s2[index]) - 4;
lsf_i2[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2[index]) - 4;
if (lsf_i2[i] == -4) if (lsf_i2[i] == -4)
lsf_i2[i] -= opus_rc_getsymbol(rc, ff_silk_model_lsf_s2_ext);
lsf_i2[i] -= ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2_ext);
else if (lsf_i2[i] == 4) else if (lsf_i2[i] == 4)
lsf_i2[i] += opus_rc_getsymbol(rc, ff_silk_model_lsf_s2_ext);
lsf_i2[i] += ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2_ext);
} }


/* reverse the backwards-prediction step */ /* reverse the backwards-prediction step */
@@ -365,7 +365,7 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
/* and then convert both sets of NLSFs to LPC coefficients */ /* and then convert both sets of NLSFs to LPC coefficients */
*has_lpc_leadin = 0; *has_lpc_leadin = 0;
if (s->subframes == 4) { if (s->subframes == 4) {
int offset = opus_rc_getsymbol(rc, ff_silk_model_lsf_interpolation_offset);
int offset = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_interpolation_offset);
if (offset != 4 && frame->coded) { if (offset != 4 && frame->coded) {
*has_lpc_leadin = 1; *has_lpc_leadin = 1;
if (offset != 0) { if (offset != 0) {
@@ -394,7 +394,7 @@ static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t to
int32_t child[2]) int32_t child[2])
{ {
if (total != 0) { if (total != 0) {
child[0] = opus_rc_getsymbol(rc,
child[0] = ff_opus_rc_dec_cdf(rc,
ff_silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1)); ff_silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1));
child[1] = total - child[0]; child[1] = total - child[0];
} else { } else {
@@ -416,17 +416,17 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
int32_t excitation[320]; // Q23 int32_t excitation[320]; // Q23


/* excitation parameters */ /* excitation parameters */
seed = opus_rc_getsymbol(rc, ff_silk_model_lcg_seed);
seed = ff_opus_rc_dec_cdf(rc, ff_silk_model_lcg_seed);
shellblocks = ff_silk_shell_blocks[s->bandwidth][s->subframes >> 2]; shellblocks = ff_silk_shell_blocks[s->bandwidth][s->subframes >> 2];
ratelevel = opus_rc_getsymbol(rc, ff_silk_model_exc_rate[voiced]);
ratelevel = ff_opus_rc_dec_cdf(rc, ff_silk_model_exc_rate[voiced]);


for (i = 0; i < shellblocks; i++) { for (i = 0; i < shellblocks; i++) {
pulsecount[i] = opus_rc_getsymbol(rc, ff_silk_model_pulse_count[ratelevel]);
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[ratelevel]);
if (pulsecount[i] == 17) { if (pulsecount[i] == 17) {
while (pulsecount[i] == 17 && ++lsbcount[i] != 10) while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
pulsecount[i] = opus_rc_getsymbol(rc, ff_silk_model_pulse_count[9]);
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[9]);
if (lsbcount[i] == 10) if (lsbcount[i] == 10)
pulsecount[i] = opus_rc_getsymbol(rc, ff_silk_model_pulse_count[10]);
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[10]);
} }
} }


@@ -461,13 +461,13 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
int bit; int bit;
for (bit = 0; bit < lsbcount[i >> 4]; bit++) for (bit = 0; bit < lsbcount[i >> 4]; bit++)
excitation[i] = (excitation[i] << 1) | excitation[i] = (excitation[i] << 1) |
opus_rc_getsymbol(rc, ff_silk_model_excitation_lsb);
ff_opus_rc_dec_cdf(rc, ff_silk_model_excitation_lsb);
} }


/* decode signs */ /* decode signs */
for (i = 0; i < shellblocks << 4; i++) { for (i = 0; i < shellblocks << 4; i++) {
if (excitation[i] != 0) { if (excitation[i] != 0) {
int sign = opus_rc_getsymbol(rc, ff_silk_model_excitation_sign[active +
int sign = ff_opus_rc_dec_cdf(rc, ff_silk_model_excitation_sign[active +
voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]); voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]);
if (sign == 0) if (sign == 0)
excitation[i] *= -1; excitation[i] *= -1;
@@ -522,11 +522,11 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
/* obtain stereo weights */ /* obtain stereo weights */
if (coded_channels == 2 && channel == 0) { if (coded_channels == 2 && channel == 0) {
int n, wi[2], ws[2], w[2]; int n, wi[2], ws[2], w[2];
n = opus_rc_getsymbol(rc, ff_silk_model_stereo_s1);
wi[0] = opus_rc_getsymbol(rc, ff_silk_model_stereo_s2) + 3 * (n / 5);
ws[0] = opus_rc_getsymbol(rc, ff_silk_model_stereo_s3);
wi[1] = opus_rc_getsymbol(rc, ff_silk_model_stereo_s2) + 3 * (n % 5);
ws[1] = opus_rc_getsymbol(rc, ff_silk_model_stereo_s3);
n = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s1);
wi[0] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s2) + 3 * (n / 5);
ws[0] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s3);
wi[1] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s2) + 3 * (n % 5);
ws[1] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s3);


for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
w[i] = ff_silk_stereo_weights[wi[i]] + w[i] = ff_silk_stereo_weights[wi[i]] +
@@ -537,15 +537,15 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
s->stereo_weights[1] = w[1] / 8192.0; s->stereo_weights[1] = w[1] / 8192.0;


/* and read the mid-only flag */ /* and read the mid-only flag */
s->midonly = active1 ? 0 : opus_rc_getsymbol(rc, ff_silk_model_mid_only);
s->midonly = active1 ? 0 : ff_opus_rc_dec_cdf(rc, ff_silk_model_mid_only);
} }


/* obtain frame type */ /* obtain frame type */
if (!active) { if (!active) {
qoffset_high = opus_rc_getsymbol(rc, ff_silk_model_frame_type_inactive);
qoffset_high = ff_opus_rc_dec_cdf(rc, ff_silk_model_frame_type_inactive);
voiced = 0; voiced = 0;
} else { } else {
int type = opus_rc_getsymbol(rc, ff_silk_model_frame_type_active);
int type = ff_opus_rc_dec_cdf(rc, ff_silk_model_frame_type_active);
qoffset_high = type & 1; qoffset_high = type & 1;
voiced = type >> 1; voiced = type >> 1;
} }
@@ -557,14 +557,14 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,


if (i == 0 && (frame_num == 0 || !frame->coded)) { if (i == 0 && (frame_num == 0 || !frame->coded)) {
/* gain is coded absolute */ /* gain is coded absolute */
int x = opus_rc_getsymbol(rc, ff_silk_model_gain_highbits[active + voiced]);
log_gain = (x<<3) | opus_rc_getsymbol(rc, ff_silk_model_gain_lowbits);
int x = ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_highbits[active + voiced]);
log_gain = (x<<3) | ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_lowbits);


if (frame->coded) if (frame->coded)
log_gain = FFMAX(log_gain, frame->log_gain - 16); log_gain = FFMAX(log_gain, frame->log_gain - 16);
} else { } else {
/* gain is coded relative */ /* gain is coded relative */
int delta_gain = opus_rc_getsymbol(rc, ff_silk_model_gain_delta);
int delta_gain = ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_delta);
log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16, log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
frame->log_gain + delta_gain - 4), 6); frame->log_gain + delta_gain - 4), 6);
} }
@@ -590,7 +590,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
const int8_t * offsets; const int8_t * offsets;


if (!lag_absolute) { if (!lag_absolute) {
int delta = opus_rc_getsymbol(rc, ff_silk_model_pitch_delta);
int delta = ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_delta);
if (delta) if (delta)
primarylag = frame->primarylag + delta - 9; primarylag = frame->primarylag + delta - 9;
else else
@@ -604,8 +604,8 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
ff_silk_model_pitch_lowbits_nb, ff_silk_model_pitch_lowbits_mb, ff_silk_model_pitch_lowbits_nb, ff_silk_model_pitch_lowbits_mb,
ff_silk_model_pitch_lowbits_wb ff_silk_model_pitch_lowbits_wb
}; };
highbits = opus_rc_getsymbol(rc, ff_silk_model_pitch_highbits);
lowbits = opus_rc_getsymbol(rc, model[s->bandwidth]);
highbits = ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_highbits);
lowbits = ff_opus_rc_dec_cdf(rc, model[s->bandwidth]);


primarylag = ff_silk_pitch_min_lag[s->bandwidth] + primarylag = ff_silk_pitch_min_lag[s->bandwidth] +
highbits*ff_silk_pitch_scale[s->bandwidth] + lowbits; highbits*ff_silk_pitch_scale[s->bandwidth] + lowbits;
@@ -614,15 +614,15 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,


if (s->subframes == 2) if (s->subframes == 2)
offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND) offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
? ff_silk_pitch_offset_nb10ms[opus_rc_getsymbol(rc,
? ff_silk_pitch_offset_nb10ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_nb10ms)] ff_silk_model_pitch_contour_nb10ms)]
: ff_silk_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc,
: ff_silk_pitch_offset_mbwb10ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_mbwb10ms)]; ff_silk_model_pitch_contour_mbwb10ms)];
else else
offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND) offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
? ff_silk_pitch_offset_nb20ms[opus_rc_getsymbol(rc,
? ff_silk_pitch_offset_nb20ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_nb20ms)] ff_silk_model_pitch_contour_nb20ms)]
: ff_silk_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc,
: ff_silk_pitch_offset_mbwb20ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_mbwb20ms)]; ff_silk_model_pitch_contour_mbwb20ms)];


for (i = 0; i < s->subframes; i++) for (i = 0; i < s->subframes; i++)
@@ -631,7 +631,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
ff_silk_pitch_max_lag[s->bandwidth]); ff_silk_pitch_max_lag[s->bandwidth]);


/* obtain LTP filter coefficients */ /* obtain LTP filter coefficients */
ltpfilter = opus_rc_getsymbol(rc, ff_silk_model_ltp_filter);
ltpfilter = ff_opus_rc_dec_cdf(rc, ff_silk_model_ltp_filter);
for (i = 0; i < s->subframes; i++) { for (i = 0; i < s->subframes; i++) {
int index, j; int index, j;
static const uint16_t *filter_sel[] = { static const uint16_t *filter_sel[] = {
@@ -641,7 +641,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
static const int8_t (*filter_taps[])[5] = { static const int8_t (*filter_taps[])[5] = {
ff_silk_ltp_filter0_taps, ff_silk_ltp_filter1_taps, ff_silk_ltp_filter2_taps ff_silk_ltp_filter0_taps, ff_silk_ltp_filter1_taps, ff_silk_ltp_filter2_taps
}; };
index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]);
index = ff_opus_rc_dec_cdf(rc, filter_sel[ltpfilter]);
for (j = 0; j < 5; j++) for (j = 0; j < 5; j++)
sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f; sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
} }
@@ -649,7 +649,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,


/* obtain LTP scale factor */ /* obtain LTP scale factor */
if (voiced && frame_num == 0) if (voiced && frame_num == 0)
ltpscale = ff_silk_ltp_scale_factor[opus_rc_getsymbol(rc,
ltpscale = ff_silk_ltp_scale_factor[ff_opus_rc_dec_cdf(rc,
ff_silk_model_ltp_scale_index)] / 16384.0f; ff_silk_model_ltp_scale_index)] / 16384.0f;
else ltpscale = 15565.0f/16384.0f; else ltpscale = 15565.0f/16384.0f;


@@ -803,9 +803,9 @@ int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
/* read the LP-layer header bits */ /* read the LP-layer header bits */
for (i = 0; i < coded_channels; i++) { for (i = 0; i < coded_channels; i++) {
for (j = 0; j < nb_frames; j++) for (j = 0; j < nb_frames; j++)
active[i][j] = opus_rc_p2model(rc, 1);
active[i][j] = ff_opus_rc_dec_log(rc, 1);


redundancy[i] = opus_rc_p2model(rc, 1);
redundancy[i] = ff_opus_rc_dec_log(rc, 1);
if (redundancy[i]) { if (redundancy[i]) {
av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n"); av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n");
return AVERROR_PATCHWELCOME; return AVERROR_PATCHWELCOME;


+ 7
- 33
libavcodec/opusdec.c View File

@@ -73,32 +73,6 @@ static int get_silk_samplerate(int config)
return 16000; return 16000;
} }


/**
* Range decoder
*/
static int opus_rc_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_read_bits = 9;
opus_rc_normalize(rc);

return 0;
}

static void opus_raw_init(OpusRangeCoder *rc, const uint8_t *rightend,
unsigned int bytes)
{
rc->rb.position = rightend;
rc->rb.bytes = bytes;
rc->rb.cachelen = 0;
rc->rb.cacheval = 0;
}

static void opus_fade(float *out, static void opus_fade(float *out,
const float *in1, const float *in2, const float *in1, const float *in2,
const float *window, int len) const float *window, int len)
@@ -185,10 +159,10 @@ static int opus_decode_redundancy(OpusStreamContext *s, const uint8_t *data, int
bw == OPUS_BANDWIDTH_MEDIUMBAND) bw == OPUS_BANDWIDTH_MEDIUMBAND)
bw = OPUS_BANDWIDTH_WIDEBAND; bw = OPUS_BANDWIDTH_WIDEBAND;


ret = opus_rc_init(&s->redundancy_rc, data, size);
ret = ff_opus_rc_dec_init(&s->redundancy_rc, data, size);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
opus_raw_init(&s->redundancy_rc, data + size, size);
ff_opus_rc_dec_raw_init(&s->redundancy_rc, data + size, size);


ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc, ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc,
s->redundancy_output, s->redundancy_output,
@@ -211,7 +185,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
int ret, i, consumed; int ret, i, consumed;
int delayed_samples = s->delayed_samples; int delayed_samples = s->delayed_samples;


ret = opus_rc_init(&s->rc, data, size);
ret = ff_opus_rc_dec_init(&s->rc, data, size);
if (ret < 0) if (ret < 0)
return ret; return ret;


@@ -246,15 +220,15 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
// decode redundancy information // decode redundancy information
consumed = opus_rc_tell(&s->rc); consumed = opus_rc_tell(&s->rc);
if (s->packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8) if (s->packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8)
redundancy = opus_rc_p2model(&s->rc, 12);
redundancy = ff_opus_rc_dec_log(&s->rc, 12);
else if (s->packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8) else if (s->packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8)
redundancy = 1; redundancy = 1;


if (redundancy) { if (redundancy) {
redundancy_pos = opus_rc_p2model(&s->rc, 1);
redundancy_pos = ff_opus_rc_dec_log(&s->rc, 1);


if (s->packet.mode == OPUS_MODE_HYBRID) if (s->packet.mode == OPUS_MODE_HYBRID)
redundancy_size = opus_rc_unimodel(&s->rc, 256) + 2;
redundancy_size = ff_opus_rc_dec_uint(&s->rc, 256) + 2;
else else
redundancy_size = size - (consumed + 7) / 8; redundancy_size = size - (consumed + 7) / 8;
size -= redundancy_size; size -= redundancy_size;
@@ -298,7 +272,7 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size
} }
} }


opus_raw_init(&s->rc, data + size, size);
ff_opus_rc_dec_raw_init(&s->rc, data + size, size);


ret = ff_celt_decode_frame(s->celt, &s->rc, dst, ret = ff_celt_decode_frame(s->celt, &s->rc, dst,
s->packet.stereo + 1, s->packet.stereo + 1,


Loading…
Cancel
Save