From 317be31eaf4f07b3bbeb703e8ee73d04b08a587c Mon Sep 17 00:00:00 2001 From: Rostislav Pehlivanov Date: Mon, 7 Nov 2016 22:33:11 +0000 Subject: [PATCH] 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 --- libavcodec/Makefile | 2 +- libavcodec/opus.h | 222 +---------------------------------------- libavcodec/opus_celt.c | 58 +++++------ libavcodec/opus_rc.c | 221 ++++++++++++++++++++++++++++++++++++++++ libavcodec/opus_rc.h | 85 ++++++++++++++++ libavcodec/opus_silk.c | 72 ++++++------- libavcodec/opusdec.c | 40 ++------ 7 files changed, 380 insertions(+), 320 deletions(-) create mode 100644 libavcodec/opus_rc.c create mode 100644 libavcodec/opus_rc.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 8e4087ef62..5fdc97f602 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -436,7 +436,7 @@ OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o -OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o \ +OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opus.o opus_celt.o opus_rc.o \ opus_silk.o opustab.o vorbis_data.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o diff --git a/libavcodec/opus.h b/libavcodec/opus.h index 3a7ea9f504..2079f423b4 100644 --- a/libavcodec/opus.h +++ b/libavcodec/opus.h @@ -32,7 +32,7 @@ #include "libswresample/swresample.h" #include "avcodec.h" -#include "get_bits.h" +#include "opus_rc.h" #define MAX_FRAME_SIZE 1275 #define MAX_FRAMES 48 @@ -59,7 +59,6 @@ #define ROUND_MULL(a,b,s) (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1) #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_MASK 0xFFE0 // top 11 bits @@ -84,21 +83,6 @@ enum OpusBandwidth { 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 CeltContext CeltContext; @@ -193,210 +177,6 @@ typedef struct OpusContext { ChannelMap *channel_maps; } 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 self_delimited); diff --git a/libavcodec/opus_celt.c b/libavcodec/opus_celt.c index ea097bd261..c115ee7ad3 100644 --- a/libavcodec/opus_celt.c +++ b/libavcodec/opus_celt.c @@ -138,7 +138,7 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc) /* use the 2D z-transform to apply prediction in both */ /* 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 */ alpha = 0; beta = 1.0f - 4915.0f/32768.0f; @@ -164,12 +164,12 @@ static void celt_decode_coarse_energy(CeltContext *s, OpusRangeCoder *rc) if (available >= 15) { /* decode using a Laplace distribution */ 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) { - 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); } else if (available >= 1) { - value = -(float)opus_rc_p2model(rc, 1); + value = -(float)ff_opus_rc_dec_log(rc, 1); } else value = -1; 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]; int q2; 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; 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++) { int q2; 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; s->frame[j].energy[i] += offset; bits_left--; @@ -230,7 +230,7 @@ static void celt_decode_tf_changes(CeltContext *s, OpusRangeCoder *rc, for (i = s->startband; i < s->endband; i++) { 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); 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] != 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++) { 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 */ s->spread = CELT_SPREAD_NORMAL; 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 */ 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)); band_dynalloc = dynalloc; 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); if (!add) break; @@ -313,7 +313,7 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc) /* obtain allocation trim */ 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 */ 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 above the chosen threshold */ 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; total += 1 << 3; @@ -489,11 +489,11 @@ static void celt_decode_allocation(CeltContext *s, OpusRangeCoder *rc) s->dualstereo = 0; if (intensitystereo_bit) 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) totalbits += dualstereo_bit; /* no intensity stereo means no dual stereo */ 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 */ remaining = totalbits - total; @@ -909,7 +909,7 @@ static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, unsigned int unsigned int idx; #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)) - 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); } @@ -960,7 +960,7 @@ static unsigned int celt_decode_band(CeltContext *s, OpusRangeCoder *rc, for (i = 0; i <= dualstereo; i++) { int sign = 0; if (s->remaining2 >= 1<<3) { - sign = opus_getrawbits(rc, 1); + sign = ff_opus_rc_get_raw(rc, 1); s->remaining2 -= 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 time split, a step for stereo, and a triangular one for the rest. */ 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) - itheta = opus_rc_unimodel(rc, qn+1); + itheta = ff_opus_rc_dec_uint(rc, qn+1); else - itheta = opus_rc_trimodel(rc, qn); + itheta = ff_opus_rc_dec_uint_tri(rc, qn); itheta = itheta * 16384 / qn; /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. Let's do that at higher complexity */ } 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; } 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; y2 = c ? X : Y; if (sbits) - sign = opus_getrawbits(rc, 1); + 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. */ @@ -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)); 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) { float gain; 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) ? - 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++) { CeltFrame *frame = &s->frame[i]; @@ -1636,7 +1636,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc, if (consumed >= s->framebits) silence = 1; else if (consumed == 1) - silence = opus_rc_p2model(rc, 15); + silence = ff_opus_rc_dec_log(rc, 15); if (silence) { @@ -1649,7 +1649,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc, /* obtain transient flag */ 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->blocksize = frame_size / s->blocks; @@ -1668,7 +1668,7 @@ int ff_celt_decode_frame(CeltContext *s, OpusRangeCoder *rc, celt_decode_bands (s, rc); 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)); diff --git a/libavcodec/opus_rc.c b/libavcodec/opus_rc.c new file mode 100644 index 0000000000..1f9af041aa --- /dev/null +++ b/libavcodec/opus_rc.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * 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; +} diff --git a/libavcodec/opus_rc.h b/libavcodec/opus_rc.h new file mode 100644 index 0000000000..68ebc05af6 --- /dev/null +++ b/libavcodec/opus_rc.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 Andrew D'Addesio + * Copyright (c) 2013-2014 Mozilla Corporation + * Copyright (c) 2016 Rostislav Pehlivanov + * + * 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 +#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 */ diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index c64d24c5da..4561b5a998 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -307,15 +307,15 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame, *lpc_order = order = s->wb ? 16 : 10; /* 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++) { int index = s->wb ? ff_silk_lsf_s2_model_sel_wb [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) - 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) - 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 */ @@ -365,7 +365,7 @@ static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame, /* and then convert both sets of NLSFs to LPC coefficients */ *has_lpc_leadin = 0; 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) { *has_lpc_leadin = 1; if (offset != 0) { @@ -394,7 +394,7 @@ static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t to int32_t child[2]) { 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)); child[1] = total - child[0]; } else { @@ -416,17 +416,17 @@ static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc, int32_t excitation[320]; // Q23 /* 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]; - 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++) { - 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) { 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) - 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; for (bit = 0; bit < lsbcount[i >> 4]; bit++) 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 */ for (i = 0; i < shellblocks << 4; i++) { 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)]); if (sign == 0) excitation[i] *= -1; @@ -522,11 +522,11 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, /* obtain stereo weights */ if (coded_channels == 2 && channel == 0) { 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++) 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; /* 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 */ 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; } 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; voiced = type >> 1; } @@ -557,14 +557,14 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, if (i == 0 && (frame_num == 0 || !frame->coded)) { /* 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) log_gain = FFMAX(log_gain, frame->log_gain - 16); } else { /* 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, frame->log_gain + delta_gain - 4), 6); } @@ -590,7 +590,7 @@ static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc, const int8_t * offsets; 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) primarylag = frame->primarylag + delta - 9; 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_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] + 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) 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_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc, + : ff_silk_pitch_offset_mbwb10ms[ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_contour_mbwb10ms)]; else 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_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc, + : ff_silk_pitch_offset_mbwb20ms[ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_contour_mbwb20ms)]; 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]); /* 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++) { int index, j; 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] = { 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++) 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 */ 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; 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 */ for (i = 0; i < coded_channels; i++) { 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]) { av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n"); return AVERROR_PATCHWELCOME; diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index 95a2435e53..ec793c6c47 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -73,32 +73,6 @@ static int get_silk_samplerate(int config) 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, const float *in1, const float *in2, 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_WIDEBAND; - ret = opus_rc_init(&s->redundancy_rc, data, size); + ret = ff_opus_rc_dec_init(&s->redundancy_rc, data, size); if (ret < 0) 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, 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 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) return ret; @@ -246,15 +220,15 @@ static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size // decode redundancy information consumed = opus_rc_tell(&s->rc); 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) redundancy = 1; 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) - redundancy_size = opus_rc_unimodel(&s->rc, 256) + 2; + redundancy_size = ff_opus_rc_dec_uint(&s->rc, 256) + 2; else redundancy_size = size - (consumed + 7) / 8; 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, s->packet.stereo + 1,