您的位置:首页 > 其它

H.264标准----概念和定义

2016-06-07 12:56 260 查看
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访问单元
视频:包含一些视频序列
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: