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访问单元

视频:包含一些视频序列

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