《电子技术应用》
您所在的位置:首页 > 其他 > 设计应用 > 支持MBAFF的H.264/AVC解码器运动矢量预测模块设计
支持MBAFF的H.264/AVC解码器运动矢量预测模块设计
包 磊,周开伦,林 涛
(同济大学 超大规模集成电路研究所,上海 200331)
摘要: 分析了宏块自适应帧场模式(MBAFF)在P帧和B帧的帧间预测算法,提出了可行的数据组织结构和硬件实现方法。作为完整的解码器的一部分,其RTL代码已经完成了功能验证和仿真,证明该设计是行之有效的。
Abstract:
Key words :

摘  要: 分析了宏块自适应帧场模式(MBAFF)在P帧和B帧的帧间预测算法,提出了可行的数据组织结构和硬件实现方法。作为完整的解码器的一部分,其RTL代码已经完成了功能验证和仿真,证明该设计是行之有效的。
关键词: H.264;MBAFF;帧间预测;运动矢量预测

  H.264/AVC支持3种图像编码模式:帧模式、场模式和宏块自适应帧场(MBAFF)[1]模式。在帧模式下,1幅图像被划分成由16×16宏块组成的帧;在场模式下,1帧图像的顶场和底场被划分成由16×16宏块组成;在MBAFF模式下,帧场编码的选择在宏块级指定,1帧图像被划分成由32×16的宏块对组成,每2个宏块组成的宏块对以帧模式或者场模式编码。一段图像可能既有动态的区域又有静态的区域,H.264的MBAFF模式可以根据图像的每个区域选择最佳的编码模式。一般来说,MBAFF模式对于视频编码的效率比其他两种模式更好,但编码和解码的复杂度也更高。本文将探讨在解码的过程中MBAFF模式在P帧和B帧的帧间预测算法和硬件设计。
1 帧间预测技术
  在进行帧间预测时,空间上距离较近的图像区域往往具有相关性很强的运动矢量,而且相对于以前视频压缩标准中最小8×8的划分,H.264最小4×4的划分使得较小的图像区域的运动矢量具有更高的相关性,因此,可以利用预测技术预测出1组运动矢量MVp,而编码器只需要传送能量很小的实际值和预测值的差值,也就是运动矢量残差MVd,这样就可以提高编码效率。在解码时,解码器只需要采用同样的算法先预测出运动矢量的预测值MVp,而后将其与残差MVd相加便可以恢复出运动矢量的实际值MV[1]供运动补偿使用。MVp[1]取决于运动补偿的尺寸和邻近MV的有无。
  在帧间预测模式下,宏块有16×16、16×8、8×16、8×8、8×4、4×8、4×4这7种运动矢量的分割方法。为方便描述,把参考宏块相应分割的运动矢量命名为MVLXN[2],参考索引命名为refIdxLXN[2],其中N可以为A、B、C、D,分别表示当前宏块或者宏块分割的左边、上边、右上和左上的相应宏块分割。当前宏块分割的运动矢量MVpLX[2]就是通过MVLXN和refIdxLXN预测得到的。图1所示为非MBAFF模式时当前宏块分割为16×16的情况,E为当前宏块或宏块分割,A、B、C分别为E的左、上、右上方的3个相对应分割块。如果E的左边不止1个分割,则取其中最上的1个为A;上方不止1个分割时,取最左边1个为B。


