H.264/AVC视频编解码技术详解二十二熵编码:语法元素的CABAC解析
Posted 取次花丛懒回顾
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H.264/AVC视频编解码技术详解二十二熵编码:语法元素的CABAC解析相关的知识,希望对你有一定的参考价值。
《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看!
“纸上得来终觉浅,绝知此事要躬行”,只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会!
链接地址:H.264/AVC视频编解码技术详解
GitHub代码地址:点击这里
在本系列的博文18中,我们讨论了算术编码的基本原理,以及实现一个简单的算术编码器内核的方法:
而在博文19和21中我们根据H.264对于CABAC的规定,讨论了语法元素二值化以及上下文概率模型的相关算法:
通过前面的研究我们已经了解,由于视频数据特殊的统计特性和对编码性能的高指标要求,CABAC的算法远远比博文18中描述的基本模型更加复杂。尽管如此,CABAC在算术编码的最核心层面依然遵循了博文18中所讲的根本原理,这一点在本文对标准协议文档的解读中也可以获得明确的证实。
一、CABAC解析(解码)的总流程
CABAC的解码过程定义与标准协议文档的9.3.3.2节。CABAC解码过程所需要的输入数据包括前一章所推导出的上下文模型索引ctxIdx、旁路模式标志bypassFlag,以及解码器引擎的状态。下图表示了CABAC解码过程的概念框图:
在上图中可以看出,根据参数的不同,CABAC解码总共可能有三种运行流程:
- DecodeBypass: 当旁路模式标志bypassFlag为1时执行,表示旁路模式的解析过程;
- DecodeDecision: 当bypassFlag为0且ctxIdx不为276时执行,表示CABAC解析过程;
- DecodeTerminate: 当bypassFlag为0且ctxIdx==276时执行,表示解析终结码的过程;
在这三种执行流程中最重要的就是第二种——DecodeDecision。接下来本文将从DecodeDecision开始分析这三种解析过程。
二、CABAC算术编码的解码(解析)过程
本节描述的即是DecodeDecision部分的方法。这一部分也是CABAC算法中最为重要的部分,H.264的main、high profile中的多数语法元素都是通过该过程进行解析的。该部分在标准协议文档的9.3.3.2.1中定义。
从标准协议中的该节内容中可知,该过程所需要的数据有ctxIdx, codIRange 和 codIOffset,其中ctxIdx由前一章《CABAC的上下文概率模型》中的方法推导,codIRange 和 codIOffset的初始值由CABAC解码器引擎的初始化确定。输出的数据包括解析出来的语法元素比特位值binVal,以及更新过的codIRange 和 codIOffset。
该过程的整体流程如下图所示:
2.1 计算 codIRangeLPS
计算 codIRangeLPS 的过程遵循以下流程:
- 根据当前的codIRange值,计算qCodIRangeIdx的值:
- qCodIRangeIdx =( codIRange >> 6 ) & 3
- 通过 qCodIRangeIdx 和 pStateIdx,计算 codIRangeLPS 的值:
- 通过查表获取:codIRangeLPS = rangeTabLPS[ pStateIdx ][ qCodIRangeIdx ]
- rangeTabLPS为预定义的表,在表9-44中指定;
2.2 更新 codIRange
更新 codIRange 的方法为:
codIRange = codIRange - codIRangeLPS;
更新完成后,判断 codIOffset,如果 codIOffset >= codIRange,输出比特位值binVal赋值为1 - valMPS,并且codIOffset自减去codIRange的值,然后codIRange的值赋值为codIRangeLPS;否则,输出比特位值binVal赋值为valMPS。
2.3 状态转移过程
在CABAC编码或解码语法元素的某一个bit,编码/解码器将随之更新编解码器的状态。状态转移过程定义于标准的9.3.3.2.1.1节。该过程根据当前的上下文模型索引和解码的比特值,来更新上下文模型索引以及LPS/MPS的定义。
状态转移过程可以下式表示:
if( binVal = = valMPS )
pStateIdx = transIdxMPS( pStateIdx )
else
if( pStateIdx = = 0 )
valMPS = 1 − valMPS
pStateIdx = transIdxLPS( pStateIdx )
在编码过程中上下文模型索引的更新同样以查表的形式实现,该表格在9-45中规定。
2.4 归一化过程
在第18篇博文“算术编码的基本原理中”已经讨论过算术编码器的归一化。在H.264实际定义的CABAC算法中,归一化同样也是必备过程。CABAC的归一化过程定义于9.3.3.2.2节,流程图以下图表示:
进行归一化的本质含义是更新codIRange和codIOffset的值,所需要的数据包括当前CABAC的codIRange和codIOffset以及当前的二进制比特流数据。主要步骤为:
- 判断如果codIRange不小于256,那么不需要进行归一化;
- 如果codIRange小于256,则进行归一化过程,方法为:
- codIRange和codIOffset分别自乘以2;
- 在码流中读取 1 bit,并与codIOffset按位取或运算并更新到codIOffset;
三、CABAC的bypass解析方法
本节描述的是CABAC的DecodeBypass方法,即旁路解析模式,在bypass值设为1时执行。DecodeBypass相比DecodeDecision方法的特点是编码效率较低但运算远比DecodeDecision简单。与DecodeDecision过程相比,DecodeBypass不需要ctxIdx,只需要codIRange和codIOffset两个值。
DecodeBypass过程的流程图如下:
解析过程为:
- 首先codIOffset自增一倍,并且从码流中读取1 bit与之求按位或操作;
- codIOffset与codIRange对比:
- 若codIOffset小于codIRange,输出二进制位0;
- 否则,输出二进制位1,且codIOffset自减去codIRange的值;
四、CABAC的终止符解析
CABAC的终止符解析即DecodeTerminate过程,主要用于解析end_of_slice和ctxIdx值为276的元素。解析的方法类似于DecodeBypass过程,流程如下:
- 首先codIOffset自减2;
- codIOffset与codIRange对比:
- 若codIOffset小于codIRange,输出二进制位0,并执行解码器的归一化过程;
- 否则,输出二进制位1;
以上是关于H.264/AVC视频编解码技术详解二十二熵编码:语法元素的CABAC解析的主要内容,如果未能解决你的问题,请参考以下文章
H.264/AVC视频编解码技术详解二十四帧间预测编码:解码显示顺序与图像管理
H.264/AVC视频编解码技术详解二十四帧间预测编码:解码显示顺序与图像管理
H.264/AVC视频编解码技术详解二十五帧间预测编码:参考帧列表
H.264/AVC视频编解码技术详解二十五帧间预测编码:参考帧列表