毕业设计论文-CABAC

更新时间:2023-10-29 16:33:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

本科毕业设计(论文)

基于CABAC的可伸缩视频编码方法研究

学 院 电子与信息学院 专 业 信息工程 学生姓名 陈易光 指导教师 吴宗泽 提交日期 2008年 6 月 11日

华 南 理 工 大 学

毕 业 设 计 (论文) 任 务 书

兹发给 04级信息工程3 班学生 陈易光 毕业设计(论文)任务书,内容如下:

1.毕业设计(论文)题目:基于CABAC的可伸缩视频编码方法研究 2.应完成的项目: (1)以H.264为主,研究各种可伸缩视频编码技术。 (2)研究CABAC编码协议以及JM8.6源程序的相关部分,将源程序的流程与 编码过程对应起来。 (3)深入研究并理清CABAC对图像的各种句法元素的编码过程。 (4)分析比较国内外对CABAC的优化技术,了解各种技术的使用场合及其优 化程度。

3.参考资料以及说明: (1)毕厚杰,新一代视频压缩编码标准——H.264/AVC[M] (2)朱江,H.264/AVC中扩展空域可伸缩编码的研究 (3)闵玲,CABAC在H.264/AVC中的应用 (4)徐苏姗,算术熵编码CABAC (5)黄菠,H.264中的CABAC熵编码研究 (6)朱莹,H.264标准的新扩展——可伸缩性编码及应用 (7)ITU-T,H.264建议书

4.本毕业设计(论文)任务书于 年 月 日发出,应于 年 月 日前完成,然后提交毕业考试委员会进行答辩。

专业教研组(系)、研究所负责人 审核 年 月 日

指导教师 签发 年 月 日

毕业设计(论文)评语:

毕业设计(论文)总评成绩:

毕业设计(论文)答辩负责人签字:

月 日

电信学院学士学位论文

摘要

数字视频技术在通信和广播领域得到了日益广泛的应用,随着互联网和移动通信的迅猛发展,视频信息和多媒体信息在互联网和移动网络中的处理和传输技术成为国内外专家研究的热点之一。当前国际上对于视频编码技术的研究热点逐渐集中于在H.264/AVC基础上实现可伸缩视频编码。因此,本文主要对H.264中的基于上下文自适应的二进制算术编码(CABAC)进行研究。

首先,本文结合标准详细描述了CABAC的三个主要步骤:二值化,上下文建模与基于表格的二进制算术编码。二值化是把非二进制句法元素唯一映射到一个二进制码字。上下文建模是利用已编码的符号为句法元素选择合适的上下文模型并自动更新概率模型。最后的基于表格的二进制算术编码则利用查表的方式进行算术编码,有效地避免了乘法运算。

然后,本文详细介绍H.264的官方测试源码JM8.6中涉及到CABAC的部分。其中包括编码片的slice.c部分函数的分析,编码块的macroblock.c与rdopt.c部分函数的分析,编码各句法元素的cabac.c部分函数的分析以及进行二进制算术编码的biariencode.c部分函数的分析。

最后,本文基于JM8.6对CABAC进行了性能测试与分析,并与CAVLC相比较。实验表明,CABAC有着更好的编码效果。

关键词:可伸缩视频编码,H.264,CABAC

I

电信学院学士学位论文

Abstract

Digital video technology has been widely applied in communications and broadcasting fields. As the Internet and the mobile communications developing rapidly, the domestic and foreign experts focus on the processing and transmission technology of video information as well as multimedia information on the Internet and in the mobile networks. Currently scalable video coding based on H.264/AVC has fradually become the research focus of international video coding technology. Now, this paper will mainly study on the Context-bsaed Adaptive Binary Arithmetic Coding (CABAC).

Firstly, the three major steps of CABAC were described detaily according to the standard: binarization, context modeling, and context-based binary arithmetic coding. Binarization is used to map the non-binary syntax elements into a binary code. Context codeling chooses the suitable context model for syntax elements using the coded symbols, and updates the possibility models automatically. And the context-based binary arithmetic coding avoid the multiplication effectively when coding with the look-up table.

Secondly, the paper will specify the CABAC part in the JM8.6, the official source testing code of H.264, including the analysis of part of the functions in following C files: slice.c, macroblock.c, rdopt.c, cabac.c, and biariencode.c.

