h264码流分析

---------------------------------------------------------------------------------------------------------------------------

说明:本文档是基于码流文件ducks.264。文档中只有括号里面的参数才会编入码流,如

nC=0

(coeff_token):ce(v)=1(0,0)

只有coeff_token在码流中有,nC只是为了读者方便。ce(v)=1(0,0)1代表码流中的字符串,括号里面是10进制。

                                                                                                                                       Writed by Bnian

---------------------------------------------------------------------------------------------------------------------------

 

SPS层句法

00000000   00 00 00 01 67 42 0028 da 01 40 16 e4 00 00 00  

01100111 01000010 00000000 0010100067 42 00 28

禁止0位(forbidden_zero_bit):         f(1)=0,应为0;

NAL参考ID内容(nal_ref_idc):        u(2)=11(3)NALU最高优先级

nal_unit_type):         u(5)=00111(7)SPS,序列参数集(seq_parameter_set

(profile_idc):      u(8)=01000010(66),基本简表

set0):        u(1)=0,可以不遵从相关简表规定

set1):        u(1)=0,可以不遵从相关简表规定

set2):        u(1)=0,可以不遵从相关简表规定

set3):        u(1)=0,可以不遵从相关简表规定

reserved_zero_4bits):     u(4)=0000

level_idc):         u(8)=00101000(40),级别号4.0,处于baseline

 

11011010 00000001 01000000 00010110 11100100da 01 40 16 e4

seq_parameter_set_id): ue(v)=1(0),序列参数集ID=0

log2_max_frame_num_minus4):    ue(v)=1(0),最多帧数=2^4=16

pic_order_cnt_type):       ue(v)=011(2),图像顺序类型为2

num_ref_frames):   ue(v)=010(1),参考帧的最大数

gaps_in_frame_num_value_allowed_flag):    u(1)=0(0),帧数差异标记

(pic_width_in_mbs_minus1):   ue(v)=0000001010000(79)((79+1)*16=1280),宽度

pic_height_in_map_units_minus1):ue(v)=00000101101(44)(44+1)*16=720),高度

frame_mbs_only_flag):   u(1)=1(1),只是帧宏块,没有场宏块

(direct_8x8_inference_flag):    u(1)=1(1),

(frame_cropping_flag):     u(1)=0(0),不存在帧剪切偏移参数

(vui_parameters_present_flag):       u(1)=0(0),没有VUI信息,默认矩阵系数2

(rbsp_trailing_bits):  100

PPS层句法

00000001 01 68 ce38 80 00 00 00 01 65 88 84 27 23 c5 e5 

01101000 11001110 00111000 10000000(68 ce 38 80)

禁止0位(forbidden_zero_bit):         f(1)=0,应为0;

NAL参考ID内容(nal_ref_idc):        u(2)=11(3)NALU最高优先级

nal_unit_type):         u(5)=01000(8)PPS,图像参数集(pic_parameter_set

pic_parameter_set_id):  ue(v)=1(0),图像参数集ID=0

seq_parameter_set_id): ue(v)=1(0),序列参数集ID=0

entropy_coding_mode_flag):  u(1)=0(0)CAVLC

pic_order_present_flag):         u(1)=0(0)

num_slice_groups_minus1):   ue(v)=1(0)

num_ref_idx_l0_active_minus1):    ue(v)=1(0)

num_ref_idx_l1_active_minus1):    ue(v)=1(0)

weighted_pred_flag):      u(1)=0(0)

 

00111000

weighted_bipred_idc):     u(2)=00(0)

pic_init_qp_minus26):     se(v)=1(0)

pic_init_qs_minus26):      se(v)=1(0)

chroma_qp_index_offset):       se(v)=1(0)

(deblocking_filter_control_present_flag):        u(1)=0(0),

(constrained_intra_pred_flag):         u(1)=0(0),

(redundant_pic_cnt_present_flag): u(1)=0(0),

(rbsp_trailing_bits):  100000000

 

I

01100101 10001000 10000100 00100111(65 88 84 27)

禁止0位(forbidden_zero_bit):         f(1)=0,应为0;

NAL参考ID内容(nal_ref_idc):        u(2)=11 (3)NALU最高优先级

nal_unit_type):u(5)=00101(5)IDR图像的片

first_mb_in_slice):   ue(v)=1(0)

slice_type):       ue(v)=0001000(7)I条带,I slice

(pic_parameter_set_id):  ue(v)=1(0),

