H264中的CABAC及FFMPEG中的实现

一.  引擎的初始化

引擎初始化

标准定义

FFMPEG实现

codIRange = 0x01FE

codIOffset = read_bits( 9 )

 

codIRangecodIOffset都是16位精度

range= 0x1FE;

low = read_bits(16)<<10;

if(((uintptr_t)c->bytestream & 1) == 0) {

c->low += (1 << 9);//这里作2字节对齐仅仅是优化内存访问效率

}else {

c->low += ((*c->bytestream++) << 2) + 2;

//在后面的10bit中先放入8bit码字,再放入标志1和尾部的0

}

Low中一共使用了26bit,前面为码字,尾部为标志1和拖尾的0,根据拖尾的0的个数可计算出low中还有多少bit的码字(26 – 1 - 拖尾0个数)

codIRangecodIOffset都是9bit数,但ffmpeglow被放到了26bit的前面,所以range在参与low的运算(比较或加减时)需要放到同样的位置,即左移26-9=17= CABAC_BITS+1

 

Context初始化

标准定义

FFMPEG实现

preCtxState = Clip3( 1, 126, ( ( m ∗ Clip3( 0, 51, SliceQPY ) ) >> 4 ) + n )

if( preCtxState <= 63 ) {

     pStateIdx = 63 - preCtxState

     valMPS = 0

} else {

     pStateIdx = preCtxState - 64

     valMPS = 1

}

对每个上下文context,有两个变量pStateIdx 和valMPS,代表的意思分别是位于哪个状态以及MPS的值

const int8_t (*tab)[2];   tab指向2元数据[0]为m,[1]为m

for( i= 0; i < 1024; i++ ) {

    int pre = 2*(((tab[i][0] * slice_qp) >>4 ) + tab[i][1]) - 127;

    pre^= pre>>31;

    if(pre > 124)

          pre= 124 + (pre&1);//这两句代码的作用相当于clip3(1,126.x)

    sl->cabac_state[i] =  pre;

}

将pStateIdx和valMPS放在一个变量cabac_state里,变量的最低位表示valMPS,高位表示pStateIdx,所以pre在初始化时乘2

Pre*2后,值限制在[2-252],再-127后,限制在[-125,125],将^对负数取反后,成了[124..0,1..125]。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值