Finally, compared to the CAVLC, it was proposed that the performance test and analysis of CABAC based on JM8.6. The experiment data showed that the CABAC had superior performance.

Keyword: Scalable video code, H.264, CABAC

II

电信学院学士学位论文

第二章 H.264标准中的CABAC

2.1概述

H.264又名“MPEG-4 AVC(Advanced Video Coding)”,是国际电信联盟电信标准化部门(International Telecommunications Union-Telecommunication Standardization Sector,ITU-T)与国际标准化组织(International Organization for Standardization,ISO)联合开发组共同开发的最新国际视频编码标准,于2003年5月发布了第一个版本。在该标准中采用了一系列先进的编码技术,在编码效率、网络适应性等诸多方面都超越了以往的视频编码标准。其中,为了改进以往标准中熵编码(Entropy Coding)存在的编码效率低、重建效果差以及存在一些不可避免的帧间符号冗余等不足,H.264中规定了两种熵编码的模式,即基于上下文的自适应二进制算术编码 (Context-bsaed Adaptive Binary Arithmetic Coding,CABAC)和基于上下文自适应可变长编码 (Context-bsaed Adaptive Variable-Length Coding,CAVLC )。

熵编码直接对变换编码后的系数进行编码。视频信号间有很强的非静态统计依赖性,这些统计特性很大程度上依赖于视频内容和图像获取方式。传统的编码思想是将视频信号的比特流映射成一个个不同码字长的语法元素,这种变长编码仅仅利用了这些非静态统计特性中的一部分进行压缩,而在以往的视频编码方案中,存在于语法元素数值之间的高阶统计依赖性则基本被忽略了。

CABAC是H.264/AVC标准中两种熵编码方法中的一种,是将自适应的二进制算术编码与一个设计精良的上下文模型结合起来得到的方法。它很好地利用了语法元素数值之间的高阶信息,使得熵编码的效率得到了进一步提高。它的主要特点有:利用每个语法元素的上下文关系,根据已编码元素为待编码元素选择概率模型,即上下文建模;根据当前的统计特性自适应地进行概率估计;使用算术编码。[5]

图2.1展示了在CABAC中编码一个单独的句法元素的通用方框图。这个编码过程主要由三个基本步骤组成:

1、二值化; 2、上下文建模;

3、基于表格的二进制算术编码。

在第一步,一个给出的非二进制值的句法元素唯一地对应到一个二进制序列,叫二进制串。当给出一个二进制值的句法元素时,这一初始步骤将被跳过,如图1所示。对于每个元素的二进制串或每个二进制值的句法元素,后面会根据编码模式有一两个子步骤。

接下来就是对二元数据进行编码,标准中有两种编码模式可供选择。在常规编码模式(regular coding mode)中,一个句法元素的每一个二进值(bin)按其判决产生的顺序进入

4

电信学院学士学位论文

上下文模型器,在这里,模型器根据已经编码过的句法元素或二进值为每一个输入的二进值分配一个概率模型,这就是上下文模型化。然后该二进值和分配给它的概率模型一起被送进常规算术编码器进行编码,此外编码器还要根据该二元位的值反馈一个信息给上下文模型器,用以更新上下文模型,这就是编码中的自适应;另一种模式是旁路编码模式(bypass coding mode),在该模式中,没有模型器为每个二进值分配一个特定的概率模型,输入的二元数据是直接用一个简单的旁路编码器进行编码的,这样做是为了加快整个编码(以及另一端解码)的速度,当然,该模式只用于某些特殊的二进值。

后面将更加详细地讨论二值化,上下文建模与基于表格的二进制算术编码这三个主要步骤以及它们之间的相互联系。

图2.1 CABAC编码器方框图

2.2二值化

CABAC的二值化方案有四种基本类型:一元码,截断一元码,k阶指数哥伦布编码,与定长编码。此外,还有基于这些基本类型的联合的二值化方案与基于查表的二值化方案。

2.2.1 一元码(Unary)

对于一个非二进制的无符号整数值符号x≥0,在CABAC中的一元码码字由x个“1”位外加一个结尾的“0”位组成。例如,输入的句法元素值为4,其二值化结果为11110。

2.2.2 截断一元码(Truncated Unary, TU)

已知截断值S。对于一个非二进制的无符号整数值符号0≤x

5

电信学院学士学位论文

2.2.3 k阶指数哥伦布编码(kth order Exp-Golomb, EGk)

