H.264標準----概念和定義

原文鏈接:https://blog.csdn.net/samssm/article/details/51602928
  1.   訪問單元:一系列NAL單元,包含一個primary coded picture,也可以包含一系列redundant coded pictures和一個auxiliary coded picture。
    
  2.   逐行掃描:每個frame進行frame coding
    

隔行掃描:每個frame可以選擇frame coding還是field coding

  1.   inter預測的direct預測模式分爲時域和空域預測兩種,都不傳MV
    
  2.   layer:序列層,圖像層,片層,宏塊層
    
  3.   宏塊地址:非MBAFF的MB爲光柵掃描序號;MBAFF的MB,每個宏塊對的頂宏塊爲光柵掃描序號×2,底宏塊爲頂宏塊+1.
    
  4.   宏塊位置:(x,y)表示 每右移一次,x+1
    

非MBAFF的宏塊,下移一次y+1

MBAFF的宏塊對,下移一次y+2,如果是底宏塊則再y+1

  1.   只有MBAFF纔有宏塊對(又分爲幀/場宏塊對) 其餘分爲宏塊單獨存在,分爲幀編碼和場編碼
    
  2.   nal_ref_idc = 0表示該場/幀/圖像不作參考使用
    
  3.   每個slice頭部有pic_parameter_set_id,確定一個圖像參數集
    
  4. 由對應圖像參數集裏的seq_parameter_set_id確定的序列參數集,圖像參數集由slice header裏面的pic_parameter_set_id確定

  5. POC(picture order count) 代表IDR後解碼順序的圖像計數值,或者清空所有ref pic後的圖像計數值

  6. run(遊程)表示非零係數前0值係數的數目

  7. RBSP最後,加上一個一個截止位1

  8. SODB(string of data bits),代表語義元素,出現在RBSP截止位之前

SODB就是編碼後的原始數據,封裝成RBSP後裝入NAL單元內

  1. 比特流格式:NAL單元流和字節流,其中,附錄B講述NAL單元的組成和NAL語義

字節流是NAL單元加上起始前綴和一系列零字節後得到的,可以相應地提取出NAL單元來;

NAL單元流由NAL單元構成。

  1. 輔助編碼圖片用於阿爾法混合(透明度混合)

  2. 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

  1. 順序:Y->Cb->Cr

  2. slice:非MBAFF,是一系列宏塊;MBAFF,是一系列宏塊對

  3. separate_colour_plane_flag = 1時,每個分量被分別調入各自的slice(由colour_plane_id區別);也就是說需要三個slice去儲存每個原來一個slice的三個分量

  4. 宏塊分割和掃描順序

見標準Figure6-9 6-10 6-11

每個4×4或8×8的luma block則是raster scan順序

  1. 反向掃描過程

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)
  1. 宏塊分割 得到值MbPartWidth MbPartHeight

對應P_8×8,P_8×8ref0或者B_8×8,有SubMbPartWidth和SubMbPartHeight

  1. 反向宏塊分割掃描

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索引

  1. 塊掃描(得到每個分塊相對於該宏塊起點的起始偏移(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 )

  1.     4×4chroma
    

當ChromaArrayType = 3時使用,同4×4luma

  1.     8×8luma
    

x = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 0 )

y = InverseRasterScan( luma8x8BlkIdx, 8, 8, 16, 1 )

  1.     8×8chroma
    

當ChromaArrayType = 3時使用,同8×8luma

  1. 宏塊地址可用性---------------獲得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時不可用

  1. 相鄰宏塊,塊,分割可用性的推導過程

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等等寫入該結構體

  1.   相鄰宏塊可用性
    

輸出爲mbAddrA和mbAddrB

xN = xD,yN = yD

計算mbAddrN

  1.   相鄰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不可用,則它也不可用)

  1.   相鄰8×8色度塊可用性(ChromaArrayType = 3)
    

同8×8亮度塊

  1.   相鄰4×4亮度塊可用性
    

輸入:luma4×4BlkIdx

輸出:mbAddrA,luma4×4BlkIdxA,mbAddrB,luma4×4BlkIdxB

步驟:

進行塊掃描得到相對於當前宏塊的起始偏移(x,y)

xN = x + xD; yN = y + yD

計算mbAddrN並得到(xW,yW)

計算luma4×4BlkIdxN

  1.   相鄰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亮度塊

  1.   相鄰分區(劃分子宏塊)可用性
    

輸入: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還沒有被解碼出來,則不可用

  1. 塊和分區的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,無子宏塊分區
  1. NAL單元:網絡抽象層,包含一些信息,分爲NAL頭和RBSP

RBSP:有各種類型,如果是編碼片(或分區)數據,形成的NAL單元就是VCL NAL單元

非VCL NAL單元的NAL單元,裏面的RBSP就是一些信息,比如PPS和SPS等控制信息

訪問單元:包含一個完整編碼圖像,由一些NAL單元組成

視頻序列:包含一系列訪問單元,第一個必須是IDR訪問單元,並且有且只有一個IDR訪問單元

視頻:包含一些視頻序列

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章