作为基础,对其他宏块/子块的访问是编解码进行预测时所必不可少的操作,除此以外在许多别的地方也会用到,比如在对系数进行熵编码时。因此本文主要讲解源码中关于宏块访问的知识,这部分代码主要在mb_access.c中。
mb_is_available()
1 | Boolean mb_is_available(int mbAddr, Macroblock *currMB) |
该函数用于检测宏块是否可用,实际上是被其他函数所调用的基础函数。输入参数是待检测宏块的地址和当前宏块,其中宏块地址是按光栅扫描的顺序的序号,即从左到右、从上到下,从0开始编号。主要的条件是宏待检测块需要在画面范围内且在当前宏块位置之前,同时和当前宏块要属于相同slice。因为一般情况下来自不同slice的宏块是不能被使用的,但是如果当前宏块是在做去块效应滤波的话可以忽略该限制。
CheckAvailabilityOfNeighbors()
1 | void CheckAvailabilityOfNeighbors(Macroblock *currMB) |
此函数检测当前宏块的左(A)、上(B)、右上(C)、左上(D)的相邻宏块是否可用,其中左、右上、左上宏块还需要判断是否超出图像的左/右边界,因此后面多出一句判断x坐标的语句。但比较奇怪的是右上邻块应该判断的是右边界但是这里却判断了左边界,暂时未解。
getNonAffNeighbour()
1 | void getNonAffNeighbour(Macroblock *currMB, int xN, int yN, int mb_size[2], PixelPos *pix) |
此函数作用是在非帧场自适应模式下获取相邻(或当前)宏块内某个像素在帧内的绝对坐标(以像素为单位)以及在其所属宏块内的相对坐标(以像素为单位)。参数中xN和yN是相邻像素以当前宏块(currMB)的左上角像素为原点的相对坐标。mb_size是宏块大小,亮度宏块两个元素均为16,色度宏块两个元素均为8。pix就是用来保存获取到的像素信息的。
get4x4Neighbour()
1 | void get4x4Neighbour (Macroblock *currMB, int block_x, int block_y, int mb_size[2], PixelPos *pix) |
此函数与上一个函数相似,作用是获取某个相邻(或当前)4x4块在帧内的绝对坐标(以4x4块为单位)以及在其所属宏块内的相对坐标(以4x4块为单位)。参数block_x和block_y是4x4块内某个像素以当前宏块(currMB)的左上角像素为原点的相对坐标(以像素为单位),其余参数含义与上一函数相同。该函数多用于判断左邻和上邻4x4块的可用性。这里与上一个函数的区别要细细钻研!