frame_num:u(v)=0000(0)

(Idr_pic_id):ue(v)=1(0)

(no_output_of_prior_pics_flag):u(1)=0

(Long_term_reference_flag):u(1)=0

(slice_qp_delta):        se(v)=00100(2),QP=26+2=28

 

P(ducks.Frame2.Mb2)

0003d310   f0 00 00 00 01 41 9a 60 96 db 41 fe 0e aa 50 b6       

01000001(41)

禁止0位(forbidden_zero_bit):         f(1)=0,应为0;

NAL参考ID内容(nal_ref_idc):        u(2)=10(2)NALU优先级

nal_unit_type):         u(5)=00001(1),不分区、非IDR图像的片

 

10011010 01100000 10010110 (9a,60,96)

片头句法

(first_mb_in_slice):   ue(v)=1(0),

slice_type):       ue(v)=00110(5)I条带,P slice

pic_parameter_set_id):  ue(v)=1(0)

frame_num):    u(v)=0011(3)

 (num_ref_idx_active_override_flag): u(1)=0,不重载参考图像

ref_pic_list_recordering_flag_10: u(1)=0,不重排序

adaptive_ref_pic_marking_mode_flag: u(1)=0, 先入先出(FIFO:使用滑动窗的机制,先入先出,在这种模式下没有办法对长期参考帧进行操作

slice_qp_delta):        se(v)=00100(2)QP=26+2=28

宏块层句法

 (mb_skip_run): ue(v)=1(0),不跳

P_L0_L0_8x16

 (mb_type):ue(v)=011(2) , 预测模式为P_L0_L0_8x16

11011011 01000001 11111110(db 41 fe )

宏块的第一个8x16:

mvd_10[mbPartIdx=0][0][compIdx=0]:se(v)=011(-1),水平运动矢量

mvd_10[mbPartIdx=0][0][compIdx=1]:se(v)=011(-1),垂直运动矢量

宏块的第二个8x16:

mvd_10[mbPartIdx=1][0][compIdx=0]:se(v)= 011 (-1),水平运动矢量----mvdmv是不同滴

mvd_10[mbPartIdx=1][0][compIdx=1]:se(v)=010(1),垂直运动矢量-------------------

 (Coded_block_pattern):me(v)=000011111(45),CBP=15,CodeBlockPatternLuma=CBP%16=13,CodeBlockPatternLuma=CBP/16=238*8块都有非零系数,1个色度信号全零);

(Mb_qp_delta): se(v)=1(0), QP=28+0=28

残差块CAVLC编码:16*16宏块先分解成4个8*8块(红(0)绿(1)棕(2)蓝(3),每个8*8块再分4个4*4块。然后在对每一个4*4块进行编码(看<THE H.264 ADVANCED第125页>):(Coded_block_pattern6位,低4位分别指出48*8块中是否有非零系数,高2位指出色度信号Cr和Cb是否有非零系数;coeff_token指出每个4*4块非零系数的个数)

                   0  1  4   5

                   2 3  6   7

8  9  12  13

10 11  14 15

残差块句法

先对luma16*16进行编码,在对色度进行编码

块8x8(0):

块4x4(0):

nC=0;

(coeff_token):ce(v)=1(0,0)

块4x4(1):

nA(块4*4(0))=0,nC=Na=0;

 (coeff_token):ce(v)=1(0,0)

00001110 10101010 01010000 101101100eaa 50 b6)

块4x4(2):

  nB(块4*4(0))=0 ,nC= nB=0;

     (coeff_token):ce(v)=00000111 (TotalCoff(coeff_token)=2,TrailingOnes(Coeff_token)=0)

                                                 Suffixlength=0

