-
訪問單元:一系列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訪問單元
視頻:包含一些視頻序列