1.1 预测运动矢量MVp的计算
  在宏块分割为16×16、8×8、8×4、4×8和4×4时,运动矢量的预测值是由参考宏块分割A、B、C的运动矢量计算得到的:
  (1)如果分割B和C不可用,而分割A可用,则会对MVLXB、MVLXC、refIdxLXB、refIdxLXC重新赋值:MVLXB=‘MVLXA、MVLXC=MVLXA、refIdxLXB=refIdxLXA、refIdx-LXC=refIdxLXA。
  (2)根据refIdxLXA、refIdxLXB和refIdxLXC的取值计算mvpLX:
  ①如果分割A、B、C的参考索引refIdxLXA、 refIdxLXB或refIdxLXC中的一个等于当前分割的索引号refIdxLX,则当前分割的矢量预测值由相应分割的运动矢量得到:MVpLX=mvLXN。
  ②如果分割A、B、C的参考索引refIdxLXA、 refIdxLXB或refIdxLXC都不等于当前分割的索引号refIdxLX,则通过取A、B、C的运动矢量中值得到:
  MVpLX[0]=Median(MVLXA[0],MVLXB[0],MVLXC[0])
  MVpLX[1]=Median(MVLXA[1],MVLXB[1],MVLXC[1])
  运动矢量的预测在当前宏块分割为16×8和8×16的时候会先做如下的判断,如果不满足则通过上述取中值的方法得到预测值:
  (1)对于1个宏块被分割成2个16×8子宏块的情况
  ①计算mbPartIdx等于0的子宏块如图2(a)所示。如果refIdxLXB等于当前分割的refIdxLX,则当前块的矢量预测值由B宏块的相应分割的矢量得到:MVpLX= MVLXB。


  ②计算mbPartIdx等于1的子宏块如图2所示,如果refIdxLXA等于当前分割的refIdxLX,则当前块的矢量预测值由A宏块的相应分割的矢量得到:MVpLX=MVLXA。
  (2)对于1个宏块被分割成2个8×16子宏块的情况:
  ①计算mbPartIdx等于0的子宏块如图2(b)所示。如果refIdxLXA等于当前分割的refIdxLX,则当前块的矢量预测值由B宏块的相应分割的矢量得到:MVpLX=MVLXA。
   ②计算mbPartIdx等于1的子宏块如图2(b)所示,如果refIdxLXC等于当前分割的refIdxLX,则当前块的矢量预测值由C宏块的相应分割的矢量得到:MVpLX=MVLXC。
1.2 参考宏块分割的运动矢量MVLXN和参考索引refIdxLXN的计算
  在计算参考宏块分割A、B、C的运动矢量MVLXN和参考索引refIdxLXN之前,应先检测分割C是否可用,如果C不可用,则用分割D的信息代替。A、B、C的运动矢量MVLXN和参考索引refIdxLXN的计算:
  (1)如果宏块mbAddrN不可用或者宏块mbAddrN为帧内编码,或者mbAddrN相应分割或者子宏块分割的predFlagLX等于0,则对MVLXN置0,对refIdxLXN置-1。
  (2)MVLXN为mbAddrN相应宏块分割或者子宏块分割的运动矢量,refIdxLXN为mbAddrN相应宏块分割的参考索引值:
  MVLXN=MvLX[mbPartIdxN][subMbPartIdxN]
  refIdxLXN=RefIdxLX[mbPartIdxN]
  (3)在MBAFF模式时,需要对MVLXN和refIdxLXN再做1次计算:
  ①如果当前宏块为场宏块,而mbAddrN为帧宏块,则:
  MVLXN[1]=MVLXN[1]/2
  refIdxLXN=refIdxLXN×2
  ②如果当前宏块为帧宏块,而mbAddrN为场宏块,则:
  MVLXN[1]=MVLXN[1]×2
  refIdxLXN=refIdxLXN/2
1.3 空间相邻参考宏块分割的选择[2]
  在非MBAFF模式时,当前宏块的空间相邻宏块地址A、B、C、D的位置如图3所示。空间参考宏块mbAddrN可以是MbAddrA、MbAddrB、MbAddrC、MbAddrD或者CurrMbAddr。


  在MBAFF模式时,当前宏块的空间相邻宏块地址A、B、C、D的位置如图4所示。此时会根据当前宏块是帧宏块或者场宏块currMbFrameFlag以及当前宏块是顶宏块或者底宏块mbIsTopMbFlag来计算1个中间值mbAddrX,并根据mbAddrX的帧场信息mbAddrXFrameFlag来得到最终的参考宏块MbAddrN。参考宏块mbAddrN可以是MbAddrA、MbAddrA+1、MbAddrB、MbAddrB+1、MbAddrC、MbAddrC+1、MbAddrD、MbAddrD+1、CurrMbAddr或者CurrMbAddr-1。
  参考分割A、B、C、D取自参考宏块mbAddrN,也可能来自当前宏块的空间相邻宏块或可能是当前宏块内已解码的分割。
1.4 运动矢量预测所需数据的组织
  运动矢量的预测需要当前分割的左边、上边、左上和右上相应分割的MVLXN和refIdxLXN信息来计算得到当前分割的MVLX。如果宏块的4个子宏块都采用4×4分割,则1个宏块有16个运动矢量,即每个4×4 block有1个运动矢量。这样需要储存每个block的运动矢量和参考索引。1个宏块需要存储16个block的运动矢量MVLX和参考索引refIdxLX,当采用其他分割类型时,每个分割内所有block的运动矢量和参考索引为相同值。
   帧间预测按照block存储和使用数据。当前宏块分割的运动矢量和参考索引需要按照block来存储以用于后面宏块的预测。每个分割内所有block的运动矢量和参考索引为相同值,所以参考分割的MVLXN和refIdxLXN的引用也可以按照block来进行。
  因为同一分割内所有block的运动矢量和参考索引为相同值,因此,参考分割的MVLXN和refIdx-LXN也就是参考宏块相应的block的MVLX和refIdx-LX。图5为非MBAFF模式时预测当前分割的运动矢量的示意图。由图可见,在进行预测时是通过与当前分割最接近的左、上、左上以及右上的4个4×4 block的运动矢量来对当前的运动矢量进行预测的。图5(a)~(d)分别表明了当前宏块采用不同划分时A、B、C、D 4个参考块的取值情况。在预测时一般选取A、B、C块对当前的运动矢量进行预测,当C不可用时则选用A、B、D进行预测。在MBAFF模式时,由于参考宏块的位置不同(参见1.3节)会作相应变化。