指数哥伦布编码是由一个前缀和一个后缀的码字连接组成的。EGk码字的前缀部分由l(x)=[log2x(x/2k+1)]的值所对应的一元码组成。EGk码字的后缀部分可以通过使用长度为k+l(x)位的x+2k(1-2l(x))的二进值来计算。另外,EGk码字也可以通过下面的伪C代码推得。

while(1) {

if (x>=(1<

put(0);//前缀的截止位“0”

while(k--) put((x>>k)&0x01); //EGk的后缀 } break; }

2.2.4 定长编码(Fixed-Length, FL)

对用到定长编码二进化的句法元素值假设了一个有限的字母表 [0,1,2,?,Cmax],编码的二进制长度为L?log2??Cmax???1 。其中,二进制1对应其中重要性最低的符号,随着重要性的增加,二进制数也会跟着增加。

2.2.5 4位FL与截断值为2的TU联合二值化方案

前缀使用长度为4位(Cmax=15)的定长编码,后缀使用截断值S=2的一元截断码。

2.2.6 TU与EGk的联合二值化方案(Unary/kth order Exp-Golomb, UEGk)

前缀使用一元截断码,后缀使用k阶哥伦布编码。对于不同的句法元素值,有不同的截断值与阶数。

2.2.7 各种句法元素值的二值化

宏块跳过标记mb_skip_flag、4*4亮度块的帧内预测模式标记prev_intra4x4_pred_mode_ flag、8*8亮度块的帧内预测模式标记prev_intra8x8_pred_mode_ flag、当前宏块的帧/场模式标记mb_field_decoding_flag、已编码块标记coded_block_flag、重要系数标记significant_ coeff_flag、最后一个重要系数标记last_significant_coeff_flag、系数符号位标记coeff_sign_ flag、片结束标记end_of_slice_flag、8*8转换系数块标记transform_size_8x8_flag均使用1位的定长编码。

运动矢量差的绝对值使用截断值为9的UEG3二值化。

6

电信学院学士学位论文

色度帧内预测模式intra_chroma_pred_mode使用截断值为3的TU二值化。 转换系数的绝对值减一coeff_abs_level_minus1使用截断值为14的UEG0二值化。 块编码模式coded_block_pattern使用4位FL与截断值为2的TU联合二值化方案。该句法元素指定了6个块,其中4个用于亮度,2个用于色度,表示其中是否含有非零系数。coded_block_pattern=coded_block_patternY+16*nc,首先,亮度部分的coded_block_patternY使用的是4位FL转换,而色度部分nc用的是截止值为2的TU二进制变换。

宏块类型mb_type与子宏块类型sub_mb_type的二值化通过查表获得,详情参见标准。 各句法元素的二值化方案可以参见标准中的表9-25。

2.2.8 联合二值化方案编码实例

输入的句法元素值为幅度的绝对值abs_level=20。则coeff_abs_level_minus1=19,对此使用截断值S=14,阶数k=0的UEG0二值化方案。

先编码前缀部分,按照编码规则易得二进制序列为11 1111 1111 1111(14个1)。 再编码后缀部分,下面分别按照伪C代码与编码规则进行编码: 1、按照伪C代码进行编码 x = 19 – S = 5。

进行第一次循环:5>1(即1<<0),因此put(1), x=5-1=4, k+1=1; 进行第二次循环:4>2(即1<<1),因此put(1), x=4-2=2, k+1=2; 进行第三次循环:2<4(即1<<2),因此put(0); 至此得到EG0的前缀一元码与截断位0。

进行第一次循环:k-1=1,因为(x>>k)&0x01=(2>>1)&0x01=1,所以put(1); 进行第二次循环:k-1=0,因为(x>>k)&0x01=(2>>0)&0x01=0,所以put(0); 至此得到EG0的后缀序列10。 2、按照编码规则进行编码

由x=5得l(x)=[log2x(x/2k+1)]=2,对应的一元码110即为EG0前缀。

又因为x+2k(1-2l(x))=5-3=2=(10)2,其中后缀码字长度为k+l(x)=2,则EG0后缀为10。 可见,两种方法得到的联合二值化后缀码字相同,均为11010,则最终输出的二进制序列为11 1111 1111 1111 11010。

2.3上下文建模

CABAC将片(Slice)作为算术编码的生命期。但对具体句法元素的编码却是发生在宏块级。实际上,在同一个宏块中,不同的句法元素是独立编码。但在不同的宏块中,相邻宏块的句法元素的上下文信息(包括概率状态state与最大概率符号MPS的值)可用于编

7

电信学院学士学位论文

码当前宏块的同一句法元素。

2.3.1 上下文的初始化

在开始编码一个新的片时,都会对每个上下文模型指定相应的一对变量(m, n),并根据m, n的值计算出每个上下文模型对应的初始概率状态state与最大概率符号MPS的值。该初始化的过程有以下三个步骤:

1、计算 pre_state=((m*(QP-12))>>4)+n;

2、对于P和B帧图像限制pre_state在[0,101]内,对于I帧图像,限制pre_state在[27,74]内,即pre_state= min(101, max(0, pre_state))(对P 和B帧),pre_state=min (74,max(27, pre_state))(对I帧);

3、将pre_state按以下规则映射到数组{state, MPS}:如果pre_state<=50,{state=50- pre_state, MPS=0},否则{state= pre_state-51, MPS=1}

对于不同上下文模型的(m, n)分配参看标准。

2.3.2 上下文模型的分类

上下文模型大概可以分成4种。

第一种上下文模型包含当前要编码的句法元素的两个相邻块的已编码句法元素的信息,其中相邻块的具体位置就要看句法元素了,一般是根据左边与上边的相邻块。

第二种上下文模型只对mb_type与sub_mb_type的句法元素有定义。对于这种上下文模型,之前已编码的二进串的值(b0, b1, b2,…, bi-1)是用来为一个索引为i的二进制句法元素值选择模型的。

第三与第四种上下文模型都是只应用在残差数据上。与其它上下文模型不同,这两种类型都是依赖于不同块种类的上下文范围,如下文所示。其中,第三种类型并不依赖于已编码数据,而是待编码数据在扫描路径上的位置。对于第四种类型,首先在前面已编码(已解码)的变换系数幅度中,统计出具有某个特定值的变换系数幅度出现的总次数,然后根据这个数值来为当前变换系数中的二进值确定上下文模型。

除了这些基于条件概率的上下文模型,还有固定的概率模型映射到为那些已在常规模式被编码的所有二进串的,以及先前没有指定范围的的上下文模型可以用到的二进值索引。

2.3.3 上下文模型的分配与确定

通常,每个句法元素的上下文模型根据上下文索引偏移量与上下文增量来确定。其中,上下文索引偏移量对于特定类型片中的特定句法元素是唯一确定的,可以在标准中通过查表获得。而上下文增量,则是根据相邻块的编码情况(也就是上下文信息)得出。

对于不同的句法元素,所需相邻块的信息不同,但一般包括可用性(如当前块在片的边缘上,则相邻快可能由于不是在同一片中而不可用)与同一句法元素的编码值。

8

电信学院学士学位论文

通常用于计算上下文增量的上下文建模函数为ctx_var_spat=cond_term(A,B),A和B表示当前块的相邻块。其中cond_term()表示的是一种函数关系,有以下3种具体情况:

ctx_var_spat1=cond_term(A) + cond_term(B); ctx_var_spat2=cond_term(A) + 2*cond_term(B); ctx_var_spat3=cond_term(A)

另外,对于利用先前bin值(已编码值)的上下文建模函数为ctx_var_bin[k] = cond_term (b1, …, bk-1)

各句法元素的上下文增量的具体推导过程参见标准。

2.4二进制算术编码

算术编码是基于区间划分的,CABAC的算术编码有以下3个明显性质:

1、概率估计是对小概率符号LPS(Plps<0.5)的概率而言的,是通过基于表格中64个不同概率状态{Pk|0≤k<64}之间的相互转换而实现的。

2、区间长度R通过一组预先量化的值{Q1,Q2,Q3,Q4}进行量化以计算新的间隔区间。通过储存一个二维表格TabRangeLPS来决定LPS的新的子间隔范围Rlps,表格包含所有64*4预计算值Qi * Pk,通过快速查表这样就可以免除算术编码中的乘法运算了。

3、对近似均匀分布(Plps=0.5)的句法元素,在编码和译码时选择旁路方式,可以免除上下文建模,提高编码速度。

2.4.1 概率估计

在H.264/AVC中的免除乘法的二进制编码基本思想依赖于一个假设:每一个上下文模型估计的概率可以用一个有效的有限的特征值集合来表征。对于CABAC,对LPS有64个特征概率值p??[0.01875,0.5]。

p????p??1forall??1......630.5)1/63

??(0.01875andp0?0.5

伸缩因子??0.95,N=64

一方面想要获得快速的自适应??0;N要小;另一方面,如果想获得更加稳定更加精确的估计,则??1;需要更大的N。注意在MQ编码中,在CABAC方法中,不需要对LPS的概率值{p?|0???63}进行表格化。在算术编码中,每一个概率p?仅仅用其相关的索引? 作为地址。

这样设计的结果导致,CABAC中的每一个上下文模型可以有两个参数完全决定:LPS概率当前估计值(0???63)和MPS的值?(0或者1)。这样,在CABAC的概率估计

9

电信学院学士学位论文

中有128个不同的状态,每一个状态用一个7位整型数来表达。实际上,有一个状态的索引(??63)对应着LPS的最小概率值,但它并没有被纳入CABAC的概率估计和更新的范围,这个值被用作特殊的场合,传达特殊的信息。比如,当解码器检测到当前区间的划分依据是这个概率值时,认为这表示当前流的结束。因此只有126个有效概率状态。另外,有一个状态的索引(??62)对应LPS的最小概率值,它对应的更新值是它自身,当MPS连续出现,LPS的概率持续减小,直到??62,保持不变。[7]

概率估计指的是上下文的更新,因此只发生在编码不同块中同一句法元素或者其它上下文发生改变的时候,它是通过在LPS的64个概率状态之间互相转移而实现的。

对于一个给定概率状态,概率的更新取决于状态索引和已经编码的符号值(MPS or LPS)。更新过程导致一个新的概率状态,潜在的LPS概率修正,如果有必要需要修改MPS的值。如果当state=0时,也就是LPS的概率已经达到了最大值0.5,输入的是一个小概率符号LPS,那么MPS和LPS就要互换,因为state=0时,Plps=0.5。

在I片中,有:

if(decision==MPS)

state<-next_state_MPS_intra(state) else state<-next_state_LPS(state) 在其他片中,有:

if(decision==MPS)

state<-next_state_MPS (state) else state<-next_state_LPS(state)

2.4.2 算术编码器的总体描述

CABAC编码器由两个子编码器组成,一个用于常规编码模式,另一个称为旁路编码器用于符号的快速编码。下面对常规编码器具体的编码过程进行描述,编码过程必须与后面介绍的译码过程相匹配(H.264标准文件中给出了译码流程,没给出具体的编码流程,下面给出的是可参考的编码流程,必须与译码流程匹配)

1、首先是编码器的初始化

该过程是发生在编码片的第一个宏块之前,在编码I_PCM宏块的数据元素pcm_alignment_zero_bit和所有pcm_byte数据之后的。此过程中,输出的是算术编码器中的相关参数,区间下限codILow设置为0,区间长度codIRange设置为0x01FE,另外的firstBitFlag设置为1,计数器(用于防止相关寄存器溢出)bitsOutstangding和symCnt都被设置为0。

2、编码决定

此过程输入的是Binval(语法元素经过二进制化后的值),context_id(上下文模型)和编码器的环境codirange,codilow和symCnt,输出的值是codirange,codilow和symCnt。

10

电信学院学士学位论文

如图2.2所示。

该过程可以分为4个步骤

(1)通过当前编码器区间范围codiRange计算Qi的索引值i,然后利用状态索引(由上下文模型得到)和i进行查表得出Rlps的概率。

(2)根据要编码的符号是否MPS来更新算术编码中的概率区间下限和概率区间范围。 (3)上下文模型概率状态的更新(参考前文) (4)重整化处理,具体操作在后文给出。

图2.2 基于查表的算术编码器流程

3、重整化处理

在区间划分结束后,如果新的区间范围R不在合法范围[28, 29]之内,那么就需要进行重整化操作,输出1位或多位。如图2.3所示。其中用到的PutBit程序,其流程图如图2.4

11

电信学院学士学位论文

所示。

图2.3 重整化操作流程图

图2.4 重整化中的PutBit程序

12

电信学院学士学位论文

4、旁路编码模式

为了加快符号编码,假设 ,则常规算术编码过程得到了简化。首先,概率估计和更新过程的旁路被建立;其次间隔细分被执行。如图2.5所示。

图2.5 旁路编码流程

最后,编码完片内所有宏块的句法元素后,写入end_of_slice_flag的标志,然后进行字节压缩,在编码完一幅图像的所有元素后,所有输出的二进制位都会进行封装,成为适合NAL层的传输单位。

13

电信学院学士学位论文

细见3.4.16)来对系数进行编码。

编码亮度系数。先编码DC系数:读取系数的幅度与游程信息(level = currSE->value1 = DCLevel[k], run = curse->value2 = DCRun [k])。然后使用cabac.c文件中的writeRunLevel_ CABAC函数(详细见3.4.16)来对系数进行编码。再编码AC系数,编码过程与编码DC系数的类似。

最后返回rate。

3.2.6 writeChromaCoeff函数分析

int writeChromaCoeff () 主要功能:编码色度系数。

编码DC系数。先读取系数的幅度与游程信息(level = currSE->value1 = DCLevel[k], run = curse->value2 = DCRun [k])。然后使用cabac.c文件中的writeRunLevel_CABAC函数(详细见3.4.16)来对系数进行编码。

编码AC系数。编码过程与编码DC系数的类似。 最后返回rate。

3.3 rdopt.c部分函数分析

3.3.1给出了encode_one_macroblock的函数分析。 3.3.2给出了RDCost_for_macroblocks的函数分析。 3.3.3给出了RDCost_for_8x8blocks的函数分析。 3.3.4给出了RDCost_for_4x4IntraBlocks的函数分析。

3.3.1 encode_one_macroblock函数分析

void encode_one_macroblock () 主要功能:决定一个宏块的编码模式

如果宏块采用亚宏块模式编码(valid[P8x8] = 1),使用rdopt.c文件中的RDCost_for_ 8x8blocks函数(详细见3.3.3)来计算所需的码率变换损失。

否则,当宏块可以采用intra4*4模式编码时(valid[I4MB] = 1),使用rdopt.c文件中的Mode_Decision_for_Intra4x4Macroblock函数来决定一个宏块的4*4帧内预测模式。其中,对当前宏块中的4个8*8的块使用rdopt.c文件中的Mode_Decision_for_8x8IntraBlocks函数来决定每个8*8帧内预测块的预测模式。其中,对当前8*8块中的4个4*4的块使用rdopt.c文件中的Mode_Decision_for_4x4IntraBlocks函数来决定每个4*4帧内预测块的预测模式。其中,对所有的4*4帧内预测模式使用rdopt.c文件中的RDCost_for_ 4x4IntraBlocks函数(详

19

电信学院学士学位论文

细见3.3.4)来计算所需的码率变换损失。

如果开启了RDO模式,对于各个宏块级预测模式,使用rdopt.c文件中的给出了RDCost _for_macroblocks函数(详细见3.3.2)来计算所需的码率变换损失。

3.3.2 RDCost_for_macroblocks函数分析

int RDCost_for_macroblocks (double lambda, int mode, double* min_rdcost) 使用macroblock.c文件中的writeMBHeader函数(详细见3.2.3)来编码宏块头。 使用macroblock.c文件中的writeMotionInfo2NAL函数(详细见3.2.4)来编码运动信息。

使用macroblock.c文件中的writeCBPandLumaCoeff函数(详细见3.2.5)来编码当前宏块的块编码模式,量化参数差值与亮度系数。

使用macroblock.c文件中的writeChromaCoeff函数(详细见3.2.6)来编码色度系数。

3.3.3 RDCost_for_8x8blocks函数分析

double RDCost_for_8x8blocks (int* cnt_nonz, int* cbp_blk, double lambda, int block, int mode, int pdir, int ref, int bwd_ref)

编码8*8块的类型信息。使用cabac.c文件中的writeB8_typeInfo_CABAC函数(详细见3.4.5)来对当前子宏块类型(currSE->value1 = b8value)进行编码。

编码运动信息。首先,使用macroblock.c文件中writeReferenceFrame函数来编码参考帧。其中,使用macroblock.c文件中BType2CtxRef函数来设置参考帧参数的上下文(currSE->context = BType2CtxRef (mode)),然后使用cabac.c文件中的writeRefFrame_ CABAC函数(详细见3.4.7)对当前宏块的参考图像参数进行编码。然后,使用macroblock.c文件中writeMotionVector8x8函数来编码一个8*8块的运动矢量。其中,使用cabac.c文件中的writeMVD_CABAC函数(详细见3.4.9)来进行编码。

编码块编码模式CBP。使用cabac.c文件中的writeCBP_BIT_CABAC函数(详细见3.4.11)对当前8*8块的块编码模式进行编码。

编码亮度系数。使用macroblock.c文件中writeLumaCoeff8x8函数来编码一个8*8的亮度系数块。其中,使用macroblock.c文件中的writeLumaCoeff4x4_CABAC函数来编码一个4*4的亮度系数块。其中,使用cabac.c文件中的writeRunLevel_CABAC函数(详细见3.4.16)来对系数进行编码。

3.3.4 RDCost_for_4x4IntraBlocks函数分析

double RDCost_for_4x4IntraBlocks (int* nonzero, int b8, int b4, int ipmode, double lambda, double min_rdcost, int mostProbableMode)

使用cabac.c文件中的writeIntraPredMode_CABAC函数(详细见3.4.6)来对对当前宏

20

电信学院学士学位论文

块对的帧内预测模式进行编码。

使用macroblock.c文件中的writeLumaCoeff4x4_CABAC函数来编码一个4*4的亮度系数块。其中,使用cabac.c文件中的writeRunLevel_CABAC函数(详细见3.4.16)来对系数进行编码。

3.4 cabac.c部分函数分析

3.4.1给出了CheckAvailabilityOfNeighborsCABAC的函数分析。 3.4.2给出了writeFieldModeInfo_CABAC的函数分析。 3.4.3给出了writeMB_skip_flagInfo_CABAC的函数分析。 3.4.4给出了writeMB_typeInfo_CABAC的函数分析。 3.4.5给出了writeB8_typeInfo_CABAC的函数分析。 3.4.6给出了writeIntraPredMode_CABAC的函数分析。 3.4.7给出了writeRefFrame_CABAC的函数分析。 3.4.8给出了writeDquant_CABAC的函数分析。 3.4.9给出了writeMVD_CABAC的函数分析。 3.4.10给出了writeCIPredMode_CABAC的函数分析。 3.4.11给出了writeCBP_BIT_CABAC的函数分析。 3.4.12给出了writeCBP_CABAC的函数分析。

3.4.13给出了write_and_store_CBP_block_bit的函数分析。 3.4.14给出了write_significance_map的函数分析。 3.4.15给出了write_significant_coefficients的函数分析。 3.4.16给出了writeRunLevel_CABAC的函数分析。

3.4.1 CheckAvailabilityOfNeighborsCABAC函数分析

void CheckAvailabilityOfNeighborsCABAC()

主要功能:检查邻居宏块是否可用,在当前宏块中分别设置对应的指针。

利用mb_access.c文件中的getNeighbour函数来获得左邻居宏块与上邻居宏块的位置信息,若邻居宏块不可用,其值为空。

3.4.2 writeFieldModeInfo_CABAC函数分析

void writeFieldModeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp) 主要功能:对一个已知宏块的场模式信息(句法元素MB_FIELD)进行编码。 输入:句法元素,编码环境指针。

21

电信学院学士学位论文

计算上下文模型的增量(act_ctx = a + b),其中a与b分别为左邻居宏块与上邻居宏块的场模式信息,其取值规则如下:

如果左邻居宏块不可用(currMB->mbAvailA = 0),或者左邻居宏块为帧宏块(img->mb_data[currMB->mbAddrA].mb_field = 0),则a应置为0;否则,a置为1。

如果上邻居宏块不可用(currMB->mbAvailB = 0),或者上邻居宏块为帧宏块(img->mb_data[currMB->mbAddrB].mb_field = 0),则b应置为0;否则,b置为1。

如果当前宏块是帧宏块(mb_field = 0),则待编码的符号值为0;否则,为1。然后使用biariencode.c文件中的biari_encode_symbol函数(详细见3.5.1),根据得到的上下文(&ctx->mb_aff_contexts[act_ctx])以及编码器的状态对待编码符号值(也就是当前宏块的场模式信息)进行算术编码。

最后保存上下文模型的增量(se->context = act_ctx)。

3.4.3 writeMB_skip_flagInfo_CABAC函数分析

void eep_dp)

