-
访问单元:一系列NAL单元,包含一个primary coded picture,也可以包含一系列redundant coded pictures和一个auxiliary coded picture。
-
逐行扫描:每个frame进行frame coding
隔行扫描:每个frame可以选择frame coding还是field coding
-
inter预测的direct预测模式分为时域和空域预测两种,都不传MV
-
layer:序列层,图像层,片层,宏块层
-
宏块地址:非MBAFF的MB为光栅扫描序号;MBAFF的MB,每个宏块对的顶宏块为光栅扫描序号×2,底宏块为顶宏块+1.
-
宏块位置:(x,y)表示 每右移一次,x+1
非MBAFF的宏块,下移一次y+1
MBAFF的宏块对,下移一次y+2,如果是底宏块则再y+1
-
只有MBAFF才有宏块对(又分为帧/场宏块对) 其余分为宏块单独存在,分为帧编码和场编码
-
nal_ref_idc = 0表示该场/帧/图像不作参考使用
-
每个slice头部有pic_parameter_set_id,确定一个图像参数集
-
由对应图像参数集里的seq_parameter_set_id确定的序列参数集,图像参数集由slice header里面的pic_parameter_set_id确定
-
POC(picture order count) 代表IDR后解码顺序的图像计数值,或者清空所有ref pic后的图像计数值
-
run(游程)表示非零系数前0值系数的数目
-
RBSP最后,加上一个一个截止位1
-
SODB(string of data bits),代表语义元素,出现在RBSP截止位之前
SODB就是编码后的原始数据,封装成RBSP后装入NAL单元内
- 比特流格式:NAL单元流和字节流,其中,附录B讲述NAL单元的组成和NAL语义
字节流是NAL单元加上起始前缀和一系列零字节后得到的,可以相应地提取出NAL单元来;
NAL单元流由NAL单元构成。
-
辅助编码图片用于阿尔法混合(透明度混合)
-
chroma_format_idc代表采样率,决定色度分量块的高SubHeightC和宽SubWidthC
separate_colour_plane_flag代表三个分量平面是否用独立的大小
MbWidthC = 16/SudWidthC 当c_f_i=0或者s_c_p_f = 1时为0
MbHeightC = 16/SubHeightC当c_f_i=0或者s_c_p_f = 1时为0
-
顺序:Y->Cb->Cr
-
slice:非MBAFF,是一系列宏块;MBAFF,是一系列宏块对
-
separate_colour_plane_flag = 1时,每个分量被分别调入各自的slice(由colour_plane_id区别);也就是说需要三个slice去储存每个原来一个slice的三个分量
-
宏块分割和扫描顺序
见标准Figure6-9 6-10 6-11
每个4×4或8×8的luma block则是raster scan顺序
- 反向扫描过程
InverseRasterScan(a,b,c,d,e)
当e=0时, 结果为( a%(d/b) )*b
当e=1时, 结果为 ( a/(d/b) )*c
a:宏块地址(宏块序号) b:宏块宽度 d:图像/区域/块宽度 c:宏块/宏块对高度 e:标志
返回的单位是像素,本宏块的相对像素起始(x,y)
宏块 => 图像/片/帧
宏块分割 => 宏块
子宏块分割 => 子宏块
MbaffFrameFlag = 0
MbaffFrameFlag = 1
x = InverseRasterScan(
mbAddr,16,16,PicWidthInSamples,0)
y = InverseRasterScan(
mbAddr,16,16,PicWidthInSamples,1)
x0 = InverseRasterScan(
mbAddr/2,16,32,PicWidthInSamples,0)
y0 = InverseRasterScan(
mbAddr/2,16,32,PicWidthInSamples,1)
frameMB:(宏块对里宏块没有重组)
x = x0
y = y0 + (mbAddr%2)*16
fieldMB:(宏块对里宏块已经重组)
x = x0
y = y0 + (mbAddr%2)
- 宏块分割 得到值MbPartWidth MbPartHeight
对应P_8×8,P_8×8ref0或者B_8×8,有SubMbPartWidth和SubMbPartHeight
- 反向宏块分割扫描
x = InverseRasterScan(
mbPartIdx, MbPartWidth( mb_type ), MbPartHeight( mb_type ), 16, 0 )
y = InverseRasterScan(
mbPartIdx, MbPartWidth( mb_type ), MbPartHeight( mb_type ), 16, 1 )
mbPartIdx表示宏块里面的分割块序号,可以有16×16,16×8,8×16,8×8四种分割
反向子宏块分割扫描
mb_type = P_8x8, P_8x8ref0, or B_8x8,
others
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 )
x = InverseRasterScan(
subMbPartIdx, 4, 4, 8, 0 )
y = InverseRasterScan(
subMbPartIdx, 4, 4, 8, 1 )
//----默认子宏块分割成4×4的块
此处 sub_mb_type为数组,分别记录了每个mbPartIdx对应的子宏块类型,此处mbPartIdx就是子宏块号,它的分割被subMbPartIdx索引
- 块扫描(得到每个分块相对于该宏块起点的起始偏移(x,y))
-
4×4luma
将16×16宏块分为4个8×8的块,再把8×8的块分成4个4×4的块
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×4chroma
当ChromaArrayType = 3时使用,同4×4luma
-
8×8luma
x = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 0 )
y = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 1 )
-
8×8chroma
当ChromaArrayType = 3时使用,同8×8luma
- 宏块地址可用性---------------获得mbAddr
当mbAddr < 0 ; mbAddr > CurrMbAddr ; mbAddr 与 CurrMbAddr属于不同Slice,则mbAddr不可用;
当MbaffFrameFlag = 0时
mbAddrX代表X的地址和其可用性
mbAddrA = CurrMbAddr – 1
当CurrMbAddr % PicWidthInMbs=0时不可用
mbAddrB = CurrMbAddr − PicWidthInMbs
mbAddrC = CurrMbAddr − PicWidthInMbs + 1
当( CurrMbAddr + 1 ) % PicWidthInMbs = 0时不可用
mbAddrD = CurrMbAddr − PicWidthInMbs – 1
当CurrMbAddr % PicWidthInMbs=0时不可用
- 相邻宏块,块,分割可用性的推导过程
N
xD
yD
A
-1
0
B
0
-1
C
predPartWidth
-1
D
-1
-1
MbaffFrameFlag = 0时
-
由相对于当前宏块左上角位置的偏移(xN,yN)得到可用性的过程:
亮度:maxW = maxH = 16
色度:maxW = MbWdithC,maxH = MbHeightC
由(xN,yN)得到对应mbAddr
xN
yN
mbAddrN
<0
<0
mbAddrD
<0
0…maxH-1
mbAddrA
0…maxW-1
<0
mbAddrB
0…maxW-1
0…maxH-1
CurrMbAddr
maxW-1
<0
mbAddrC
maxW-1
0…maxH-1
不可用
maxH-1
不可用
得到对应于mAddr里偏移的位置(xW,yW)
xW = (xN + maxW)%maxW
yW = (yN + maxH)%maxH
只要有mbAddrN,则该宏块就可用,相应信息比如mb_type等等写入该结构体
-
相邻宏块可用性
输出为mbAddrA和mbAddrB
xN = xD,yN = yD
计算mbAddrN
-
相邻8×8亮度块可用性
输入:luma8×8BlkIdx,当前宏块的8×8亮度块序号
输出:mbAddrA(可能等于CurrMbAddr,也可能是左边一个MbAddr),luma8×8BlkIdxA,mbAddrB,luma8×8BlkIdxB
步骤:
xN = (luma8×8BlkIdx%2)*8 + xD
yN = (luma8×8BlkIdx/2)*8 + yD
计算mbAddrN并得到(xW,yW);
计算luma8×8BlkIdxN(如果mbAddrN不可用,则它也不可用)
-
相邻8×8色度块可用性(ChromaArrayType = 3)
同8×8亮度块
-
相邻4×4亮度块可用性
输入:luma4×4BlkIdx
输出:mbAddrA,luma4×4BlkIdxA,mbAddrB,luma4×4BlkIdxB
步骤:
进行块扫描得到相对于当前宏块的起始偏移(x,y)
xN = x + xD; yN = y + yD
计算mbAddrN并得到(xW,yW)
计算luma4×4BlkIdxN
-
相邻4×4色度块可用性
ChromaArrayType = 1,2
输入:chroma4×4BlkIdx
输出:mbAddrA,chroma4×4BlkIdxA,mbAddrB,chroma4×4BlkIdxB
步骤:
x = InverseRasterScan( chroma4x4BlkIdx, 4, 4, 8, 0 )
y = InverseRasterScan( chroma4x4BlkIdx, 4, 4, 8, 1 )
xN = x + xD; yN = y + yD
计算mbAddrN并得到(xW,yW)
计算chroma4×4BlkIdxN
ChromaArrayType = 3
同4×4亮度块
-
相邻分区(划分子宏块)可用性
输入:mbPartIdx (当前宏块分区号/当前子宏块号)
currSubMbType(当前子宏块类型)
subMbPartIdx(当前子宏块里面的分区号)
输出:mbAddrN/mbPartIdxN/subMbPartIdxN (N=A/B/C/D);
步骤:
(1)扫描出当前宏块分割相对于宏块的偏移(x,y),即子宏块相对于宏块的偏移
(2)如果mb_type为P_8x8, P_8x8ref0 or B_8x8,扫描出当前子宏块里分区相对于子宏块的偏移(xS,yS),否则(xS,yS) = (0,0)
(3) 表中predPartWidth的确定:
mb_type = P_skip/B_skip/B_Direct_16×16:predPartWidth = 16
mb_type = B_Direct_8×8:predPartWidth = 16
mb_type = P_8×8/B_8×8(非B_Direct_8×8):
predPartWidth = SubMbPartWidth( sub_mb_type[ mbPartIdx ] )
其他:predPartWidth = MbPartWidth( mb_type )
(4) xN = x+xS+xD; yN = y+yS+yD
计算mbAddrN,得到(xW,yW)
(5)如果mbAddrN不可用,mbAddrN/mbPartIdxN/subMbPartIdxN不可用
否则: mbTypeN和相应submbtypeN(如果有)被赋给mbAddrN
宏块中,覆盖(xW,yW)的宏块分割块被指定为mbPartIdxN,相应覆盖(xW,yW)的子宏块分割块被指定为subPartIdxN,如果相应mbPartIdxN和subPartIdxN还没有被解码出来,则不可用
- 块和分区的index计算方法
输入:(xP,yP) 代表相对于该宏块(亮度/色度)的偏移
输出:
luma4×4BlkIdx = 4*(x/8) + ( (x%8)/4 ) + 8*(y/8) + 2*( (y%8) /4 )
chroma4×4BlkIdx = 2*(y/8) + (x/8) (ChromaArrayType = 1,2)
luma8×8BlkIdx = 2*(y/8) + (x/8)
mbPartIdx和subMbPartIdx
mbType为I宏块,mbPartIdx = 0 I宏块不分区,
否则,mbPartIdx = 2 * ( yP / MbPartHeight( mbType ) ) + ( xP / MbPartWidth( mbType ) )
mbType为非P_8×8,P_8×8ref0,B_8×8,B_skip,B_Direct_16×16,subMbPartIdx = 0
mbType为B_skip,B_Direct_16×16,subMbPartIdx = 2 * ( ( yP % 8 ) / 4 ) + ( ( xP % 8 ) / 4 )
mbType为P_8×8,P_8×8ref0,B_8×8,
subMbPartIdx = 2 * ( ( yP % 8 ) / SubMbPartHeight( subMbType[ mbPartIdx ] ) )
+( ( xP % 8 ) / SubMbPartWidth( subMbType[ mbPartIdx ] ) )
总结: I宏块中,只有luma4×4BlkIdx,luma8×8BlkIdx,mbPartIdx=0,宏块不分区
P/SP/B宏块,如果不是8×8 subMbPartIdx = 0,无子宏块分区
- NAL单元:网络抽象层,包含一些信息,分为NAL头和RBSP
RBSP:有各种类型,如果是编码片(或分区)数据,形成的NAL单元就是VCL NAL单元
非VCL NAL单元的NAL单元,里面的RBSP就是一些信息,比如PPS和SPS等控制信息
访问单元:包含一个完整编码图像,由一些NAL单元组成
视频序列:包含一系列访问单元,第一个必须是IDR访问单元,并且有且只有一个IDR访问单元
视频:包含一些视频序列