首页 cabac原理及其实现笔记

cabac原理及其实现笔记

举报
开通vip

cabac原理及其实现笔记Context-Based Adaptive Binary Arithmetic Coding in the H.264/AVC 简称Cabac,H264中的一种熵编码方式:基于上下文的自适应二进制算术编码 内容安排:1,介绍算术编码 2,介绍二进制算术编码 3介绍Cabac及其一些实用的实现方式(参考JSVM代码,也可以参考JM) ---张新发 一,算术编码 算术编码是一种常用的变字长编码,它是利用信源概率分布特性、能够趋近熵极限的编码方法。它与 Huffman 一样,也是对出现概率大的符号赋予短码,对概率...

cabac原理及其实现笔记
Context-Based Adaptive Binary Arithmetic Coding in the H.264/AVC 简称Cabac,H264中的一种熵编码方式:基于上下文的自适应二进制算术编码 内容 财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容 安排:1,介绍算术编码 2,介绍二进制算术编码 3介绍Cabac及其一些实用的实现方式(参考JSVM代码,也可以参考JM) ---张新发 一,算术编码 算术编码是一种常用的变字长编码,它是利用信源概率分布特性、能够趋近熵极限的编码 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 。它与 Huffman 一样,也是对出现概率大的符号赋予短码,对概率小的符号赋予长码。但它的编码过程与 Huffman 编码却不相同,而且在信源概率分布比较均匀的情况下其编码效率高于 Huffman 编码。它和 Huffman 编码最大的区别在于它不是使用整数码。Huffman 码是用整数长度的码字来编码的最佳方法,而算法编码是一种并不局限于整数长度码字的最佳编码方法。算术编码是把各符号出现的概率表示在单位概率 [0,1] 区间之中,区间的宽度代表概率值的大小。符号出现的概率越大对应于区间愈宽,可用较短码字表示;符号出现概率越小对应于区间愈窄,需要较长码字表示。 举例如下: 以符号 为例 在算术编码中通常采用二进制分数表示概率,每个符号所对应的概率区间都是半开区间,即该区间包括左端点,而不包括右端点,如 S1对应 [0, 0.001),S2 对应 [0.001, 0.01) 等。 算术编码产生的码字实际上是一个二进制数值的指针,指向所编的符号对应的概率区间。 · 符号序列 …… 的第一个符号 S3 用指向第 3 个子区间的指针来代表,可以用这个区间内的任意一个小数来表示这个指针,这里约定这个区间的左端点代表这个指针,因此得到第一个码字.011。 · 后续的编码将在前面编码指向的子区间内进行,将 [.011, .111] 区间再按概率大小划分为 4 份,第二个符号 S3 指向 .1001 (S3 区间的左端),输出码字变为 .1001。 · 然后,S3 对应的子区间又被划分为 4 份,开始对第三个符号 S2 进行编码,……. · 两个参量:编码点(指针所指处)C 和区间宽度 A。 · 初始状态 编码点(指针所指处)C = 0 区间宽度 A = 1.0 · 新编码点 C = 原编码点 C + 原区间 A×Pi 新区间 A = 原区间 A×pi · 序列 S3S3S2S4 …… 的编码过程: · 第1个符号 (S3): C = 0 + 1×.011 = .011 A = 1×.1 = .1 · 第2个符号 (S3): C = .011 + .1×.011 = .1001 A = .1×.1 = .01 · 第3个符号 (S2): C = .1001 + .01×.001 = .10011 A = .01×.01 = .0001 · 第4个符号 (S4): C = .10011 + .0001×.111 = .1010011 (输出的码字) A = .0001×.001 = .0000001 解码过程 · 算法解码采取与编码过程相反的步骤 · 把接收到的码字串指向其对应的子区间,得到此子区间对应的符号,即为解码后的符号。 · 即从码字串中减去已解码符号的子区间的左端点的数值(累积概率), · 并将差值除以该子区间的宽度(概率值),得到新的码字串。 · 上述例子 · 当收到字码串 (.1010011) 时,其指向子区间 [.011, .111],对应于 S3,因此,得到第 1 个符号为 S3。 · 新码字串:(.1010011 - .011) ÷ (.1) = 0.100011 ,新码字串仍然指向子区间 [.011, .111],因此,第 2 个符号仍为 S3。 · 其它符号依次类推 二,二进制算术编码 二进制算术编码的输入的字符只有两种,如果信源字符集内包含有多个字符,则先将这些字符经过一系列的二进判决,变成二进制字符串。 这两个符号构成的序列的编码与算术编码基本原理相同,仍是不断划分概率子区间的递归过程。 在两个输入字符中,出现概率较大的为 MPS (More Probable Symbol),MPS 的概率为 Pe;出现概率较小的为 LPS (Less Probable Symbol),LPS 的概率为 Qe,Pe=1-Qe。 编码初始化子区间为 [0,1],MPS与 LPS 分配如图所示: 编码时,设置两个专用寄存器(C,A) C 寄存器的值为编码点(指针所指处),初时化为0 A 寄存器的值为子区间的宽度 (该宽度恰好是已输入符号串的概率),初时化为1 随着被编码数据源输入,C 和 A 的内容按以下编码规则修正: 当低概率符号 LPS 到来时: C=C , A=AQe 当高概率符号MPS到来时: C=C + AQe , A=Ape = A(1-Qe) 例: 信源符号序列 11011111 0 为 LPS Qe = 1/8 =(0.001)b 1 为 MPS Pe = 7/8 =(0.111)b 初始状态:C=0 (子区间起始位置) A=1 (子区间宽度) 1, 第1个符号1为 MPS C = C + AQe = 0 + 1 (0.001 = 0.001 A = APe = 1 (0.111 = 0.111 2, 第2个符号1仍为 MPS C=C+AQe = 0.001 + 0.111 (0.001=0.001111 A=APe= 0.111 (0.111 =0.110001 3, 第3个符号0为 LPS C=C=0.001111 A=A Qe = 0.110001 (0.001 =0.000110001 4, 继续下去……. 最后得 C= 0.010001111110111100000001 A= 0.000011001001000010111111 此时区间的尾为C+A=0.010101000111111111000000,编码区间[C, C+A) 编码输出可以是最后一个编码区间中的任意小数值,但为了取得最好的编码效率,选择的小数应有最短的比特长度。上面区间我们可取0.0101,即输出为0101 解码过程 按 Qe、Pe 分成两个子区间,判断被解码的码字落在哪个区间,并赋予对应符号。 设 c’ =(0.0101) b是被解码的值,初始值 A=1 Qe = 0.001 当 c’ 落在 0-QeA 之间,解码符号为 D=0,则C’ = C’, A = Qe A 当 c’ 落在 QeA-A 之间,解码符号为 D=1,则C’ = C’-Qe A ,A = A(1-Qe) 1, c’ = 0.0101落在 Qe A -A 之间,解码符号为 D = 1 c’ = c’-QeA = 0.0101 - 0.001 = 0.0011 , A = A(1-Qe)= 0.111 2, c’= 0.0011 落在 Qe A -A 之间,解码符号为 D=1 c’=c’-QeA= 0.0011 -0.000111=0.000101 ,A=A(1-Qe)= 0.111(0.111=0.110001 3,c’ = 0.000101 落在 0-QeA 之间,解码符号为 D = 0 c’ = c’ = 0.000101 A = AQe = 0.110001(0.001 = 0.000110001 三,CABAC原理及其实现 CABAC是H264的一种熵编码 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,相比如H264的另外一种熵编码方案CAVLC而言,在可接受的视频质量(30dB到38dB之间)内变化时,前者可节约平均9%到14%的码流。CABAC有以下几个特性: 1, 对多数符号使用了自适应概率模型。 2, 通过使用上下文关系,利用了符号相关性。 3, 限制为二进制算术编码(binary arithmetic coding),基于只用查表和移位方式的快速二进制算术编解码器。 4, 399 种预定义的上下文模型,分成了各种不同的模型组,例如模型 14-20 用于帧间宏块类型的编码,模型的选择基于前面编码的信息(上下文关系),每个上下文模型适应实验分布。 先大致介绍CABAC的实现过程,然后对一些技术做细节介绍 下面是CABAC的编码 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 图 按上图可知,对一个符号编码有如下过程: 1,转化成二进制(Binarization) CABAC使用二值算术编码,也就是说只对二进制的判决(0或者1)进行编码。非二进制符号(例如转换后的系数或者运动矢量)在编码前先要进行二进制转换。这一过程和变长编码(VLC)中将信息符号转化为变长编码一样,所不同的是,算术编码器在将信息送去传输之前还要进一步对这些二进制符号进行编码。 2, 选择基于内容的模型: “基于内容的模型”是二进制符号中一个或多个比特的概率模型。根据对先前已编码符号的统计,从可选模型中选择适当的概率模型。 3, 算术编码: 根据选择的概率模型对每个比特进行算数编码。 4, 更新模型 上图中的bypass coding是指对于一些特定语法元素的二进制比特符号,为了加快编码速度而不使用上下文模型的形式。 使用CABAC的熵编码方式在时间耗费方面大于CAVLC,为了达到一个折中,在实际编码中,并不是对所有的语法元素都使用CABAC编码方案,有许多表征视频序列本身固有参数特征的语法元素的熵编码还是使用CAVLC。下图是一些需要用CABAC编码的语法元素及对应的上下文模型索引。 下面来具体介绍编码过程 1,二进制化 为了降低算术编码的复杂度,提高编码速度,采用二进制算术编码,即进行熵编码的符号是一系列的二进制符号,这得首先需要把编码语法元素转化成二进制串,包括基本方案和串接方案。 Unary Binarization:对于x>=0的无符号整数值,由x个”1”和一个终结符合”0”组成。 Truncated Unary Binarization(TU):给定一个参数S,对于编码符号x,0<=x<=S有效,如果x>S,则取x=S,对于x=(1<>k)&0x01) break } } 前缀是由对应值为 的Unary Binarization方案产生的二进制串组成,后缀由 这个十进制值对应的二进制串组成。 Fixed-Length(FL)Binarization:给定一个参数S,对于编码语法元素x,必须满足0<=x9时,后缀是x=|mvd|-9的EG3的方案输出的二进制串,mvd的符号为正时用”1”表征,为负时用”0”表征,当0<|mvd|<9时,后缀仅由表征mvd符号的比特生成。3,对于变换系数绝对值的二进制化,前缀采用S=14的TU方式,后缀采用EG0方式,注意此时二进制化的语法元素coeff_abs_value_minus1=abs_level-1,对于abs_level=0的情况,我们用一个significance map将其处理了。这和二进制化mvd比较相似,但此时并没有处理符号,符号是后面要单独处理的。下面是一个例子 2, 上下文模型 假设对已编码符号有一个预定义的集T,即所谓的上下文模版,有一个上下文的相关集C={0,1,…,C-1}给出,这个上下文是通过操作在T上的一个模型函数F:T--->C所定义的。对每一个即将要编码的符号x,可以利用它的已经编码的相邻符号 的概率模型来估计一个条件概率p(x|F(z)),在CABAC中,符号是二进制形式,而且通过选择少数的上下文C使得算法变得更为简单。 CABAC中有四种上下文模型的设计方式: 第1种类型的模型必须根据它相邻的已编码的语法元素构成,一般是其左边和上边的对应语法元素来建立相应的概率模型,对当前语法元素进行模型预测。第2种模型仅局限于对宏块类型和子宏块类型的应用,其中第n比特的概率模型的选定要参考前面已编码n-1比特所采用的模型。第3种和第4种模型仅用于残余数据的编码,这两种模型都依赖编码块的类型,其中第3种模型依赖的不是已编码的系数,而是系数在扫描路径中的位置。第4种模型则要计算该比特所在系数之前已编码的系数数目。在CABAC中除了这些条件上下文模型之外,还有一些固定概率模型,它们对待编码的比特提供固定的概率预测,已编码比特的模型不加以应用。 每个概率模型都对应一个索引 ,每个概率模型由两个值决定:一个6比特的概率状态索引 ,以及一个1比特的MPS符号 。 从0到72的索引值与宏块类型,子宏块类型,空域和时域的预测模式,以及基于宏块和slice的控制信息的语法元素有关,在这种情况下的上下文索引值通过下式来计算 从73到398的模型索引通过下式来计算 其中 表示各种语法元素对应得模型索引的偏移量,也就是前文给出的那个索引表里的所定义的一些下限值,例如,对于mb_qp_delta而言,这个值就是60。在实际的程序设计时,我们可以不用考虑设计这个值,而是将不同类型的语法元素单独设计一套模型索引值,即此时这个偏移量对于不同的模型类型都为0。 取决于当前二进制符号的索引,这个值反映了上下文模型的概念,它由当前编码而进制字符的上下文模型的四种设计方式决定。 反映了模型类别,其取值规则如下: 在JSVM中,定义了下列一些模型类型m_cBLFlagCCModel;m_cBLSkipCCModel; m_cBLQRefCCModel;m_cBCbpCCModel;m_cMapCCModel;m_cLastCCModel;m_cRefCCModel;m_cSigCCModel;m_cOneCCModel;m_cAbsCCModel; m_cChromaPredCCModel;m_cMbTypeCCModel;m_cBlockTypeCCModel; m_cMvdCCModel; m_cRefPicCCModel;m_cBLPredFlagCCModel; m_cResPredFlagCCModel;m_cDeltaQpCCModel;m_cIntraPredCCModel; m_cCbpCCModel;m_cBCbpEnhanceCCModel;m_cCbpEnhanceCCModel; m_cTransSizeCCModel;每个模型类型里都定义一定数量的模型 对这些模型进行初始化,以Intra型的m_cDeltaQpCCModel 为例,根据索引表可知,这个模型类型有4个模型,其索引是从60到63,在设计的时候,因为我们单独设计了这个模型类型,因此其索引是从0到4,对应这四种模型我们定义一个数组static const Short INIT_DELTA_QP_I[1][1][4][2]= { //----- model 0 ----- { { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} }, } }; 根据这个数组来初始化这四个模型,注意这个数组里的{0,41}等数据对是根据一系列的训练序列得到的,它并不是我们前面提及的表征一个模型的数据对{ , },我们将这个数组里的数据对记为 ,初始化就是由 得到每个模型的初始的{ , },转化 原则 组织架构调整原则组织架构设计原则组织架构设置原则财政预算编制原则问卷调查设计原则 如下 这里还要注意的是 这个参数,它表征的是二进制符号的概率,在CABAC中,符号的概率由LPS的64个量化概率值 表征, ,这个值范围由下面这个式子得到 从上面的介绍我们可以看出,在预测当前符号的概率模型时,最主要的是根据前面介绍的四种上下文模型的设计方式来预测当前的概率模型,即主要是求出 这个值, 得到后,当前符号的模型索引确定,根据这个索引值,再已经初始化或已经更新了的模型系列中找到当前符号的预测概率模型,在这个模型里得到概率状态和MPS,即{ , }对,利用这两个值进行算数编码,这在后面介绍算术编码时再具体介绍。下面我们介绍不同的语法元素的 的求取方法,(注意:每个模型都是针对一个二进制化后的二进制符来说的,而不是针对语法元素本身的值,但有的语法元素的值直接可以用一个二进制符来表征)这里体现了上下文的思想: A. 宏块类型,预测模式,控制信息等语法元素 1) 宏块和子宏块类型 包含的语法元素有,mb_skip_flag,mb_type,sub_mb_type(仅讨论SP/P Slice) mb_skip_flag:相邻宏块编码特性被用来设计当前宏块的概率模型,对于一个给定的当前宏块C,设其左边宏块为A,上边宏块为B,则A和B的mb_skip_flag值被用来设计当前宏块mb_skip_flag对应的二进制字符的上下文模型,具体是用他们的值来求 ,如下所示 如果A或B不可得,则将不可得的那个宏块的mb_skip_flag设为0。 Mb_type和sub_mb_type:概率模型是固定的,与已编码的宏块或子宏块无关,即对于一定的mb_type或sub_mb_type,有确定的 值与它相对应。 2) 预测模式 Luma4x4的Intra预测模式:有两个句法元素,prev_intra4x4_pred_mode_flag和rem_intra4x4_pred_mode_flag,由前面的表可以看到,这两个语法元素对应的概率模型序号为68和69,即在程序设计时,可以把 分别设计为0和1。在JSVM中,由m_cIntraPredCCModel这个模型类型表征。 Chroma中的Intra预测模式:chroma_pred_flag,这个语法元素值经过TU方式的二进制化之后有3个字符,其中第一个二进制字符的概率模型由下式决定: 其中C表示当前色度块,A表示左边色度块,B表示上边色度块,ChPredInDCMode表示某个色度块的预测方式是否是DC Mode (用0表示),有上面的表达式可以看出,第一个二进制字符的概率模型有3种。在CABAC中,第一个二进制字符之后的两个二进制符采用固定的概率模型,故这种类型的概率模型共有4种,JSVM中用m_cChromaPredCCModel成员类来表征这种类型的概率模型,这个成员类里有一个长度为4的一维概率模型变量。 参考图象索引:ref_idx,也是对这个语法元素值所对应的第一个二进制字符进行概率模型预测,是用上下文思想,其后的字符采用固定的模型。 RefIdxZeroFlag表示某个分割块其参考帧索引是否为0。 MVd:对于某个分割,用mvd(X,cmp)来表示其mvd,cmp是mvd的横纵座标值,即{horizontal,vertical},则mvd对应的第一个二进制字符的概率模型由下式决定: 前面介绍过,mvd的二进制化是用的是S=9的UEG3的方式,在编码余下的二进制字符时,使用如下方案,前缀中剩下的8个字符使用另外的四个固定的模型,后缀中的字符使用bypass编码方式,即不使用概率模型。 3)控制信息:mb_qp_delta,end_of_slice_flag,mb_field_decoding_flag 第三个我很少用到,只介绍前两个 mb_qp_delta: 在二进制化这个语法元素值x(c)之前,将它的值作一个转化 x’(c)=2|x(c)|-((x(c)>0)?1:0) 然后再对x’(c)使用Unary方式的二进制化,二进制化后的第一个字符的模型由下式决定(x(P)!=0),P表示C的下一个解码宏块。剩下的二进制符使用两个固定的概率模型。 end_of_slice_flag:使用一个特定的非自适应概率模型。 B. 残差数据的编码 1)有以下一些特征: 1. 在一个给定的dct变换块中,1比特的coded_block_flag表示是否有非零系数出现,一个二进制值significance map表征非零系数的位置。 2. 非零系数以反扫描顺序编码。 3. 非零系数编码上下文模型的选择基于已编码的非零系数数目(注意编码顺序是反扫描顺序) 2)编码流程: 首先,一个1比特的参数coded_block_flag被传送。如果coded_block_flag为0,则这个块将不会传送任何其他信息,否则,一个标示非零系数位置的significance map将会被编码。最后,各个非零系数的绝对值及其符号被编码,注意这些符合以反扫描次序被传送。 下图是一个编码过程图 Coded Block Pattern:对于除了Intra16x16的nonskip模式的宏块,coded_block_pattern标示了6个8x8块,其中4个Luma块,2个Chroma块,这个参数的二进制化采用的方案是4-bit FL+TU(S=2)。标示这六个块中哪些块含有非零的变换系数。 Coded Block Flag:是一个1比特符号,标示一个变换块是否有非零系数。 Significance Map:对于扫描次序中的每个系数,一个1比特的符号significant_ coeff_flag被传送,如果significant_coeff_flag为1,另外一个1比特的符号last_significant_coeff_flag也被传送,这个符号标示是否当前sig系数是最后一个sig系数,下图是一个sig map 的一个例子 Level Information:sig 系数是用两个符号,coeff_abs_level_minus1和coeff_sign_flag,一个标示系数的绝对值,一个标示系数值的符号。注意,系数的编码顺序是反扫描顺序,这可以用来合理地去调整上下文模型,下面会讲到。 3)残差数据的上下文模型 如下图所示,将所有的block类型分为5大类型, Coded Block Pattern:将coded_block_pattern二进制化后有6个二进制字符,前4个代表Luma,后2个代表Chroma,前四个字符的概率模型由下式决定 其中bin_idx表示字符索引,后两个字符的概率模型的获取方式和前四个字符的概率模型获取方式一样。 Coded Block Flag:对于上表中的5种类型,每种类型都采用4种概率模型,获取方式如下式: A表示当前块左边的块,B表示当前块上边的块 这里有几个问题需要注意: 上面这个式子只适用上表中所标示的同类型的块,若相邻块不是同类型的块,例如当前块属于Intra16x16,而相邻块X是以Inter方式编码,那么这时候的coded_block_flag(X)取值0;如果当前块的相邻块不属于当前块的Slice(当然,这也包含相邻块不存在的情况),这时候coded_block_flag(X)取缺省值,这个缺省值有两种取法,当前块是Intra型时,这个缺省值取1,否则取0。由此可见,对于coded block flag总共有5x4=20种概率模型供选择。 Significance map:significant_coeff_flag和last_significant_coeff_flag总共有15种不同的概率模型供选择,他们的选择方式取决于当前系数的扫描位置,如下: Level Information:反的扫描顺序可以提供一个更为准确的概率估计,因为在这种反扫描路径的最后,很容易出现连续的trailing 1的情况。编码coeff_abs_level_minus1的时候,用到两种模型,一种是二进制化后的第一个字符用到的概率模型,另一种是编码UEG0的剩余前缀字符(1到13)用到的。 NumT1(i)表示已编码的trailing 1个数,NumLgt1(i)表示已编码完的绝对值大于1的系数个数,i表示当前系数的扫描位置,而编码次序是反扫描次序,这意味着这两个值随着i的减小而增大,则coeff_abs_level_minus1的第一个字符的概率模型由当前的NumT1决定,但如果NumT1的值大于3了,则编码剩余系数时所选取的 的值总是3。如果NumLgt1〉0,则后面系数选取 总为4。 对于bin_index>0的情况(1<=bin_index<=13),如果有NumLgt1〉0,则 为5+min(4,NumLgt1(i));下表给出了个例子: 注意上面这个表的编码顺序是从i=9到i=1的。 对于UEG0的后缀部分及非零系数的符号信息的编码都采用bypass coding。 C. 二进制编码 由上面所述可以得到当前字符的概率模型,也就是得到了当前模型中的LPS的索引 以及MPS字符,再结合上一次编码所提供的Interval的Range值R,下一步就是要对当前的字符进行二进制编码,这里的二进制编码和第二部分所讲的就大致相同了,过程如下: 随着一个即将编码字符的到来,原有的Interval将会被分割成两个subInterval,一个Interval的宽度为 ,这与LPS相关,另外一个是 ,这与MPS相关, 是与得到的概率模型中的LPS索引 对应的,根据当前的字符是MPS还是LPS划分出一个新的Interval,这就与第二部分所述的二进制算术编码完全一致了。为了简化计算以及减少乘法运算带来的复杂度,CABAC中做了如下处理: 将R的值限定在1<<8到1<<9(即256到512之间),初时化R为512,将R值量化成4个值。 由于 是与 对应的, 有64个值,这样上面的乘法就只有4x64个值,将这个乘法运算做成一个以R和 为索引的二维数组,由于R的值较大,而R索引实际只有四个,故对R做一个处理(R>>6)&3,这样上面的乘法运算结果就合成到一个TabRangeLPS[64][4]的数组中,就这样得到概率模型后,二进制编码可用下图流程来说明: writeSymbol( UInt uiSymbol, CabacContextModel& rcCCModel ); 传递一个即将编码的字符以及其对应的Model UInt uiLow = m_uiLow; UInt uiRange = m_uiRange; UInt uiLPS = g_aucLPSTable64x4[rcCCModel.getState()][(uiRange>>6) & 3]; //compute the Interval of LPS,that's Rlps AOT_DBG( 1 < uiSymbol ); rcCCModel.incrementCount(); uiRange -= uiLPS; if( uiSymbol != rcCCModel.getMps() ) //for the first time,the default MPS { uiLow += uiRange; uiRange = uiLPS; if( ! rcCCModel.getState() ) { rcCCModel.toggleMps(); } rcCCModel.setState( g_aucACNextStateLPS64[rcCCModel.getState()] ); } else { rcCCModel.setState( g_aucACNextStateMPS64[rcCCModel.getState()] ); } while( uiRange < QUARTER ) { if( uiLow >= HALF ) { RNOK( xWriteBitAndBitsToFollow( 1 ) ); uiLow -= HALF; } else if( uiLow < QUARTER ) { RNOK( xWriteBitAndBitsToFollow( 0 ) ); } else { m_uiBitsToFollow++; uiLow -= QUARTER; } uiLow <<= 1; uiRange <<= 1; } m_uiLow = uiLow; m_uiRange = uiRange; return Err::m_nOK; } 以上就是用C++实现的编码过程。 上面有个函数是setState( UChar ucState )即编完当前字符后对概率的更新过程。toggleMps()是重新设置MPS。 D. 概率模型的更新 上面是LPS的概率状态转移图,概率的状态转移遵循以下原则 为了减少乘法运算带来的复杂度,将概率转移转化为概率索引 的转移,又将 的转移用两个数组表示出来 const UChar g_aucACNextStateMPS64[64] = {1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,62,63}; const UChar g_aucACNextStateLPS64[64] = { 0, 0, 1, 2, 2, 4, 4, 5, 6, 7,8, 9, 9,11,11,12,13,13,15,15, 16,16,18,18,19,19,21,21,22,22,23,24,24,25,26,26,27,27,28,29, 29,30,30,30,31,32,32,33,33,33,34,34,35,35,35,36,36,36,37,37,37,38,38,63}; 由数组可看出,当前字符为MPL时,LPS的状态索引 只是简单地加1,但当前字符为LPS的时候, 的改变就复杂多了。 需要注意的是,当在 =62处,在这里LPS的概率到达最小,或者说MPS的最大概率到达,如果这时候即将编码的仍然是一个MPS,则概率索引值62将不会改变,除非有一个LPS出现,这时候按照LPS的状态转移规则进行转移,我们可以看到,这时候状态63实际上是没有用到的。当在 =0的时候,当前即将编码符号仍然是LPS,则状态索引不变,但模型的MPS值 将要改变,这就导致了随后的LPS与MPS定义的交换,这就是函数toggleMps()的作用。 _1230552613.unknown _1230554457.unknown _1230571565.unknown _1230572312.unknown _1230572352.unknown _1230573629.unknown _1230574905.unknown _1230572370.unknown _1230572320.unknown _1230571616.unknown _1230569490.unknown _1230571478.unknown _1230554878.unknown _1230554133.unknown _1230554225.unknown _1230553427.unknown _1230553498.unknown _1230474941.unknown _1230550404.unknown _1230550462.unknown _1230549649.unknown _1230549762.unknown _1230549531.unknown _1230470702.unknown _1230470917.unknown _1230462990.unknown
本文档为【cabac原理及其实现笔记】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_095674
暂无简介~
格式:doc
大小:748KB
软件:Word
页数:18
分类:
上传时间:2012-05-02
浏览量:28