2 直接预测模式和硬件设计
  H.264/AVC对运动矢量的重建引入了直接预测模式,在该模式下运动矢量残差没有被传送,只有宏块的预测模式会被传送。解码器根据预测模式以及其余宏块的信息对当前的运动矢量进行恢复。运动矢量的重建流程如图6所示。在直接预测模式下,H.264分别采用3种不同的方式对运动矢量进行重建。


  (1)复制模式。在P类型的宏块中,利用空间上相邻分割的运动矢量对当前的运动矢量进行预测。
  (2)空间模式。在B类型的宏块中,利用空间上相邻分割的运动矢量对当前的运动矢量进行预测。
  (3)时间模式。在B类型的宏块中,通过将时间上相邻而且在空间上位置相同的8×8分割的运动矢量进行重量化来预测出当前的运动矢量。
  其中复制模式和空间模式在算法上具有一定的相似性,差别在于复制模式只需要重建1个方向的运动矢量,而空间模式需要重建双向的运动矢量。
2.1 空间模式及复制模式重建算法和硬件设计
    在这2种模式下:(1)宏块只能划分成1个16×16分割或者4个8×8分割。在划分成4个8×8时,每1个8×8分割可以独立地被设置成直接模式或者ReadMV模式;(2)计算当前的运动矢量需要借助在空间上相邻分割的运动矢量来对当前分割的运动矢量进行重建。此时运动矢量的预测算法与前面介绍的预测运动矢量的算法基本相同,所不同的是此时宏块中的任意1个分割预测时所使用的相邻块信息均由图7所示的A、B、C、D 4个块预测。

  Direct 8×8用A、B、C、D 4个块进行预测。预测的基本算法流程如图8所示。由图可见,在预测时首先检测参考块C是否可用,如不可用,则C块的参数用D块的参数代替;而后利用A、B、C块的参考索引RefIdxA[f/b]、RefIdxB[f/b]、RefIdxC[f/b]中大于0的最小值来预测出当前分割的参考索引号ReFrame[f/b],如果RefIdxA[f/b]、RefIdxB[f/b]、RefIdxC[f/b]全部小于0,则ReFrame[f/b]取-1;然后用ReFrame[f/b]与A、B、C块的参考索引进行对比,如果ReFrame[f/b]只是A、B、C其中的1个,现令其为SelectedBlk的索引号相同,则当前分割的运动矢量中,(MVx,MVy)取SelectedBlk的(MVxS,MVyS);否则取A、B、C块运动矢量的中值。


  在空间模式及复制模式下,需要使用空间上相邻的上边及左边的4×4块的运动矢量信息来对空间模式、复制模式中的运动矢量以及ReadMV模式中的MVp进行计算。针对非MBAFF模式和MBAFF模式所需要的block的运动矢量信息分析如下:
  (1)在非MBAFF模式时,硬件实现需要维持1个4×4 block行,以及当前待解码宏块的左边4个block列的运动矢量信息。解码器如果需要支持1 920×1 280分辨率视频流的解码,则就要存储(1 920/4+4+1)=485个4×4 block的运动矢量信息,如图9所示。

  (2)在MBAFF模式时,由于宏块对的出现使得所需要的block信息相比非MBAFF模式的情况更加复杂。硬件实现时需要维持2个4×4 block行,以及当前待解码宏块的左边宏块对的8个block列的运动矢量信息。解码器如果需要支持1 920×1 280分辨率视频流的解码,则就要存储(2×(1920/4)+8+1)=969个4×4 block的运动矢量信息,如图10所示。


    设计中将这部分信息存放在片内SRAM中。此外,为了便于读取以及节省存取时间,设计中将1个block的运动矢量信息存放于SRAM 1个地址单元中。1个地址单元的数据结构需要存放前向参考索引RefIdxF、后向参考索引RefIdxB、前向水平运动矢量MVxF、前向垂直运动矢量MVyF、后向水平运动矢量MVxB、后向垂直运动矢量MVyB。
    通过以上分析在硬件实现时采用如图11所示的结构对该模块进行设计。设计中使用1个Local Sram作为1个Line buffer来对空间模式及复制模式下需要使用到的空间上相邻块的运动矢量信息进行存储。当该模块被启动后,根据输入的当前宏块的预测模式以及当前宏块的位置信息,地址生成器根据当前宏块的信息产生相应的地址以及控制信号从Local Sram中取出A、B、C、D 4个block的运动矢量信息传送给MV idx计算模块来计算当前分割的运动矢量,计算完毕后得出完成信号给地址生成器以便其产生相应的地址将解码好的数据存回Local Sram中供后续解码使用。


