-
2004-12-23
读取码流的函数
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://ffmpeg.blogbus.com/logs/553112.html
讨论讨论位流(stream)的读取,其实很简单
先看Bitstream的结构
typedef struct
{
uint32_t curr;//位流访问中的当前字(32bits为一个字)
uint32_t next;//要访问的下一个字,供跨字访问时使用
uint32_t buf;//读bitstream的话,这个可不要
uint32_t pos;//比特位置,在curr中读到哪一个位了
uint32_t *tail; //位流缓冲区所指向的当前指针,读到哪一个字节
uint32_t *start;//位流缓冲区的头
uint32_t length;//缓冲区总的长度
}Bitstream;//初始化位流结构
static void __inline
BitstreamInit(Bitstream * const bs,
void *const bitstream,
uint32_t length)
{
uint32_t tmp;bs->start = bs->tail = (uint32_t *) bitstream;
tmp = *(uint32_t *) bitstream;
#ifndef ARCH_IS_BIG_ENDIAN
BSWAP(tmp); //因为bitstream是bigendian的,所以在编译小尾程序时,需要swap一下
#endif
bs->curr = tmp;tmp = *((uint32_t *) bitstream + 1);
#ifndef ARCH_IS_BIG_ENDIAN
BSWAP(tmp);
#endif
bs->next = tmp;bs->buf = 0;
bs->pos = 0; //因为还没开始读比特流,所以位置为0
bs->length = length;
}//取得将要读到的比特位数的指,不更改比特位置
static uint32_t __inline
BitstreamShowBits(Bitstream * const bs,
const uint32_t bits)
{
//分析将要读出的比特位数,是否跨过一个字(32位)边界
int nbit = (bits + bs->pos) - 32;if (nbit > 0) {//越界,则由curr和next的两部分拼出要读取的值
return ((bs->curr & (0xffffffff >> bs->pos)) << nbit) | (bs->next >> (32 -nbit));
} else {//没有越界,通过移位curr就能得到要取的值
return (bs->curr & (0xffffffff >> bs->pos)) >> (32 - bs->pos - bits);
}
}//移动比特位位置,分越界和不越界两种情况
static void __inline
BitstreamSkip(Bitstream * const bs,
const uint32_t bits)
{
bs->pos += bits;if (bs->pos >= 32) {
uint32_t tmp;
//如果越界了,自动修改curr和next
bs->curr = bs->next;
tmp = *((uint32_t *) bs->tail + 2);
#ifndef ARCH_IS_BIG_ENDIAN
BSWAP(tmp);
#endif
bs->next = tmp;
bs->tail++;
bs->pos -= 32;
}
}/* read n bits from bitstream */
//将读值和修改位置,同时做
static uint32_t __inline
BitstreamGetBits(Bitstream * const bs,
const uint32_t n)
{
uint32_t ret = BitstreamShowBits(bs, n);BitstreamSkip(bs, n);
return ret;
}结束,呵呵。很简单。
随机文章:
xvid 代码的几个小bug 2005-01-08rmp4包简单介绍 2004-12-28YUV2RGB565(16位色) 2004-12-03oh my god,我改,改,改 2004-11-27又想起来一点 2004-10-11
收藏到:Del.icio.us








评论