您的位置:首页 > 其它

jm8.6之参数,函数简介

2014-05-19 11:10 337 查看
变量解释

六重指针all_mv的含义:

对应的是一个六维数组如下:

all_mv[block_x][block_y][list][ref][blocktype][direction]

其中block_x, block_y分别表示4*4块在整个宏块16*16内的水平和垂直位置,同时也说明所保存的运动矢量都是以4*4为单位的,假如有一个8*4的块,其运动矢量会保存成相同的两份。

List表示的是哪个参考帧列表

Ref表示的是参考帧序号

Blocktype表示的是宏块的类型,有16×16,16×8。。。4×4

Direction表示水平或垂直方向,其值分别是0和1

irng->all_mv[block_x][block_y][1ist][ref][mode][direction]:该变量是一个6维数组,存储了一个宏块的16个4x4块在全部参考帧.全部帧间预测模式下的运动向量。direetion=O表示运动向量的X分量,direction=1标示Y分量。函数BloekMotion-Search()的主要任务就是进行运动搜索,并更新该数组的值。

imgY_org存储原始的YUV像素。

best8x8fwref[mode][block8x8]:该2维数组存储了一个宏块的4个8x8block在各个帧间预测模式下的最佳前向参考帧。

bestSx8mode[block8x8]:该维数组存储了一个宏块的4个8x8block的最佳帧间预测模式。它的作用和意义和best8x8fwref类似。

b8Mode是帧间预测中对8X8块的再次细分,称为亚宏块级模式,划分定在表格b8_mode_table中const int b8_mode_table[6] = {0, 4, 5, 6, 7};其中0是8X8 Direct模式,只对B帧,4,8X8,5,8X4,6,4X8,7,4X4,以上5中模式在宏块级中统称为P8X8模式,这个可以在码流TRACE文件中可以应证。

img->cofAC[][][][],//AC coefficients[8x8block][4x4block][level/run][scan_pos],
第一个中括号中的值可为0,1,2,3,4,5,Y为0到3,U为4,V为5,第二个中括号中的值可为0,1,2,3,分别对应每个8*8块中的4个4*4的块,第三个中括号确定了是RunLevel还是Level,那么第四个中括号便是定位分量的具体位置了,其取值范围是0到15。

ene_pieture->imgY[pix_y][pix_x],enc_picture->imgUV[uv][pix_y][pix_x]:这两个数组存储了当前编码帧的重建图像的亮度分量和色度分量。其中。pix_y,pix_x表示像素点在整个图像中的纵横坐标。uv则指示了u或v分量.这两个数组在计算SSD值时被引用。

