Newer
Older
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
Diego Biurrun
committed
* 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
Diego Biurrun
committed
* version 2.1 of the License, or (at your option) any later version.
Diego Biurrun
committed
* 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
Diego Biurrun
committed
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
Michael Niedermayer
committed
/**
Michael Niedermayer
committed
*/
#ifndef AVCODEC_GET_BITS_H
#define AVCODEC_GET_BITS_H
Michael Niedermayer
committed
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/avassert.h"
/*
* Safe bitstream reading:
* optionally, the get_bits API can check to ensure that we
* don't read past input buffer boundaries. This is protected
* with CONFIG_SAFE_BITSTREAM_READER at the global level, and
* then below that with UNCHECKED_BITSTREAM_READER at the per-
* decoder level. This means that decoders that check internally
* can "#define UNCHECKED_BITSTREAM_READER 1" to disable
* overread checks.
* Boundary checking causes a minor performance penalty so for
* applications that won't want/need this, it can be disabled
* globally using "#define CONFIG_SAFE_BITSTREAM_READER 0".
*/
#ifndef UNCHECKED_BITSTREAM_READER
#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER
#endif
Michael Niedermayer
committed
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
Michael Niedermayer
committed
} GetBitContext;
#define VLC_TYPE int16_t
typedef struct VLC {
int bits;
VLC_TYPE (*table)[2]; ///< code, bits
int table_size, table_allocated;
} VLC;
typedef struct RL_VLC_ELEM {
int16_t level;
int8_t len;
uint8_t run;
} RL_VLC_ELEM;
/* Bitstream reader API docs:
name
arbitrary name which is used as prefix for the internal variables
Michael Niedermayer
committed
gb
getbitcontext
OPEN_READER(name, gb)
load gb into local variables
Michael Niedermayer
committed
CLOSE_READER(name, gb)
store local vars in gb
Michael Niedermayer
committed
UPDATE_CACHE(name, gb)
refill the internal cache from the bitstream
Michael Niedermayer
committed
after this call at least MIN_CACHE_BITS will be available,
GET_CACHE(name, gb)
will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
SHOW_UBITS(name, gb, num)
Michael Niedermayer
committed
SHOW_SBITS(name, gb, num)
Michael Niedermayer
committed
SKIP_BITS(name, gb, num)
will skip over the next num bits
Michael Niedermayer
committed
SKIP_CACHE(name, gb, num)
will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
SKIP_COUNTER(name, gb, num)
will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
LAST_SKIP_BITS(name, gb, num)
like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER
Michael Niedermayer
committed
for examples see get_bits, show_bits, skip_bits, get_vlc
*/
#ifdef LONG_BITSTREAM_READER
# define MIN_CACHE_BITS 32
#else
Michael Niedermayer
committed
# define MIN_CACHE_BITS 25
Michael Niedermayer
committed
#if UNCHECKED_BITSTREAM_READER
unsigned int name##_index = (gb)->index; \
av_unused unsigned int name##_cache
Michael Niedermayer
committed
#define HAVE_BITS_REMAINING(name, gb) 1
#else
#define OPEN_READER(name, gb) \
unsigned int name##_index = (gb)->index; \
unsigned int av_unused name##_cache = 0; \
unsigned int av_unused name##_size_plus8 = \
(gb)->size_in_bits_plus8
#define HAVE_BITS_REMAINING(name, gb) \
name##_index < name##_size_plus8
#endif
#define CLOSE_READER(name, gb) (gb)->index = name##_index
#ifdef BITSTREAM_READER_LE
Michael Niedermayer
committed
# define UPDATE_CACHE(name, gb) name##_cache = \
AV_RL64((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
# define UPDATE_CACHE(name, gb) name##_cache = \
AV_RL32((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num) name##_cache >>= (num)
#else
# define UPDATE_CACHE(name, gb) name##_cache = \
AV_RB64((gb)->buffer + (name##_index >> 3)) >> (32 - (name##_index & 7))
# define UPDATE_CACHE(name, gb) name##_cache = \
AV_RB32((gb)->buffer + (name##_index >> 3)) << (name##_index & 7)
Michael Niedermayer
committed
# define SKIP_CACHE(name, gb, num) name##_cache <<= (num)
Michael Niedermayer
committed
Michael Niedermayer
committed
#if UNCHECKED_BITSTREAM_READER
# define SKIP_COUNTER(name, gb, num) name##_index += (num)
#else
# define SKIP_COUNTER(name, gb, num) \
name##_index = FFMIN(name##_size_plus8, name##_index + (num))
Michael Niedermayer
committed
#define SKIP_BITS(name, gb, num) do { \
SKIP_CACHE(name, gb, num); \
SKIP_COUNTER(name, gb, num); \
} while (0)
Michael Niedermayer
committed
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
Michael Niedermayer
committed
#ifdef BITSTREAM_READER_LE
# define SHOW_UBITS(name, gb, num) zero_extend(name##_cache, num)
# define SHOW_SBITS(name, gb, num) sign_extend(name##_cache, num)
# define SHOW_UBITS(name, gb, num) NEG_USR32(name##_cache, num)
# define SHOW_SBITS(name, gb, num) NEG_SSR32(name##_cache, num)
Michael Niedermayer
committed
#define GET_CACHE(name, gb) ((uint32_t)name##_cache)
Michael Niedermayer
committed
static inline int get_bits_count(const GetBitContext *s)
{
Michael Niedermayer
committed
return s->index;
}
Michael Niedermayer
committed
static inline void skip_bits_long(GetBitContext *s, int n){
#if UNCHECKED_BITSTREAM_READER
#else
s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index);
#endif
Michael Niedermayer
committed
}
Michael Niedermayer
committed
/**
* read mpeg1 dc style vlc (sign bit + mantisse with no MSB).
* if MSB not set it is negative
Michael Niedermayer
committed
* @param n length in bits
*/
static inline int get_xbits(GetBitContext *s, int n)
{
Michael Niedermayer
committed
register int32_t cache;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
cache = GET_CACHE(re, s);
sign = ~cache >> 31;
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
Michael Niedermayer
committed
}
static inline int get_sbits(GetBitContext *s, int n)
{
Michael Niedermayer
committed
register int tmp;
av_assert2(n>0 && n<=25);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
Michael Niedermayer
committed
return tmp;
}
/**
Michael Niedermayer
committed
*/
static inline unsigned int get_bits(GetBitContext *s, int n)
{
Michael Niedermayer
committed
register int tmp;
av_assert2(n>0 && n<=25);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
Michael Niedermayer
committed
return tmp;
}
/**
Michael Niedermayer
committed
*/
static inline unsigned int show_bits(GetBitContext *s, int n)
{
Michael Niedermayer
committed
register int tmp;
av_assert2(n>0 && n<=25);
Michael Niedermayer
committed
return tmp;
}
static inline void skip_bits(GetBitContext *s, int n)
{
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
LAST_SKIP_BITS(re, s, n);
CLOSE_READER(re, s);
Michael Niedermayer
committed
}
static inline unsigned int get_bits1(GetBitContext *s)
{
unsigned int index = s->index;
uint8_t result = s->buffer[index>>3];
#ifdef BITSTREAM_READER_LE
Michael Niedermayer
committed
#else
result <<= index & 7;
result >>= 8 - 1;
Michael Niedermayer
committed
#endif
#if !UNCHECKED_BITSTREAM_READER
if (s->index < s->size_in_bits_plus8)
#endif
index++;
Michael Niedermayer
committed
return result;
}
static inline unsigned int show_bits1(GetBitContext *s)
{
Michael Niedermayer
committed
return show_bits(s, 1);
}
static inline void skip_bits1(GetBitContext *s)
{
Michael Niedermayer
committed
skip_bits(s, 1);
}
static inline unsigned int get_bits_long(GetBitContext *s, int n)
{
if (!n) {
return 0;
} else if (n <= MIN_CACHE_BITS)
#ifdef BITSTREAM_READER_LE
return ret | (get_bits(s, n-16) << 16);
#else
unsigned ret = get_bits(s, 16) << (n-16);
return ret | get_bits(s, n-16);
/**
* Read 0-64 bits.
*/
static inline uint64_t get_bits64(GetBitContext *s, int n)
Michael Niedermayer
committed
if (n <= 32) {
return get_bits_long(s, n);
Michael Niedermayer
committed
} else {
#ifdef BITSTREAM_READER_LE
uint64_t ret = get_bits_long(s, 32);
Michael Niedermayer
committed
return ret | (uint64_t)get_bits_long(s, n - 32) << 32;
#else
Michael Niedermayer
committed
uint64_t ret = (uint64_t)get_bits_long(s, n - 32) << 32;
return ret | get_bits_long(s, 32);
#endif
}
}
* Read 0-32 bits as a signed integer.
static inline int get_sbits_long(GetBitContext *s, int n)
{
return sign_extend(get_bits_long(s, n), n);
}
static inline unsigned int show_bits_long(GetBitContext *s, int n)
{
if (n <= MIN_CACHE_BITS)
return show_bits(s, n);
Reimar Döffinger
committed
return get_bits_long(&gb, n);
}
}
static inline int check_marker(GetBitContext *s, const char *msg)
{
av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg);
return bit;
}
Michael Niedermayer
committed
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
Michael Niedermayer
committed
* @param bit_size the size of the buffer in bits
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
Michael Niedermayer
committed
*/
static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
Michael Niedermayer
committed
{
int buffer_size;
int ret = 0;
if (bit_size > INT_MAX - 7 || bit_size < 0) {
Michel Bardiaux
committed
buffer_size = bit_size = 0;
buffer = NULL;
Michel Bardiaux
committed
}
Michael Niedermayer
committed
buffer_size = (bit_size + 7) >> 3;
s->buffer = buffer;
s->size_in_bits = bit_size;
s->size_in_bits_plus8 = bit_size + 8;
s->buffer_end = buffer + buffer_size;
s->index = 0;
Michael Niedermayer
committed
}
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param byte_size the size of the buffer in bytes
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
int byte_size)
{
if (byte_size > INT_MAX / 8)
return AVERROR_INVALIDDATA;
return init_get_bits(s, buffer, byte_size * 8);
Michael Niedermayer
committed
}
static inline void align_get_bits(GetBitContext *s)
Michael Niedermayer
committed
{
int n = -get_bits_count(s) & 7;
if (n) skip_bits(s, n);
Michael Niedermayer
committed
}
#define init_vlc(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
flags) \
ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \
bits, bits_wrap, bits_size, \
codes, codes_wrap, codes_size, \
NULL, 0, 0, flags)
Loren Merritt
committed
int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
Michael Niedermayer
committed
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
Loren Merritt
committed
const void *symbols, int symbols_wrap, int symbols_size,
Michael Niedermayer
committed
int flags);
#define INIT_VLC_LE 2
Michael Niedermayer
committed
#define INIT_VLC_USE_NEW_STATIC 4
void ff_free_vlc(VLC *vlc);
Michael Niedermayer
committed
#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size) do { \
static VLC_TYPE table[static_size][2]; \
(vlc)->table = table; \
(vlc)->table_allocated = static_size; \
init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC); \
} while (0)
Michael Niedermayer
committed
Michael Niedermayer
committed
/**
* If the vlc code is invalid and max_depth=1, then no bits will be removed.
* If the vlc code is invalid and max_depth>1, then the number of bits removed
* is undefined.
Michael Niedermayer
committed
*/
#define GET_VLC(code, name, gb, table, bits, max_depth) \
do { \
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
code = table[index][0]; \
n = table[index][1]; \
\
if (max_depth > 1 && n < 0) { \
LAST_SKIP_BITS(name, gb, bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
if (max_depth > 2 && n < 0) { \
LAST_SKIP_BITS(name, gb, nb_bits); \
UPDATE_CACHE(name, gb); \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + code; \
code = table[index][0]; \
n = table[index][1]; \
} \
} \
SKIP_BITS(name, gb, n); \
} while (0)
#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update) \
do { \
int n, nb_bits; \
unsigned int index; \
\
index = SHOW_UBITS(name, gb, bits); \
level = table[index].level; \
n = table[index].len; \
\
if (max_depth > 1 && n < 0) { \
SKIP_BITS(name, gb, bits); \
if (need_update) { \
UPDATE_CACHE(name, gb); \
} \
\
nb_bits = -n; \
\
index = SHOW_UBITS(name, gb, nb_bits) + level; \
level = table[index].level; \
n = table[index].len; \
} \
run = table[index].run; \
SKIP_BITS(name, gb, n); \
} while (0)
Michael Niedermayer
committed
/**
* @param bits is the number of bits which will be read at once, must be
Michael Niedermayer
committed
* identical to nb_bits in init_vlc()
* @param max_depth is the number of times bits bits must be read to completely
Michael Niedermayer
committed
* = (max_vlc_length + bits - 1) / bits
*/
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
Michael Niedermayer
committed
{
int code;
OPEN_READER(re, s);
UPDATE_CACHE(re, s);
Michael Niedermayer
committed
GET_VLC(code, re, s, table, bits, max_depth);
Michael Niedermayer
committed
Michael Niedermayer
committed
return code;
}
static inline int decode012(GetBitContext *gb)
{
int n;
n = get_bits1(gb);
if (n == 0)
return 0;
else
return get_bits1(gb) + 1;
}
static inline int decode210(GetBitContext *gb)
{
if (get_bits1(gb))
return 0;
else
return 2 - get_bits1(gb);
}
static inline int get_bits_left(GetBitContext *gb)
{
return gb->size_in_bits - get_bits_count(gb);
}
Michael Niedermayer
committed
//#define TRACE
#ifdef TRACE
static inline void print_bin(int bits, int n)
{
Michael Niedermayer
committed
int i;
av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1);
Michael Niedermayer
committed
}
av_log(NULL, AV_LOG_DEBUG, " ");
Michael Niedermayer
committed
}
Diego Biurrun
committed
static inline int get_bits_trace(GetBitContext *s, int n, const char *file,
const char *func, int line)
{
Michael Niedermayer
committed
print_bin(r, n);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n",
r, n, r, get_bits_count(s)-n, file, func, line);
Michael Niedermayer
committed
return r;
}
static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
Diego Biurrun
committed
int bits, int max_depth, const char *file,
const char *func, int line)
{
int show = show_bits(s, 24);
int pos = get_bits_count(s);
int r = get_vlc2(s, table, bits, max_depth);
int len = get_bits_count(s) - pos;
int bits2 = show >> (24-len);
Michael Niedermayer
committed
print_bin(bits2, len);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n",
bits2, len, r, pos, file, func, line);
Michael Niedermayer
committed
return r;
}
Diego Biurrun
committed
static inline int get_xbits_trace(GetBitContext *s, int n, const char *file,
const char *func, int line)
{
int show = show_bits(s, n);
int r = get_xbits(s, n);
Michael Niedermayer
committed
print_bin(show, n);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n",
show, n, r, get_bits_count(s)-n, file, func, line);
Michael Niedermayer
committed
return r;
}
#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
#define tprintf(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__)
Michael Niedermayer
committed
#else //TRACE
Michael Niedermayer
committed
#endif