主要功能:对宏块跳过标记(句法元素mb_skip_flag)进行编码。 输入:句法元素,编码环境指针。

根据句法元素获取当前宏块的宏块类型(curr_mb_type = se->value1)。

为了计算上下文模型的增量act_ctx,求分别表示为左邻居宏块与上邻居宏块的宏块跳过标记信息的a与b,其取值规则如下:

如果左邻居宏块不可用(currMB->mb_available_up = NULL),或者左邻居宏块为非跳过宏块(currMB->mb_available_up->skip_flag = 0),则a应置为0;否则,a置为1。

如果上邻居宏块不可用(currMB->mb_available_left = NULL),或者上邻居宏块为非跳过宏块(currMB->mb_available_left->skip_flag = 0),则b应置为0;否则,b置为1。

若当前宏块是在B帧里面,进行以下编码: 计算上下文模型的增量(act_ctx = 7 + a + b)。

如果当前宏块采用直接预测模式,同时又没有重要系数(se->value1=0, se->value2 =0),则待编码的符号值为1;否则,为0。然后使用biariencode.c文件中的biari_encode_symbol函数(详细见3.5.1),根据得到的上下文(&ctx->mb_type_contexts[2][act_ctx])以及编码器的状态对待编码符号值(也就是当前宏块的场模式信息)进行算术编码。

