📄 bitstream.h
字号:
/*
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* 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
*/
/**
* @file bitstream.h
* bitstream api header.
*/
#ifndef BITSTREAM_H
#define BITSTREAM_H
#include "log.h"
#include "debug.h"
extern int g_code;
extern const uint8_t ff_reverse[256];
#define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
/* bit output */
/* buf and buf_end must be present and used by every alternative writer. */
typedef struct PutBitContext
{
uint32_t bit_buf;
int bit_left;
uint8_t *buf, *buf_ptr, *buf_end;
} PutBitContext;
static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
{
if(buffer_size < 0) {
buffer_size = 0;
buffer = NULL;
}
s->buf = buffer;
s->buf_end = s->buf + buffer_size;
s->buf_ptr = s->buf;
s->bit_left=32;
s->bit_buf=0;
}
/* bit input */
/* buffer, buffer_end and size_in_bits must be present and used by every reader */
typedef struct GetBitContext {
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
} 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;
#if defined(ARCH_MIPS)
#define UNALIGNED_STORES_ARE_BAD
#endif
#define unaligned16(x) *(__unaligned uint16_t*)x
#define unaligned32(x) *(__unaligned uint32_t*)x
#define unaligned64(x) *(__unaligned uint64_t*)x
static inline void put_bits(PutBitContext *s, int n, unsigned int value)
{
unsigned int bit_buf;
int bit_left;
assert(n == 32 || value < (1U << n));
bit_buf = s->bit_buf;
bit_left = s->bit_left;
/* XXX: optimize */
if (n < bit_left) {
bit_buf = (bit_buf<<n) | value;
bit_left-=n;
} else {
bit_buf<<=bit_left;
bit_buf |= value >> (n - bit_left);
#ifdef UNALIGNED_STORES_ARE_BAD
if (3 & (intptr_t) s->buf_ptr) {
s->buf_ptr[0] = bit_buf >> 24;
s->buf_ptr[1] = bit_buf >> 16;
s->buf_ptr[2] = bit_buf >> 8;
s->buf_ptr[3] = bit_buf ;
} else
#endif
*(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
s->buf_ptr+=4;
bit_left+=32 - n;
bit_buf = value;
}
s->bit_buf = bit_buf;
s->bit_left = bit_left;
}
/* Bitstream reader API docs:
name
abritary name which is used as prefix for the internal variables
gb
getbitcontext
OPEN_READER(name, gb)
loads gb into local variables
CLOSE_READER(name, gb)
stores local vars in gb
UPDATE_CACHE(name, gb)
refills the internal cache from the bitstream
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)
will return the next num bits
SHOW_SBITS(name, gb, num)
will return the next num bits and do sign extension
SKIP_BITS(name, gb, num)
will skip over the next num bits
note, this is equivalent to SKIP_CACHE; SKIP_COUNTER
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_CACHE(name, gb, num)
will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
LAST_SKIP_BITS(name, gb, num)
is equivalent to SKIP_LAST_CACHE; SKIP_COUNTER
for examples see get_bits, show_bits, skip_bits, get_vlc
*/
#define MIN_CACHE_BITS 25
#define OPEN_READER(name, gb)\
int name##_index= (gb)->index;\
int name##_cache= 0;\
#define CLOSE_READER(name, gb)\
(gb)->index= name##_index;\
#define UPDATE_CACHE(name, gb)\
{\
const uint8_t *p=((const uint8_t *)(gb)->buffer)+(name##_index>>3);\
name##_cache = (int)((((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3])) << (name##_index&0x07);\
}\
#define SKIP_CACHE(name, gb, num)\
name##_cache <<= (num);
// FIXME name?
#define SKIP_COUNTER(name, gb, num)\
name##_index += (num);\
#define SKIP_BITS(name, gb, num)\
{\
SKIP_CACHE(name, gb, num)\
SKIP_COUNTER(name, gb, num)\
}\
#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
#define LAST_SKIP_CACHE(name, gb, num) ;
#define SHOW_UBITS(name, gb, num)\
NEG_USR32(name##_cache, num)
#define SHOW_SBITS(name, gb, num)\
NEG_SSR32(name##_cache, num)
#define GET_CACHE(name, gb)\
((uint32_t)name##_cache)
/**
* reads 0-17 bits.
* Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
*/
static always_inline unsigned int get_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
tmp= SHOW_UBITS(re, s, n);
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
return tmp;
}
/**
* shows 0-17 bits.
* Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
*/
static inline unsigned int show_bits(GetBitContext *s, int n)
{
register int tmp;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
tmp= SHOW_UBITS(re, s, n);
// CLOSE_READER(re, s)
return tmp;
}
static always_inline void skip_bits(GetBitContext *s, int n)
{
//Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
LAST_SKIP_BITS(re, s, n)
CLOSE_READER(re, s)
}
static always_inline unsigned int get_bits1(GetBitContext *s)
{
int index= s->index;
uint8_t result= s->buffer[ index>>3 ];
result<<= (index&0x07);
result>>= 8 - 1;
index++;
s->index= index;
return result;
}
extern GetBitContext* s;
#define show_bits1(s) show_bits(s, 1)
#define skip_bits1(s) skip_bits(s, 1)
/**
* reads 0-32 bits.
*/
static inline unsigned int get_bits_long(GetBitContext *s, int n)
{
if(n<=17) return get_bits(s, n);
else
{
#ifdef ALT_BITSTREAM_READER_LE
int ret= get_bits(s, 16);
return ret | (get_bits(s, n-16) << 16);
#else
int ret= get_bits(s, 16) << (n-16);
return ret | get_bits(s, n-16);
#endif
}
}
/**
* init GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
* because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
*/
static inline void init_get_bits(GetBitContext *s,
const uint8_t *buffer, int bit_size)
{
int buffer_size= (bit_size+7)>>3;
if(buffer_size < 0 || bit_size < 0) {
buffer_size = bit_size = 0;
buffer = NULL;
}
s->buffer= buffer;
s->size_in_bits= bit_size;
s->buffer_end= buffer + buffer_size;
s->index=0;
}
static always_inline void align_get_bits(GetBitContext *s)
{
int n= (-s->index) & 7;
if(n) skip_bits(s, n);
}
int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
const void *bits, int bits_wrap, int bits_size,
const void *codes, int codes_wrap, int codes_size,
int flags);
#define INIT_VLC_USE_STATIC 1
#define INIT_VLC_LE 2
void free_vlc(VLC *vlc);
/**
*
* if the vlc code is invalid and max_depth=1 than no bits will be removed
* if the vlc code is invalid and max_depth>1 than the number of bits removed
* is undefined
*/
#define GET_VLC(code, name, gb, table, bits, max_depth)\
{\
int n, index, nb_bits;\
\
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)\
}
#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update)\
{\
int n, index, nb_bits;\
\
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)\
}
/**
* parses a vlc code, faster then get_vlc()
* @param bits is the number of bits which will be read at once, must be
* identical to nb_bits in init_vlc()
* @param max_depth is the number of times bits bits must be readed to completly
* read the longest vlc code
* = (max_vlc_length + bits - 1) / bits
*/
#define GET_VLC2(s, table, bits, max_depth)\
{\
OPEN_READER(re, s);\
UPDATE_CACHE(re, s);\
\
GET_VLC(g_code, re, s, table, bits, max_depth);\
\
CLOSE_READER(re, s);\
}
/*
STATIC_FUNC always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth)
{
int code;
OPEN_READER(re, s)
UPDATE_CACHE(re, s)
GET_VLC(code, re, s, table, bits, max_depth)
CLOSE_READER(re, s)
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;
}
#endif /* BITSTREAM_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -