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

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.       宏块地址:非MBAFFMB为光栅扫描序号;MBAFFMB,每个宏块对的顶宏块为光栅扫描序号×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/SubHeightCc_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×48×8luma 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:标志

返回的单位是像素,本宏块的相对像素起始(xy)

宏块       => 图像//

宏块分割   => 宏块

子宏块分割 => 子宏块

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×8P_8×8ref0或者B_8×8,有SubMbPartWidthSubMbPartHeight

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×1616×88×168×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宏块分为48×8的块,再把8×8的块分成44×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 = MbWdithCmaxH = 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)       相邻宏块可用性

输出为mbAddrAmbAddrB

xN = xD,yN = yD

计算mbAddrN

 

3)       相邻8×8亮度块可用性

输入:luma8×8BlkIdx,当前宏块的8×8亮度块序号

输出:mbAddrA(可能等于CurrMbAddr,也可能是左边一个MbAddr)luma8×8BlkIdxAmbAddrBluma8×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

输出:mbAddrAluma4×4BlkIdxAmbAddrBluma4×4BlkIdxB

步骤:

进行块扫描得到相对于当前宏块的起始偏移(x,y)

xN = x + xD; yN = y + yD

计算mbAddrN并得到(xW,yW)

计算luma4×4BlkIdxN

 

6)       相邻4×4色度块可用性

ChromaArrayType = 12

  输入:chroma4×4BlkIdx

输出:mbAddrAchroma4×4BlkIdxAmbAddrBchroma4×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_typeP_8x8, P_8x8ref0 or B_8x8,扫描出当前子宏块里分区相对于子宏块的偏移(xS,yS),否则(xS,yS) = (0,0)

   (3) 表中predPartWidth的确定:

      mb_type = P_skip/B_skip/B_Direct_16×16predPartWidth = 16

      mb_type = B_Direct_8×8predPartWidth = 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,如果相应mbPartIdxNsubPartIdxN还没有被解码出来,则不可用

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)

 

mbPartIdxsubMbPartIdx

mbTypeI宏块,mbPartIdx = 0   I宏块不分区,

否则,mbPartIdx = 2 * ( yP / MbPartHeight( mbType ) ) + ( xP / MbPartWidth( mbType ) )

 

mbType为非P_8×8P_8×8ref0B_8×8B_skipB_Direct_16×16subMbPartIdx = 0

mbTypeB_skipB_Direct_16×16subMbPartIdx = 2 * ( ( yP % 8 ) / 4 ) + ( ( xP % 8 ) / 4 )

mbTypeP_8×8P_8×8ref0B_8×8

subMbPartIdx = 2 * ( ( yP % 8 ) / SubMbPartHeight( subMbType[ mbPartIdx ] ) )

+( ( xP % 8 ) / SubMbPartWidth( subMbType[ mbPartIdx ] ) )

 

总结: I宏块中,只有luma4×4BlkIdxluma8×8BlkIdxmbPartIdx=0,宏块不分区

       P/SP/B宏块,如果不是8×8   subMbPartIdx = 0,无子宏块分区

 

29.   NAL单元:网络抽象层,包含一些信息,分为NAL头和RBSP

RBSP:有各种类型,如果是编码片(或分区)数据,形成的NAL单元就是VCL NAL单元

VCL NAL单元的NAL单元,里面的RBSP就是一些信息,比如PPSSPS等控制信息

访问单元:包含一个完整编码图像,由一些NAL单元组成

视频序列:包含一系列访问单元,第一个必须是IDR访问单元,并且有且只有一个IDR访问单元

视频:包含一些视频序列

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值