diff options
author | Rostislav Pehlivanov <atomnuker@gmail.com> | 2016-11-07 22:33:11 +0000 |
---|---|---|
committer | Rostislav Pehlivanov <atomnuker@gmail.com> | 2016-11-08 14:18:59 +0000 |
commit | 317be31eaf4f07b3bbeb703e8ee73d04b08a587c (patch) | |
tree | 9a07a44dde6a86a34bb8d6f7675b8eeaabd15f56 /libavcodec/opus.h | |
parent | 0660a09dd1d12e17216d44ec42584690d812b7f3 (diff) |
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>
Diffstat (limited to 'libavcodec/opus.h')
-rw-r--r-- | libavcodec/opus.h | 222 |
1 files changed, 1 insertions, 221 deletions
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); |