保存当前宏块的跳过标记(currMB->skip_flag = (se->value1==0 && se->value2== 0)?0:1)。

最后保存上下文模型的增量(se->context = act_ctx)。 若当前宏块是在非B帧里面,进行以下编码: 计算上下文模型的增量(act_ctx = a + b)。

22

writeMB_skip_flagInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr

电信学院学士学位论文

如果当前宏块为跳过宏块(curr_mb_type = 0),则待编码的符号值为1;否则,为0。然后使用biariencode.c文件中的biari_encode_symbol函数(详细见3.5.1),根据得到的上下文(&ctx->mb_ type_contexts[1][act_ctx])以及编码器的状态对待编码符号值(也就是当前宏块的场模式信息)进行算术编码。

保存当前宏块的跳过标记(currMB->skip_flag = (curr_mb_type==0)?0:1)。 最后保存上下文模型的增量(se->context = act_ctx)。

3.4.4 writeMB_typeInfo_CABAC函数分析

void writeMB_typeInfo_CABAC(SyntaxElement *se, EncodingEnvironmentPtr eep_dp) 主要功能:对一个已知宏块的宏块类型(句法元素mb_type)进行编码。 输入:句法元素,编码环境指针。

根据句法元素获取当前宏块的宏块类型(curr_mb_type = se->value1)。

