1. 访问单元:一系列NAL单元,包含一个primary coded picture,也可以包含一系列redundant coded pictures和一个auxiliary coded picture。
2. 逐行扫描:每个frame进行frame coding
隔行扫描:每个frame可以选择frame coding还是field coding
3. inter预测的direct预测模式分为时域和空域预测两种,都不传MV
4. layer:序列层,图像层,片层,宏块层
5. 宏块地址:非MBAFF的MB为光栅扫描序号;MBAFF的MB,每个宏块对的顶宏块为光栅扫描序号×2,底宏块为顶宏块+1.
6. 宏块位置:(x,y)表示 每右移一次,x+1
非MBAFF的宏块,下移一次y+1
MBAFF的宏块对,下移一次y+2,如果是底宏块则再y+1
7. 只有MBAFF才有宏块对(又分为帧/场宏块对) 其余分为宏块单独存在,分为帧编码和场编码
8. nal_ref_idc = 0表示该场/帧/图像不作参考使用
9. 每个slice头部有pic_parameter_set_id,确定一个图像参数集
10. 由对应图像参数集里的seq_parameter_set_id确定的序列参数集,图像参数集由slice header里面的pic_parameter_set_id确定
11. POC(picture order count) 代表IDR后解码顺序的图像计数值,或者清空所有ref pic后的图像计数值
12. run(游程)表示非零系数前0值系数的数目
13. RBSP最后,加上一个一个截止位1
14. SODB(string of data bits),代表语义元素,出现在RBSP截止位之前
SODB就是编码后的原始数据,封装成RBSP后装入NAL单元内
15. 比特流格式:NAL单元流和字节流,其中,附录B讲述NAL单元的组成和NAL语义
字节流是NAL单元加上起始前缀和一系列零字节后得到的,可以相应地提取出NAL单元来;
NAL单元流由NAL单元构成。
16. 辅助编码图片用于阿尔法混合(透明度混合)
17. 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
18. 顺序:Y->Cb->Cr
19. slice:非MBAFF,是一系列宏块;MBAFF,是一系列宏块对
20. separate_colour_plane_flag = 1时,每个分量被分别调入各自的slice(由colour_plane_id区别);也就是说需要三个slice去储存每个原来一个slice的三个分量
21. 宏块分割和扫描顺序
见标准Figure6-9 6-10 6-11
每个4×4或8×8的luma block则是raster scan顺序
22. 反向扫描过程
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) |
23. 宏块分割 得到值MbPartWidth MbPartHeight
对应P_8×8,P_8×8ref0或者B_8×8,有SubMbPartWidth和SubMbPartHeight
24. 反向宏块分割扫描
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索引
25. 块扫描(得到每个分块相对于该宏块起点的起始偏移(x,y))
1) 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 ) |
2) 4×4chroma
当ChromaArrayType = 3时使用,同4×4luma
3) 8×8luma
x = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 0 ) y = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 1 ) |
4) 8×8chroma
当ChromaArrayType = 3时使用,同8×8luma
26. 宏块地址可用性---------------获得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时不可用 |
27. 相邻宏块,块,分割可用性的推导过程
N | xD | yD |
A | -1 | 0 |
B | 0 | -1 |
C | predPartWidth | -1 |
D | -1 | -1 |
MbaffFrameFlag = 0时
1) 由相对于当前宏块左上角位置的偏移(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等等写入该结构体
2) 相邻宏块可用性
输出为mbAddrA和mbAddrB
xN = xD,yN = yD
计算mbAddrN
3) 相邻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不可用,则它也不可用)
4) 相邻8×8色度块可用性(ChromaArrayType = 3)
同8×8亮度块
5) 相邻4×4亮度块可用性
输入:luma4×4BlkIdx
输出:mbAddrA,luma4×4BlkIdxA,mbAddrB,luma4×4BlkIdxB
步骤:
进行块扫描得到相对于当前宏块的起始偏移(x,y)
xN = x + xD; yN = y + yD
计算mbAddrN并得到(xW,yW)
计算luma4×4BlkIdxN
6) 相邻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亮度块
7) 相邻分区(划分子宏块)可用性
输入: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还没有被解码出来,则不可用
28. 块和分区的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,无子宏块分区
29. NAL单元:网络抽象层,包含一些信息,分为NAL头和RBSP
RBSP:有各种类型,如果是编码片(或分区)数据,形成的NAL单元就是VCL NAL单元
非VCL NAL单元的NAL单元,里面的RBSP就是一些信息,比如PPS和SPS等控制信息
访问单元:包含一个完整编码图像,由一些NAL单元组成
视频序列:包含一系列访问单元,第一个必须是IDR访问单元,并且有且只有一个IDR访问单元
视频:包含一些视频序列