非零系数1:(Level_prefix(1):ce(v)= 01(1)  Suffixlength=1

  由CAVLC残差句法可知,因为以下条件成立:

i==TrailingOnes(coeff_token)&&TrailingOnes(coeff_token)<3

所以levelCode+=2=2; 

            Level(1)=-2

非零系数2:(Level_prefix(0):ce(v)=01(1)    

                 Level_suffix:u(v)=0(0)       

                   Level(0)=2

Zeroleft=(Total_zeros):ce(v)=101(2)

(Run _before(1):ce(v)= 00(2)    zeroleft=0

Run _before(0)=0,不编码

     综上所述,块4x4(2)的矩阵A(反zig-zag)是:

              

     至于怎么变成H264visa软件里面的coef,留待高手去考究,我就不写了。

  块4x4(3):

nB(块4*4(1))=0,nA(块4*4(2))=2,nC=(nB+nA+1)>>1=1.5,

(coeff_token):ce(v)=1 (0,0)  

因为CodeBlockPatternLuma=CBP%16=13, 二进制是1101,所以块8x8(1)为全0         

块8x8(2):

块4x4(8):

nB(块4*4(2))=2,nC=nB=2,

(coeff_token):ce(v)=0100(4,3)

(Trailing_ones_sign_flag(3)):u(1)=0(+)

(Trailing_ones_sign_flag(2)):u(1)=0(+)

(Trailing_ones_sign_flag(1)):u(1)=1(-)

                                               Suffixlength=0

非零系数1:(Level_prefix(0):ce(v)=01(1)  Suffixlength=1

Level(0)=-1

Zeroleft=(Total_zeros):ce(v)=101(5)

(Run_before(3)):ce(v)= 10(1)    zeroleft=4

0003d320    44 ed 71 3d 55 fa f5 07 76 b3 41 b5 28 65 ab fe 

01000100 11101101(44 ed )

(Run_before(2)):ce(v)=01(2)     zeroleft=2

(Run _before(1)):ce(v)=00(2)     zeroleft=0

必然有Run_before(0)=0,但不编码

综上所述,块4x4(8)的矩阵A(反zig-zag)是:

 

块4x4(9):

nA(块4*4(8))=4, nB(块4*4(3))=0,nC=(nA+nB+1)>>2=2.5,

 (coeff_token):ce(v)=0100 (4,3)

(Trailing_ones_sign_flag(3)):u(1)=1(-)

(Trailing_ones_sign_flag(2)):u(1)=1(-)

(Trailing_ones_sign_flag(1)):u(1)=1(-)

                                               Suffixlength=0

非零系数1:(Level_prefix(0):ce(v)=01(1)  Suffixlength=1

Level(0)=-1

Zeroleft=(Total_zeros):ce(v)=101(5)

01110001 00111101(71 3d)

 (Run_before(3)):ce(v)= 011(2)    zeroleft=3

(Run_before(2)):ce(v)=10(1)     zeroleft=2

(Run _before(1)):ce(v)=00(2)     zeroleft=0

必然有Run_before(0)=0,但不编码

综上所述,块4x4(9)的矩阵A(反zig-zag)是:

 

块4x4(10):

nB(块4*4(8))=4 ,nC=nB=4,

(coeff_token):ce(v)=1001(6,3)

(Trailing_ones_sign_flag(5)):u(1)=1(-)

(Trailing_ones_sign_flag(4)):u(1)=1(-)

(Trailing_ones_sign_flag(3)):u(1)=1(-)

                                               Suffixlength=0

非零系数1:(Level_prefix(2):ce(v)=01(1)  Suffixlength=1

            Level(2)=-1

01010101 11111010(55 fa )

 

非零系数2:(Level_prefix(1):ce(v)=01(1)    

                 Level_suffix:u(v)=0(0)         Suffixlength=1

                   Level(1)=2

非零系数3:(Level_prefix(0):ce(v)= 1(0)    

                  Level_suffix:u(v)=0(0)        Suffixlength=1

                   Level(0)=1

Zeroleft=(Total_zeros):ce(v)=101 (4)

(Run _before(5)):ce(v)= 11(0)    zeroleft=4

(Run_before(4)):ce(v)=11(0)     zeroleft=4

(Run _before(3)):ce(v)= 10(1)    zeroleft=3

(Run _before(2)):ce(v)=10(1)     zeroleft=2

11110101 00000111(f5 07)

(Run _before(1)):ce(v)= 1(0)    zeroleft=2

Run _before(0)=2,不编码

综上所述,块4x4(10)的矩阵A(反zig-zag)是:

              

块4x4(11):

nB(块4*4(10))=6, nA块4*4(9))=4 ,nC=(nB+Nb+1)>>1=5.5,

(coeff_token):ce(v)= 1110 (1,1)

 (Trailing_ones_sign_flag(0)):u(1)=1(-)

Zeroleft=(Total_zeros):ce(v)=010(2)

Run _before(0))=2,不编码  

综上所述,块4x4(11)的矩阵A(反zig-zag)是:

              

块8x8(3):

块4x4(12):

nA(块4*4(9))=4,nB(块4*4(6))=0,nC=(nA+Nb+1)>>1=2.5,

 (coeff_token):ce(v)=0000111(3,0)

01110110 10110011(76 b3 )

Suffixlength=0

非零系数1:(Level_prefix(2):ce(v)=01(1)     Suffixlength=0

           Level(2)=-2

非零系数2:(Level_prefix(1):ce(v)=1(0)    

                  Level_suffix:u(v)=1(1)         Suffixlength=1

                   Level(1)=-1

非零系数3:(Level_prefix(0):ce(v)= 01(1)    

                 Level_suffix:u(v)=1(1)       

                    Level(0)=-2

Zeroleft=(Total_zeros):ce(v)=0101(0) 

综上所述,块4x4(12)的矩阵A(反zig-zag)是:

              

块4x4(13):

nA(块4*4(12))=3, nB(块4*4(7))=0,nC=(nB+Nb+1)>>1=2,

 (coeff_token):ce(v)=10(1,1)

 (Trailing_ones_sign_flag(0)):u(1)=0(+)

Zeroleft=(Total_zeros):ce(v)=1 (0)

    综上所述,块4x4(13)的矩阵A(反zig-zag)是:

              

01000001 10110101(41 b5)

块4x4(14):

nA(块4*4(11))=1, nB(块4*4(12))=3,nC=(nB+Nb+1)>>1=2.5,

(coeff_token):ce(v)=10(1,1)

(Trailing_ones_sign_flag(0)):u(1)=1(-)

Zeroleft=(Total_zeros):ce(v)=0000011 (9)

    综上所述,块4x4(14)的矩阵A(反zig-zag)是:

              

块4x4(15):

nA(块4*4(14))=1, nB(块4*4(13))=1,nC=(nB+Na+1)>>1=1.5,

(coeff_token):ce(v)=01(1,1)

 (Trailing_ones_sign_flag(0)):u(1)=1(-)

Zeroleft=(Total_zeros):ce(v)=010(2)

    综上所述,块4x4(15)的矩阵A(反zig-zag)是:

              

Chroma DC

因为4:2:0,所以nC=-1,

(coeff_token):ce(v)=1 (1,1)

00101000 0110010128 65

(Trailing_ones_sign_flag(0)):u(1)=0(+)

Zeroleft=(Total_zeros):ce(v)=01 (2)

    综上所述,UDC2X2的矩阵A(反zig-zag)是:

              

此处先对A进行IDCT,然后再进行反量化(参考书《THE H.264 ADVANCEDVIDEO COMPRESSION STANDARD》)第183页,反量化过程参考《H.264变换和量化的分析。pdf》楼剑,陆亮

(coeff_token):ce(v)=01 (0,0)

综上所述,V  DC2X2的矩阵A(反zig-zag)是:

              

Chroma AC

U:

块4x4(18)

nC=0,

 (coeff_token):ce(v)=000011(4,3)

(Trailing_ones_sign_flag(3)):u(1)=0(+)

(Trailing_ones_sign_flag(2)):u(1)=0(+)

(Trailing_ones_sign_flag(1)):u(1)=1(-)

Suffixlength=0

非零系数1:(Level_prefix(0):ce(v)=01(1)     Suffixlength=1

           Level(0)=-1

10101011 11111110ab fe

Zeroleft=(Total_zeros):ce(v)=101(5) (特别注意,此处并没有算左上角哪一位)

(Run _before(3)):ce(v)= 010(3)    zeroleft=2

(Run_before(2)):ce(v)=1(0)     zeroleft=2

(Run _before(1)):ce(v)= 1(0)    zeroleft=2

Run _before(0)=2,不编码

 

综上所述,块4x4(18)的矩阵A(反zig-zag)是(已经把DC部分写进去了):

              

块4x4(19)

nA(块4*4(18))=4,nC=(nA)=4

(coeff_token):ce(v)=1111(0,0)

综上所述,块4x4(19)的矩阵A(反zig-zag)是(已经把DC部分写进去了):

              

块4x4(20)

nB(块4*4(18))=4,nC=(nB)=4

(coeff_token):ce(v)=1110(1,1)

0003d330    84 7ff2 d2 a2 9c 87 54 7b 43 30 44 b4 bc 94 1a 

10000100 01111111(84 7f)

(Trailing_ones_sign_flag(0)):u(1)=1(-)

Zeroleft=(Total_zeros):ce(v)=000010(8)(特别注意,此处并没有算左上角哪一位)

综上所述,块4x4(20)的矩阵A(反zig-zag)是(已经把DC部分写进去了):

              

块4x4(21)

nB(块4*4(19))=0,nB(块4*4(20))=1,nC=(nB+Na+1)>>2=1

(coeff_token):ce(v)=001(2,2)

 (Trailing_ones_sign_flag(1)):u(1)=1(-)

(Trailing_ones_sign_flag(0)):u(1)=1(-)

Zeroleft=(Total_zeros):ce(v)=111(0)(特别注意,此处并没有算左上角哪一位)

综上所述,块4x4(21)的矩阵A(反zig-zag)是(已经把DC部分写进去了):

              

 

P_ 8x8ref0(ducks.Frame2.Mb2)

(mb_skip_run): ue(v)=1(0),不跳

(mb_type)ue(v)=00101(4) , 预测模式为P_8x8ref0

11101001 10011000 11101101 01010110(e9 98 ed56 42 bb 63)

每个块8X8的预测类型:

(sub_mb_type(0)):ue(v)=011(2),预测模式为P_L0_4X8

(sub_mb_type(1)): ue(v)=1(0), 预测模式为P_L0_8X8

(sub_mb_type(2)) :ue(v)=010(1), 预测模式为P_L0_8X4

(sub_mb_type(3)) :ue(v)=011(1), 预测模式为P_L0_4X8

块8x8(0):

mvd_10[mbPartIdx=0][submbpartidx=0][compIdx=0]:se(v)=00110(3),水平运动矢量

mvd_10[mbPartIdx=0][0][compIdx=1]:se(v)=00111(-3),垂直运动矢量

(mvd_10[mbPartIdx=0][1][compIdx=0]):se(v)=011(-1),水平运动矢量

mvd_10[mbPartIdx=0][1][compIdx=1]:se(v)=010(1),垂直运动矢量

块8x8(1):

mvd_10[mbPartIdx=1][0][compIdx=0]:se(v)=1(0),水平运动矢量

mvd_10[mbPartIdx=1][0][compIdx=1]:se(v)=010(1),垂直运动矢量

块8x8(2):

mvd_10[mbPartIdx=2][0][compIdx=0]:se(v)=1(0),水平运动矢量

mvd_10[mbPartIdx=2][0][compIdx=1]:se(v)=1(0),垂直运动矢量

01000010 10111011 01100011 00110000(42 bb 6330)

mvd_10[mbPartIdx=2][1][compIdx=0]:se(v)=00100(2),水平运动矢量

mvd_10[mbPartIdx=2][1][compIdx=1]:se(v)=00101(-2),垂直运动矢量

块8x8(3):

mvd_10[mbPartIdx=3][0][compIdx=0]:se(v)=011(-1),水平运动矢量

mvd_10[mbPartIdx=3][0][compIdx=1]:se(v)=1(0),垂直运动矢量

mvd_10[mbPartIdx=3][1][compIdx=0]:se(v)=011(-1),水平运动矢量

mvd_10[mbPartIdx=3][1][compIdx=1]:se(v)=011(-1),垂直运动矢量

(Coded_block_pattern):me(v)=0001100(15),CBP=15,CodeBlockPatternLuma=CBP%16=15,CodeBlockPatternLuma=CBP/16=0(每个8*8块都有非零系数,色度信号CrCb全零);

(Mb_qp_delta):se(v)=1(0), QP=28+0=28

下面主要来讲讲在宏块层句法中,各种类型宏块(intra_4x4,intra_16x16,p_8x8ref0和非p_8x8ref0的inter)中的区别:

1、   sub_mb_pred(mb_type)和mb_pred(mb_type)的选择:只有p_8x8ref0时,选择sub_mb_pred(mb_type)。p_8x8ref0类型:16x16块分为4个8x8块,然后每个8x8块还会细分成更小的块。所以在sub_mb_pred(mb_type)中首先要给出每一个更小的块的sub_mb_type,然后给出每一个更小的块的运动矢量(这步和mb_pred(mb_type)是一样的)。而当选择mb_pred(mb_type)时,若宏块是intra类型时,就不会有运动矢量的说法。而是给出了另外几个参数:

 

2、   残差句法中的特殊情况:

若宏块类型是intre6x6时,先要对亮度DC进行CAVLC变换,这一点在其他类型中是没有的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2014-11-23 18:08  Bnian  阅读(1361)  评论(0编辑  收藏  举报