根据句法元素mb_type的值act_sym采取不同的编码方式。一般使用biariencode.c文件中的biari_encode_symbol函数(详细见3.5.1),根据得到的上下文以及编码器的状态对待编码符号值进行算术编码。为了简化叙述,下文只介绍求上下文与待编码符号的过程。

对于不同的片,不同的宏块类型,有不同的编码方式。 1、在I片中(img->type = I_SLICE),使用帧内预测模式时。

计算上下文模型的增量(act_ctx = a + b),其中a与b分别为左邻居宏块与上邻居宏块的宏块类型信息,其取值规则如下:

如果左邻居宏块不可用(currMB->mb_available_left = NULL),或者左邻居宏块为帧内预测4*4块(currMB->mb_available_left->mb_type = I4MB),则a应置为0;否则,a置为1。

如果上邻居宏块不可用(currMB->mb_available_up = NULL),或者上邻居宏块为帧内预测4*4块(currMB->mb_available_up->mb_type = I4MB),则b应置为0;否则,b置为1。

准备编码当前宏块类型(act_sym = curr_mb_type)。 保存上下文模型的增量(se->context = act_ctx)。

(1)当宏块类型为帧内预测4*4块(mb_type = Intra_4x4, act_sym = 0)时。 待编码符号为0,上下文模型增量使用之前求得的结果,则上下文为ctx->mb_type_contexts[0] + act_ctx。

(2)当宏块类型为I_PCM块(mb_type = I_PCM, act_sym = 25)时。

待编码符号有两位,第一位为1,上下文模型增量使用之前求得的结果,则上下文为ctx->mb_type_contexts[0] + act_ctx。

第二位待编码符号为1,使用biariencode.c文件中的biari_encode_symbol_final函数(详细见3.5.3),根据编码器的状态对待编码符号值(这里为1)进行算术编码。

(3)当宏块类型为帧内预测16*16块(mb_type = Intra_16x16_x_y_z, act_sym取值为

23

本文来源:https://www.bwwdw.com/article/lnm2.html

Top