CABAC流程

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算术编码

流程:

CABAC编码

首先要说明的是CABAC的生命期是SLICE,因此本篇所讲的也是一个SLICE里CABAC的流程,其次对于我们来说场模式几乎用不到,所以本文的编码流程只使用帧模式,因此实际上用到的表只有277个, 当然如果我写成460, 不是说里面所有表都用到的. 这里只是声明一下这个问题, 如果大家实际操作的时候发现模型表序号始终不过276那是很正常的. 本文参考了T264的代码, 应此一帧里只有一个SLICE. 而本文用的变量则采用标准里的变量.本文不会讲CABAC的原理, 想要了解原理请参

考FTP上的<>

片级:即以下步骤在片期间只做1次

1.初始化上下文模型

先根据SliceQP算出460个模型表里的pStateIdx和valMPS, 构成一张初始表,根据标准9.3.1.1里的公式, 同时可以参考T264_cabac_context_init函数. 这张表不要和模型表弄混,虽然都是399维的, 但我们宏块级编码过程中实际用的只是这张表, 而不是标准里的那张模型表Table 9-23, 9-23这张表是用来算由pStateIdx和valMPS构成的初始表的.

2.初始化概率的下限和区间

然后就是初始化CABAC的初值, 下界指针,区间范围,可参考T264_cabac_encode_init函数.

解:下界指针codILow为0,区间范围codIRange为(0x1FE)510

宏块级:以下则是每个宏块都要做一次的, 这一级中会处理很多的语法元素, 这里我只用前2个语法元素做为例子:

假设:

mb_skip_flag = 1

mb_type = 3

3.语法元素二值化

H.264 通过二进制化把多维算术编码转化为二进制算术编码,提高了运算速度。语法元

素二进制化就是把非二进制的符号映射成若干位的二进制串。CABAC 引入了二进制化预处理过程来减小要编码的语法元素符号集的大小, 对于给定的语法元素用一个惟一的二进制串代替。CABAC 二进制化方案由基本方案,串接方案(参考标准子条款9.3.2.3,9.3.2.6)以及特别的手工选择方案(参考标准子条款9.3.2.5)组成。基本方案有一元码、截断一元码、K 阶指数哥伦布码和定长码4 种;串接方案由基本方案串接而成;手工选择方案有5 种,专门针对mb_type 和sub_mb_type 这两种语法元素。对语法元素的二进制化方案参考标准表9‐25。经二进制化编码输出的是MPS 概率极高的比特流,这样可以达到极高的压缩效果。

4. CABAC编码处理流程

首先mb_skip_flag标志进行CABAC编码, 由于这个元素本身就是2值的,所以直接就可以进行上下文模型选择了:

1.求ctxIdx上下文模型索引值

1)由标准Table 9-11知道, P帧(这里要注意是slice_type==P, 不是mb_type)的这个元素用9-13号表, B帧用9-14号表.

解:

假设P帧

得到ctxIdxOffset=11

2)由于这个元素只有1个bit, 因此只要算第一个bit的ctxIdxInc 就可以了, 参考标准Table 9-30,根据9.3.3.1.1子条款可以知道这一位的ctxIdxInc可能是0, 1, 2中的一个, 变量condTermFlagN (N 为A 或 B)的值推导如下:

—如果mbAddrN不可用或宏块mbAddrN 的mb_skip_flag等于1,则condTermFlagN被置为0;

—否则condTermflagN置为1。

变量ctxIdxInc 为: ctxIdxInc = condTermFlagA + condTermFlagB. 解:

如果全是skip模式

得到ctxIdx=13

2. 规则算术编码过程

下来就是算术编码部分了, 简单提一下基本原理: 在CABAC中为了减少R LPS= R*p LPS这个区间变换公式的开销, 用128个有限状态(实际可用的为126)代替p LPS , 用rangeTab这张表代替了R LPS, 见标准Table 9-35. 可以参考T264中的T264_cabac_encode_decision函数, 看一下具体流程:

1)查表得pStateIdx和valMPS

▲获得当前bin的pStateIdx和valMPS(来自片级计算的那张初始表) 假设cabac_init_idc=0查表获得:m=21,n=0

假设SliceQP Y=26

preCtxState = Clip3( 1, 126, ( ( 21 * Clip3( 0, 51, 26 ) ) >> 4 ) + 0 )

preCtxState=34

if( preCtxState <= 63 ) {

pStateIdx = 63 - preCtxState

valMPS = 0

} else {

pStateIdx = preCtxState - 64

valMPS = 1

}

解:

pStateIdx=29,valMPS=0;

2)求得变换后的区间

▲根据标准9.3.3.2.1子条款, 求得qCodIRangeIdx用来索引表rangeTab, 即可以求得变换后的区间了.

解:

qCodIRangeIdx = (codIRange>>6)&3

qCodIRangeIdx = (510>>6)&3 = 2

.

查表9-35,codIRangeLPS =46

▲修正区间codIRange = codIRange – codIRangeLPS

解:

codIRange =510-46=464

3)更新下边界,区间,概率状态索引值

▲判断当前的bin是否为最有可能的值, 如果不是(binVal!= valMPS),则更新区间下边界codILow = codILow + codIRange, 同时修正区间codIRange = codIRangeLPS;然后判断当前状态, 如果已经达到状态0, 是则把valMPS的值取反(即0,1互换), 如果还有没达到0, 则进行LPS 的状态迁移,具体参看标准Table 9-36的状态迁移表中的transIdxLPS

相关文档
最新文档