2.2 时间模式重建算法和硬件设计
  图12所示为宏块类型为B宏块、预测模式为直接预测模式时采用时间模式对运动矢量进行重建的算法示意图。


   由图可见,时间模式运动矢量重建的步骤为:
  (1)当前待解的分割先在List[1][0]中找到与自己位置相对应的分割相应的、在List[0]中的参考图像List[0][x],将该参考图像作为当前分割的List[0]参考。
  (2)找出List[1][0]图像中与当前分割位置相对应的分割指向List[0][x]的运动矢量MVCol[2]和参考索引refIdxCol[2]。
  (3)根据当前分割所在图像与List[0][x]图像的播放顺序POC的差值tb[2]、List[0][x]与List[1][0]的POC的差值td[2],通过如下公式量化出当前分割指向List[0][x]图像的运动矢量MVL0以及指向List[1][0]的运动矢量MVL1。
  tb=Clip3(-128,127,DiffPicOrderCnt(currPicOrField, pic0))
  td=Clip3(-128,127,DiffPicOrderCnt(pic1,pic0))
  tx=(16 384+Abs(td/2))/td
      DistScaleFactor=Clip3(-1024,1023,(tb*tx+32)>>6)
      MVL0=(DistScaleFactor*mvCol+128)>>8
      MVL1=MVL0-MVCol
     (4) 根据refIdxCol和当前图像是帧或场图像标志field_pic_flag以及当前宏块是帧宏块或场宏块来计算refIdxL0:
     refIdxL0=((refIdxCol<0)?0:MapColToList0(refIdxCol))
     refIdxL1=0
     在非MBAFF模式时,图像类型可以是FRM和FLD表示当前是帧或场;在MBAFF模式时,图像类型以AFRM表示当前图像是宏块级帧场自适应。
     在MBAFF模式时,首先根据当前图像类型PicCodingStruct(CurrPic)[2]和参考图像类型PicCodingStruct(colPic)[2]来计算1个宏块地址mbAddrX,然后再根据mbAddrX是否为场宏块以及当前宏块是否为场宏块来计算出在List[1][0]中与当前分割位置相对应的宏块mbAddrCol,最后得到其中相应宏块分割mbAddrCol\mbPartIdxCol\subMbPartIdxCol的运动矢量MVCol和参考索引refIdxCol,MVCol和refIdxCol取值为mbAddrCol相应分割的前向或者后向运动矢量和参考索引。
  因此,对于已经解码的图像需要存储每个宏块的运动矢量、参考索引、宏块类型(mbType、subMbType)和宏块的帧场标志mb_field_decoding_flag[2],以用于当前图像宏块的运动矢量预测。
  时间模式下运动矢量重建的硬件实现框图如图13所示。设计中采用了空间模式以及复制模式硬件实现所用的Local Sram。这里还在Local Sram中开辟了一段新的存储空间,用于存放所需要的图像层信息。与空间及复制模式一样,重建后的运动矢量信息写回到Local Sram中供后续解码使用。


  由运算公式可见时间模式下运动矢量的重建涉及乘法、除法、加法以及减法运算,这些运算对于硬件实现将会带来很大的开销,所以设计中将差值运算拆分成流水线的形式进行运算。
  本文介绍了H.264/AVC的宏块自适应帧场模式在P帧和B帧的帧间预测算法,分析了运动矢量预测模块的硬件实现,提出了可行的数据组织结构和硬件实现方法。
参考文献
[1] 毕厚杰.新一代视频压缩编码标准——H.264/AVC[J].北京:人民邮电出版社,2002.
[2] Advanced video coding for generic audiovisual services. ITU-T Recommendation H.264, May. 2005.

此内容为AET网站原创,未经授权禁止转载。