参考博文
https://blog.csdn.net/xiexingshishu/article/details/39323515
https://blog.csdn.net/fanbird2008/article/details/47122091
1.亮度和色度采样
参考此博文中对源、解码图像中色度采样结构,亮度数组和色度数组之间的关系的分析。chroma_format_idc | 色彩格式 | SubWidthC | SubHeightC |
---|---|---|---|
0 | 单色 | – | – |
1 | 4:2:0 | 2 | 2 |
2 | 4:2:2 | 2 | 1 |
3 | 4:4:4 | 1 | 1 |
总结:样点是以宏块为单位进行处理的,每个宏块中的样点阵列的高和宽度均为16个采样点,变量MbWidthC和MbHeightC分别定义了每个宏块中色度阵列的高度和宽度:
2.反向扫描过程
2.1宏块扫描
在非宏块对的情况下:A和B宏块序号不连续,相差图像一行宏块个数。即按光栅扫描顺序编号.
在帧宏块对的情况下:A和B宏块序号连续,即按照锯齿扫描顺序编号。A、B组成不变。A称为顶帧宏块,B称为底帧宏块。
在场宏块对的情况下:A、B宏块序号连续,即按照锯齿扫描顺序编号。但是这个时候A是由原来A、B两个宏块中的奇数行像素组成,称为顶场宏块;而B是由原来A、B两个宏块中偶数行像素组成,称为底场宏块。
2.1宏块相对位置计算
位置计算的输入一般是宏块地址、宏块分割的索引或者子宏块分割的索引、4x4亮度块索引、8x8亮度块索引、- 输入为宏块地址addr,计算与图像相对x、y坐标
InverseRasterScan(a,b,c,d,e)
当e=0时, 结果为( a%(d/b) )*b
当e=1时, 结果为 ( a/(d/b) )*c
a:表示地址,地址是序号相关的,
反向扫描中addr序号对应的宏块的相对位置x,y
MbaffFrameFlag为0时,表示非宏块对出现
x=InverseRasterScan(addr,16,16,sampleWidth,0);
y=InverseRasterScan(addr,16,16,sampleWidth,1);
MbaffFrameFlag为1时,表示宏块对出现先计算x1、y1
x1 = InverseRasterScan(addr/2,16,32,sampleWidth,0);
y1 = InverseRasterScan(addr/2,16,32,sampleWidth,1);
接下来就是根据帧宏块和场宏块区分,如果是帧宏块那么y的值需要加上(addr%2)*16,场宏块y的值加上(addr%2)。
- 输入为宏块分割的索引mbPartIdx,计算与宏块相对x、y坐标
x= InverseRasterScan(mbPartIdx,MbPartWidth(mb_type),MbPartHeight(mb_type),16,0);
y= InverseRasterScan(mbPartIdx,MbPartWidth(mb_type),MbPartHeight(mb_type),16,1);
- 输入为子宏块分割的索引mbPartIdx和子宏块分割索引subMbPartIdx,计算子宏块分割subMbPartIdx中左上角亮度样点与所处子宏块相对x、y坐标
if mbtype in P_8x8、P_8x8ref()、B_8x8
x= InverseRasterScan(SubmbPartIdx,SubMbPartWidth(sub_mb_type[mbPartIdx]),SubMbPartHeight(sub_mb_type[mbPartIdx]),8,0);
y= InverseRasterScan(SubmbPartIdx,SubMbPartWidth(sub_mb_type[mbPartIdx]),SubMbPartHeight(sub_mb_type[mbPartIdx]),8,1);
else
x = InverseRasterScan(SubmbPartIdx,4,4,8,0);
y = InverseRasterScan(SubmbPartIdx,4,4,8,1);
4.反向4x4亮度块位置计算,输入为4x4亮度块的索引luma4x4Blkidx,输出对应的是其左上角相对于宏块左上角位置x、y坐标
x= InverseRasterScan(luma4x4Blkidx/4,8,8,16,0) + InverseRasterScan(luma4x4Blkidx%4,4,4,8,0);
y= InverseRasterScan(luma4x4Blkidx/4,8,8,16,1) + InverseRasterScan(luma4x4Blkidx%4,4,4,8,1);
4.反向8x8亮度块位置计算,输入为4x4亮度块的索引luma8x8Blkidx,输出对应的是其左上角相对于宏块左上角位置x、y坐标
x= InverseRasterScan(luma8x8Blkidx,8,8,16,0)
y= InverseRasterScan(luma4x4Blkidx/4,8,8,16,1)
2.1宏块可用性
2.1.1宏块地址及可用性推导
1.宏块地址可用性,输入是一个 宏块地址mbAddr,输出为可用性信息,存在以下条件时,宏块标志为不可用:mbAddr <0
mbAddr > CurrMbAddr
地址为mbAddr的宏块和地址为CurrMbAddr的宏块属于不同条带
2.相邻宏块地址可用性,输入是一个 宏块地址mbAddr,输出为可用性信息,存在以下条件时,宏块标志为不可用:
图示表示地址为mbAddr、mbAddrB、mbAddrC和mbAddrD的宏块与地址为CurrMbAddr的当前宏块在空间上的相对位置。
mbAddrA = CurrMbAddr -1,输出为mbAddr 宏块是否可用,当CurrMbAddr%PicWidthInMbs = 0时,mbAddrA标识为不可用
mbAddrB = CurrMbAddr -PicWidthInMbs ,输出为mbAddrB是否可用
mbAddrC = CurrMbAddr - PicWidthInMbs +1 当(CurrMbAddr + 1)%PicWidthInMbs =0时,mbAddrC 标识为不可用
mbAddrD = CurrMbAddr - PicWidthInMbs -1 当CurrMbAddr % PicWidthInMbs = 0时标识为不可用。
3.MBAFF帧中相邻宏块地址可用性推导,当MbaffFrameFlag为1,调用本过程
mbAddrA =2*( CurrMbAddr /2-1),输出为mbAddr 宏块是否可用,当(CurrMbAddr/2)%PicWidthInMbs = 0时,mbAddrA标识为不可用
mbAddrB = 2*( CurrMbAddr /2 -PicWidthInMbs) ,输出为mbAddrB是否可用
mbAddrC = 2*( CurrMbAddr /2 - PicWidthInMbs +1) 当( CurrMbAddr /2+ 1)%PicWidthInMbs =0时,mbAddrC 标识为不可用
mbAddrD = 2*( CurrMbAddr /2 - PicWidthInMbs -1 )当( CurrMbAddr /2)% PicWidthInMbs = 0时标识为不可用。
2.1.2相邻宏块、块和分割块的推导过程
如下表规定了输入的亮度位置差分值(xd,yd)和N的对应关系。N表示输出的mbAddrN、mbPartIdxN、subMbPartIdxN、luma8x8BlkIdxN、luma4x4BlkIdxN和chroma4x4BlkIdxN中N的替换值。N | xD | yD |
---|---|---|
A | -1 | -1 |
B | 0 | -1 |
C | prePartWidth | -1 |
D | -1 | -1 |
对应的与当前快的位置关系如下图
下面重点描述相邻4x4色度快的推导以及相邻分割快的推导过程
- 4x4色度块的推导输入值为索引chroma4x4BlkIdx,输出为mbAddrA、chroma4x4BlkIdxA、mbAddrB、chroma4x4BlkIdxB可用性状态,计算方法如下:根据chroma_format_idc的不同取值,索引为chroma4x4BlkIdx的4x4色度快左上角位置(x,y)推导
chroma_format_idc == 1或者2时
x= InverseRasterScan(luma4x4Blkidx%4,4,4,8,0);
y= InverseRasterScan(luma4x4Blkidx%4,4,4,8,1);
chroma_format_idc == 3
x= InverseRasterScan(luma4x4Blkidx/4,8,8,16,0) + InverseRasterScan(luma4x4Blkidx%4,4,4,8,0);
y= InverseRasterScan(luma4x4Blkidx/4,8,8,16,1) + InverseRasterScan(luma4x4Blkidx%4,4,4,8,1);
色度位置 xN = x + xD,yN=y+yD,调用下面2.2中相邻位置推导过程,以(xN,yN)作为输入,输出分别赋值给mbAddrN和(xW,yW)
- 相邻分割块的推导过程,本过程的输入为宏块分割索引mbPartIdx、当前子宏块类型currSubMbType、子宏块分割块的索引subMbPartIdx,输出为mbAddr/mbPartIdxA/subMbPartIdxA(当前宏块左侧的宏块或子宏块分割块机器可用性状态,或者是子宏块分割快CurMbAddr/mbPartIdx/subMbPartIdx左侧宏块或者子宏块分割快及可用性状态)
以mbPartIdx作为输入,计算得到反向宏块分割扫描的(x,y)坐标
以subMbPartIdx作为输入,调用反向子宏块分割的扫描过程计算得到(xS,yS)坐标
xN = x + xS +xD
yN = y + yS +yD
获取亮度位置,以(xN,yN)为输入,调用下面2.2中相邻位置推导过程,输出赋值给mbAddrN和(xW,yW)
如果mbAddrN不可用,将宏块或者子宏块标志为不可用
mbAddrN可用那么,宏块mbAddr中覆盖亮度位置(xW,yW)的宏块分割快被指定为mbPartIdxN,而且在宏块mbAddrN内,宏块分割mbPartIdxN中覆盖亮度位置(xW,yW)的子宏块分割快被指定为subMbPartIdxN
当mbPartIdxN和subMbPartIdxN还没有被解码时,将宏块分割块mbPartIdxN和子宏块分割块subMbPartIdxN标志为不可用。
2.2 相邻位置推导过程
xW = (xN + maxW)% maxW
yW = (yN+maxH)%maxH