PC机的MPEG-4编码原理详解及实现
程序采用了以下策略选取相邻块。定义块A,B,C,X的DC系数值分别为DC_A,DC_B,DC_C,DC_X。
如果DC_A与DC_B的差小于DC_B与DC_C的差,则DC_A与DC_B在数值上比较接近,即在垂直方向上的数值比水平方向上更接近,所以采用DC_C来预测DC_X;反之,在水平方向的数值比较接近,即采用DC_A来预测DC_X。
将当前块的DC系数与用来预测的相邻块的DC系数,经过特定处理后做差,其差存放到当前块的DC位置上,同时记录此DC系数的预测方向。
AC预测主要是针对8×8块的第一行或者第一列AC系数,其预测方向取决于当前块DC系数的预测方向。如图2所示,如果之前DC预测为水平预测,则当前块X的第一列AC系数采用A块的第一列AC系数预测,同时将X的第一列7个AC系数各自取绝对值后相加到变量S1(S1的初始值为0)上。将当前块第一列AC系数与用来预测的相邻块A的第一列AC系数做差,其7个差值存放到当前块的第一列AC系数的位置上,同时将7个差值各自取绝对值后相加到变量S2(S2的初始值为0)上。如果之前的DC预测为垂直预测,则只进行当前块X的第一行AC系数预测,其预测步骤同第一列AC系数的预测一样。
有时AC预测会产生较大的预测误差,并没有达到节省位流的目的,因此必须判断AC预测的有效性。在单个8×8小块的AC预测中,用S1记录了此小块的第一行或第一列AC系数的绝对值之和,用S2记录了第一行或第一列预测后7个差值的绝对和。以一个宏块的6个8×8小块为单位,将各个小块的S1与S2之差相加,得到值S。如果S非零,则此宏块进行AC预测,其标志ACpred_flag置1,否则此宏块不进行AC预测,ACpred_flag置0。
1.2.2 之字型扫描
DC和AC预测之后,对8×8块的系数进行之字形扫描,共有Zigzag,Zigzag_v(交替垂直扫描)和Zigzag_h(交替水平扫描)三种扫描方式。采用何种扫描方式由三个要素决定,即帧内还是帧间预测,AC预测标志ACpred_flag的值,DC系数的预测方向。
对于帧内预测的宏块,如果AC预测标志ACpredflag为0,则此宏块中的6个8×8块都使用Zigzag扫描;如果AC预测标志为1,则此宏块中的6个8×8块将根据各自的DC预测方向决定AC系数的扫描方向。如果DC预测为水平预测,则此8×8块使用Zigzag_v扫描方式扫描系数,否则使用Zigzag_h扫描方式。
对于帧间预测的宏块,其每个8×8块统一采用Zigzag扫描方式扫描系数。
8×8的系数矩阵经过之字型扫描后,大部分非零系数集中在一个一维数组的前部,大部分零系数集中在此一维数组的后面,根据此特点便产生了游程编码。
1.2.3 游程编码和熵编码
所谓游程编码就是对8×8系数矩阵的AC系数进行特定的处理,使其成为个数更少的三维矢量(Last,Run,Level)。其中,Level代表非0系数的大小。Run代表Level前面连续0的个数。Last代表终止标志:其值为0时,表示Level后还有不为0的系数;其值为1时表示该系数是最后不为0的数;余下的系数全为0。游程编码生成三维矢量,压缩了数据量,然后根据Last,Run和Level的不同组合作为索引,找到对应Huffman编码表中的码字,生成码流。
评论