---------------------------------------------------------------------------------------------------------------------------
说明:本文档是基于码流文件ducks.264。文档中只有括号里面的参数才会编入码流,如
nC=0;
(coeff_token):ce(v)=1(0,0)
只有coeff_token在码流中有,nC只是为了读者方便。进制。
Writed by Bnian
---------------------------------------------------------------------------------------------------------------------------
SPS层句法
00000000 00 00 00 01 67 42 0028 da 01 40 16 e4 00 00 00
(67 42 00 28)
位(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
100100(da 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
(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),宽度
),高度
(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
000 10000000(68 ce 38 80)
位(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),
(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帧
100 00100111(65 88 84 27)
位(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
0(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图像的片
10110 (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
(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),水平运动矢量----mvd和mv是不同滴
(mvd_10[mbPartIdx=1][0][compIdx=1]):se(v)=010(1),垂直运动矢量-------------------
个色度信号全零);
(Mb_qp_delta): se(v)=1(0), QP=28+0=28
残差块CAVLC编码:16*16宏块先分解成4个8*8块(个8*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)
(0eaa 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
:(Level_prefix(1)):ce(v)= 01(1) Suffixlength=1
由CAVLC残差句法可知,因为以下条件成立:
i==TrailingOnes(coeff_token)&&TrailingOnes(coeff_token)<3
所以levelCode+=2=2;
Level(1)=-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
:(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
(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
:(Level_prefix(0)):ce(v)=01(1) Suffixlength=1
Level(0)=-1
Zeroleft=(Total_zeros):ce(v)=101(5)
(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
:(Level_prefix(2)):ce(v)=01(1) Suffixlength=1
Level(2)=-1
(55 fa )
:(Level_prefix(1)):ce(v)=01(1)
(Level_suffix):u(v)=0(0) Suffixlength=1
Level(1)=2
:(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
1(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)
1(76 b3 )
Suffixlength=0
:(Level_prefix(2)):ce(v)=01(1) Suffixlength=0
Level(2)=-2
:(Level_prefix(1)):ce(v)=1(0)
(Level_suffix):u(v)=1(1) Suffixlength=1
Level(1)=-1
:(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)是:
01(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)
(28 65)
(Trailing_ones_sign_flag(0)):u(1)=0(+)
Zeroleft=(Total_zeros):ce(v)=01 (2)
综上所述,UDC2X2的矩阵A(反zig-zag)是:
页,反量化过程参考《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
:(Level_prefix(0)):ce(v)=01(1) Suffixlength=1
Level(0)=-1
(ab 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
1(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
(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),垂直运动矢量
10000(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块都有非零系数,色度信号Cr和Cb全零);
(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变换,这一点在其他类型中是没有的