motion cost[mode][1ist][refl[block]:该数组存储了一个宏块的分块在不同帧间模式和参考帧下的运动估计的开销值。函数PartitionMotionSearch()的主要任务就是更新该数组。同时,该数组也在决定最佳参考帧时被引用。

img->mpr,img->mprr,img->mprr_2和img->mprr_c。这4个数组分别存储了一个宏块在如下4种预测模式下的预测值:亮度分量的帧间预测,亮度分量的4x4的帧内预测,亮度分量的16x16的帧内预测,色度分量的8x8预测。

mb_data为Macroblock类型的指针, if(((img->mb_data) = (Macroblock *) calloc(img->FrameSizeInMbs,sizeof(Macroblock))) == NULL)意思是:分配img->FrameSizeInMbs个Macroblock对象。

StorblePicture存放的是一帧帧方式或场方式的重建图像

FrameStore嵌套了StorblePicture,同时增加了一些标志信息,如是否已输出到文件等,所以它可以用于通用的表示一帧的数据结构(不分场或帧)

DecodedPictureBuffer又嵌套了FrameStore,它用于保存所有的重建图像(应该保存的),其中设置很多辅助的参数,如used_size用来表示已经保存的重建图像数,它可能保存了非参考帧重建图像。

listX[6]:该变量的作用是用来在每次编码一帧图像时,将所要用到的参考帧保存在其中。但真正所要用到的参考帧图像数据是指向到dpb对应的结构元素中。

对于P帧,只要用到listX[0]。

对于B帧,要用到listX[0],listX[1]

对于Mbaff的编码方式,可能还会用到listX[2-5]。

DC系数和AC系数

量化后得到的仍是64个系数,量化并没有改变系数的性质。大家知到DCT变换是将数据域从时(空)域变换到频域,在频域平面上变换系数是二维频域变量u和v的函数。对应于u=0,v=0的系数,称做直流分量,即DC系数,其余63个系数称做AC系数,即交流分量。

编码

IP帧如何编码

I帧是指帧内预测,该帧的每一个宏块都是根据已经编码好的宏块进行预测。

P帧是帧间预测,该帧中的每一个宏块是根据已经编码好的前面的帧中的宏块来进行帧间预测,同时也会根据本帧内已经编码好的宏块进行帧内预测,然后通过率失真函数来进行比较两者。

SAD



SAD为计算两块等大宏块区域中所有像素差的绝对值之和,其中s 是当前进行编码的原始数据,而c 是已经编码重建的用于进行运动补偿的参考帧的数据。MV 为候选的运动矢量,λMOTION 为拉格朗日常数,PMV 为中值预测矢量,R(MV-PMV)代表了运动矢量差分编码可能耗费的比特数, 由于在接下来的四种匹配误差预测方式中匹配误差中的λMOTION×R(MV-PMV)部分通常很接近而抵消,SAD 部分的预测特性基本上可以反映整个匹配函数的预测特性,因此J(MV,λMOTION)用SAD 来表示。

SA(T)D 表示原始图像块和预测图像块之间的绝对差值和。如果使用Hadamard 变换,SA(T)D 表示对原始图像和预测图像之间的差值矩阵进行4x4 的Hadamard 变换,然后对变换后的矩阵求绝对值和并除以2。

SSD标示原始图像块和重建图像块之间的差值和。

为什么使用SATD而不使用SAD呢?

关键原因在于编码之后码流的大小是和图像块DCT变换后频域信息紧密相关的,而和变换前的时域信息关联性小一些。SAD只能反应时域信息;SATD却可以反映频域信息,而且计算复杂度也低于DCT变换,因此是比较合适的模式选择的依据。

编码模式

编码模式在以下的7种帧问,17种帧内模式中间选择。7种帧问模式包括:16xi6、16x8、8x16、8x8、8x4、4x8、4x4,分别对应模式编号l~7。17种帧内模式包括:以4x4块为单位进行亮度分量预测的9种模式(统称为I4MB),以宏块为单位进行亮度分量预测的4种模式(统称为I16MB)和以宏块为单位进行色度分量预测的4种模式。值得注意的是,在进行帧间预测的时候,只有在选择了把一个宏块划分成4个8x8的块之后,才能进一步选择8x4,4x8和4x4的分块,因此,在JM模型中,把和7的4种帧间模式统称为P8x8。根据配置文件中的RDOptimization的取值,JM采用两套不同的编码步骤,IPCM为不需要预测。

色度块采用和亮度块同样的分割模式,只是尺寸减半(水平和垂直方向抖减半)。色度块的MV也是通过相应亮度运动矢量的水平和垂直分量减半而得。

全搜索算法

JM为实现全搜索ME算法在mv-search.c文件中提供了两个函数FullPelBlockMotionSearch与FastFullPelBlockMotionSearch,这两个函数实现的都是全搜索。可以通过定义宏_FAST_FULL_ME_来选择使用FastFullPelBlockMotionSearch而不使用FullPelBlockMotionSearch ,为了改写的方便我们选择使用.FullPelBlockMotionSearch 并对其改写,这样我们需在defines.h头文件中将#define
_FAST_FULL_ME_一行删去或注释掉,这样编译器将只编译FullPelBlockMotionSearch函数。

BlockMotionSearch

BlockMotionSearch()的主要任务就是进行运动搜素,并更新all_mv[block_x][block_y][list][ref][mode][direction]的值。

PartiotionMotionSearch

对于宏块和亚宏块级的运动估计,都采用了这个共同的函数。PartiotionMotionSearch()主要进行了3项工作:

第一,选择一个参考帧和分块(如果选择了P8x8模式,则每个8x8bloek还要进行继续的划分)。调用BlockMotionSearch()进行每个分块的运动搜索。其中,BlockMotionSeareh()函数找到运动向量并更新img->all_mv的值,并将对应运动开销作为函数返回值;

第二,用BlockMotionSerch0的返回值更新motion_cost,作为接下来进行参考帧选择的依据;

第三,更新encpicture->re_idx,encpicture->mv两个全局变量,这两个变量将作为BlockMotionSearch()中运动搜索时运动向量预测的依据。程序从PartitionMotionSearch()返回之后,继续进行最佳参考帧的选择,选择依据cost_motion = SA(T)D+lambda_motion*Rate_moiton;cost_ref=cost_motion+lambda_motion*Rate_mf。最后,程序将最佳参考帧的信息存储在数组bestSx8fwref中。

RDCost_for8x8blocks

程序将调用RDCost_for8x8blocks()来进行模式开销的计算,该函数主要进行了以下几项工作。

第一,调用LumaResidualCoding8x8()对该8x8块进行亮度值的预测,残差数据的变换量化以及反变换反量化,以及重建图像的计算。

第二,调用熵编码函数对待编码信息进行熵编码,得到rate值。

第三,计算SSD值并计算开销,将其作为函数的返回值。其中,LumaPrediction4x4首先调用OneComponentLumaPrediction4x4()函数,按照给定的预测模式,参考帧以及运动向量,得到一个(或者两个,对于B slice的双向预测而言)4x4block的亮度矩阵。然后对该亮度矩阵进行加权处理,将预测值存储在img->mpr中。随后,程序调用dct_luma()对残差数据进行变换量化以及反量化反变换,并进行重建块的计算,将重建块矩阵存储在encpicture->imgY中,并将经过重排序和游程编码的系数存储在img->cofAC中。程序从LumaResidualCoding8x8()函数返回以后,将紧接着调用熵编码函数计算Rate值,在计算了SSD之后,程序按照式cost_motion
= SA(T)D+lambda_motion*Rate_moiton;cost_ref=cost_motion+lambda_motion*Rate_mf得到编码开销作为函数的返回值。

Intra16x16_Mode_Decision

该函数包括3部分: intrapred_luma_16x16:计算4种模式的预测值,find_sad_16x16: 计算SATD值作为代价,从而得到最优的模式,dct_luma_16x16:对于所选出的最优模式进行DCT变换/量化和反DCT变换和量化。

encode_one_macroblock

encode_one_macroblock函数中的运动估计分为两大块,对于宏块级的三种模式,分块后直接对patition依次调用PartitionMotionSearch()函数,而对于亚宏块级的(含8x8,8x4,4x8,4x4)模式,首先将宏块拆分为4个8x8子宏块,针对每个8x8子宏块调用PartitionMotionSearch()函数。

解码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: