1片层句法(不分区)
句法 |
C |
Desc |
slice_layer_without_partitioning_rbsp(){ |
|
|
slice_header() |
2 |
|
slice_data() /* all categories of slice_data() syntax */ |
2|3|4 |
|
rbsp_slice_trailing_bits() |
2 |
|
} |
|
|
表6
2 片层A分区句法
句法 |
C |
Desc |
slice_data_partition_a_layer_rbsp(){ |
|
|
slice_header() |
2 |
|
slice_id |
2 |
ue(v) |
slice_data() /* only category 2 parts of slice_data() syntax */ |
2 |
|
rbsp_slice_trailing_bits() |
2 |
|
} |
|
|
表7
3 片层B分区句法
句法 |
C |
Desc |
slice_data_partition_b_layer_rbsp(){ |
|
|
slice_id |
3 |
ue(v) |
if(redundant_pic_cnt_present_flag) |
|
|
redundant_pic_cnt |
3 |
|
slice_data() /* only category 3 parts of slice_data() syntax */ |
3 |
ue(v) |
rbsp_slice_trailing_bits() |
3 |
|
} |
|
|
表8
4 片层C分区句法
句法 |
C |
Desc |
slice_data_partition_c_layer_rbsp(){ |
|
|
slice_id |
4 |
ue(v) |
if(redundant_pic_cnt_present_flag) |
|
|
redundant_pic_cnt |
4 |
|
slice_data() /* only category 4 parts of slice_data() syntax */ |
4 |
ue(v) |
rbsp_slice_trailing_bits() |
4 |
|
} |
|
|
表9
5 拖尾(trailing bits)句法
句法 |
C |
Desc |
rbsp_trailing_bits(){ |
|
|
rbsp_stop_one_bit /* equal to 1 */ |
All |
f(1) |
while(!byte_aligned()) |
|
|
rbsp_alignment_zero_bit /* equal to 0 */ |
All |
f(1) |
} |
|
|
表10
6 片头(Slice header)句法
句法 |
C |
Desc |
slice_header(){ |
|
|
first_mb_in_slice /* 片中的第一个宏块地址,片通过这个句法元素来标定它自己的地址。在帧场自适应模式下,宏块都是成对出现,这时本句法元素表示的是第几个宏块对,对应的第一个宏块的真实地址应该是:2*first_mb_in_slice */ |
2 |
ue(v) |
slice_type /* 片的类型,见表12 */ |
2 |
ue(v) |
pic_parameter_set_id /* 引用的图像集索引 */ |
2 |
ue(v) |
frame_num /* 每个参考帧都有一个连续的frame_num作为它们的标识,它指明了各图像的解码顺序。非参考帧也有,但没有意义。 */ |
2 |
u(v) |
if(!frame_mbs_only_flag){ |
|
|
field_pic_flag /* 片层中标识图像编码模式的唯一一个元素,详细描述,见图3 */ |
2 |
u(1) |
if(filed_pic_flag) |
|
|
bottom_field_flag /* 1:底场,0:顶场 */ |
2 |
u(1) |
} |
|
|
if(nal_unit_type==5) |
|
|
idr_pic_id /* IDR图像标识,不同的IDR图像有不同的IDR值。场模式下,IDR帧的两个场有相同的idr_pic_id值,[0..65535] */ |
2 |
ue(v) |
if(pic_order_cnt_type==0){ |
|
|
pic_order_cnt_lsb/* 在poc的第一种算法中,显示传递poc的值,u(v)中,v=log2_max_pic_order_cnt_lsb_minus4+4 */ |
2 |
u(v) |
if(pic_order_present_flag && !field_pic_flag) |
|
|
delta_pic_order_cnt_bottom /* 如果是在场模式下,场对中的两个场都各自被构造为一个图像,它们有各自的poc的计算方法来分别计算两场的poc,也就是一个场对拥有一对poc值;而在帧模式或帧场自适应模式下,一个图像只能根据片头中的元素计算出一个poc。在frame_mbs_only_flag不为1时,每个帧或场自适应的图像在解码时,帧或帧场自适应中包含的两个场也必须有各自的poc值,通过本元素,可以在已经解码的帧或帧场自适应图像的poc基础上新映射一个poc,并把它赋给底场。 */ |
2 |
se(v) |
} |
|
|
if(pic_order_cnt_type==1 && !delta_pic_order_always_zero_flag){ |
|
|
delta_pci_order_cnt[0] /* poc的第二和第三种算法是从frame_num中映射得来,本元素用于帧编码下的底场和场编码方式的场 */ |
2 |
se(v) |
if(pic_order_present_flag && !field_pic_flag) |
|
|
delta_pic_order_cnt[1] /* 用于帧编码下的顶场 */ |
2 |
se(v) |
} |
|
|
if(redundant_ic_cnt_present_flag) |
|
|
redundant_pic_cnt /* 冗余片的id号 */ |
2 |
ue(v) |
if(slice_type==B) |
|
|
direct_spatial_mv_pred_flag /* B图像在直接预测模式下,1:空间预测,0:时间预测 */ |
2 |
u(1) |
if(slice_type==P||slice_type==SP||slice_type==B){ |
|
|
num_ref_idx_active_override_flag /* 重载PPS中的参考帧队列中实际可用的参考帧的数目。 */ |
2 |
u(1) |
if(num_ref_idx_active_override_flag){ |
|
|
num_ref_idx_10_active_minus1 /* 重载值 */ |
2 |
ue(v) |
if(slice_type==B) |
|
|
num_ref_idx_11_active_minus1 /* 重载值 */ |
2 |
ue(v) |
} |
|
|
} |
|
|
ref_pic_list_reordering() /* 见第7节描述 */ |
2 |
|
if((weighted_pred_flag && (slice_type==P || slice_type==SP)) || (weighted_bipred_idc==1 && slice_type==B)) |
|
|
pred_weight_table() /* 见第8节描述 */ |
2 |
|
if(nal_ref_idc!=0) |
|
|
dec_ref_pic_marking() /* 见第9节描述 */ |
2 |
|
if(entropy_coding_mode_flag && slice_type!=1 && slice_type != SI) |
|
|
cabac_init_idc /* 给出cabac初始化时表格的选择,[0..2] */ |
2 |
ue(v) |
slice_qp_delta /* 指出用于当前片的所有宏块的量化参数的初始值。SliceQPY=26+pic_init_qp_minus26+slice_qp_delta,[0..51] */ |
2 |
se(v) |
if(slice_type==SP || slice_type==SI){ |
|
|
if(slice_type==SP) |
|
|
sp_for_switch_flag /* 指出SP帧中的p宏块的解码方式是否是switching模式 */ |
2 |
u(1) |
slice_qs_delta /* 与slice_qp_delta的语义相似,用于SP和SI,QSY=26+pic_init_qs_minus26+slice_qs_delta,[0..51] */ |
2 |
se(v) |
} |
|
|
if(deblocking_flter_control_present_flag){ |
|
|
disable_deblocking_filter_idc /* H.264指定了一套算法可以在解码器端独立地计算图像中各边界的滤波强度进行滤波。除了解码器独立计算之外,编码器也可以传递句法元素来干涉滤波强度,该元素指定了在块的是否使用滤波,同时批明那个块的边界不用滤波 */ |
2 |
ue(v) |
if(disable_deblocking_filter_idc != 1){ |
|
|
slice_alpha_c0_offset_div2 /* 增强alpha时的偏移值,FilterOffsetA=slice_alpha_c0_offset_div2 << 1 */ |
2 |
se(v) |
slice_beta_offset_div2 /* 增强beta的偏移值,FilterOffsetB=slice_beta_offset_div2<<1 */ |
2 |
se(v) |
} |
|
|
} |
|
|
if(num_slice_group_minus1 > 0 && slice_group_map_type>=3 && slice_group_map_type <= 5) |
|
|
slice_group_change_cycle /* 片组类型是3.4.5时,由该元素可以获取片组中映射单元的数目 */ |
2 |
u(v) |
} |
|
|
表11
slice_type |
name |
0 |
P slice |
1 |
B slice |
2 |
I slice |
3 |
SP slice |
4 |
SI slice |
5 |
P slice |
6 |
B slice |
7 |
I slice |
8 |
SP slice |
9 |
SI slice |
表12(注:IDR图像时,slice_type为2,4,7,9)
图3
7 参考帧重排序
句法 |
C |
Desc |
ref_pic_list_reordering(){ /* 每个参考图像都有frame_num,但编码器要指定当前图像的参考图像时,使用是ref_id,frame_num->PicNum->ref_id */ |
|
|
if(slice_type!=I && slice_type!=SI){ |
|
|
ref_pic_list_reordering_flag_l0 /* 指明List0是否进行重排序 */ |
2 |
u(1) |
if(ref_pic_list_reordering_flag_l0) |
|
|
do{ |
|
|
reordering_ofpic_nums_idc /* 执行哪种重排序操作,见表14描述 */ |
2 |
ue(v) |
if(reordering_ofpic_nums_idc==0 || reordering_ofpic_nums_idc==1) |
|
|
abs_diff_pic_num_minus1 /* 对短期参考帧重排序时指明重排序图像与当前的差,见表14 */ |
2 |
ue(v) |
elseif(reordering_ofpic_nums_idc==2) |
|
|
long_term_pic_num /* 对长期参考帧得排序时指明重排序图像 */ |
2 |
ue(v) |
}while(reordering_of_pic_nums_idc!=3) |
|
|
} |
|
|
if(slice_type==B){ |
|
|
ref_pic_list_reordering_flag_l1 /* 指明List1是否进行重排序 */ |
2 |
u(1) |
if(ref_pic_list_reordering_flag_l1) |
|
|
do{ |
|
|
reordering_ofpic_nums_idc /* 执行哪种重排序操作,见表14描述 */ |
2 |
ue(v) |
if(reordering_ofpic_nums_idc==0 || reordering_ofpic_nums_idc==1) |
|
|
abs_diff_pic_num_minus1 /* 对短期参考帧重排序时指明重排序图像与当前的差,见表14 */ |
2 |
ue(v) |
elseif(reordering_ofpic_nums_idc==2) |
|
|
long_term_pic_num /* 对长期参考帧得排序时指明重排序图像 */ |
2 |
ue(v) |
}while(reordering_of_pic_nums_idc!=3) |
|
|
} |
|
|
} |
|
|
表13
reordering_of_pic_nums_idc |
操作 |
0 |
短期参考帧重排序,abs_diff_pic_num_minus1会出现在码流中,从当前图像的PicNum减去(abs_diff_pic_num_minus1+1)后指明需要重排序的图像 |
1 |
短期参考帧重排序,abs_diff_pic_num_minus1会出现在码流中,从当前图像的PicNum加上(abs_diff_pic_num_minus1+1)后指明需要重排序的图像 |
2 |
长期参考帧重排序,long_term_pic_num会出现在码流中,指明需要重排序的图像。 |
3 |
结束循环,退出重排序操作。 |
表14
8 加权预测的语义
句法 |
C |
Desc |
pred_weight_table(){ |
|
|
luma_log2_weight_denom /* 给出参考帧列表中参考图像所有亮度的加权系数,[0..7] */ |
2 |
ue(v) |
chroma_log2_weight_denom /* 给出参考帧列表中参考图像所有色度的加权系数,[0..7] */ |
2 |
ue(v) |
for(i=0;i<=num_ref_idx_l0_active_minus1;i++){ |
|
|
luma_weight_10_flag /* 1:在参考帧序列0中的亮度的加权系数存在 */ |
2 |
u(1) |
if(luma_weight_l0_flag){ |
|
|
luma_weight_l0[i] /* 用参考序列0预测亮度值时,所用的加权系数。如果luma_weight_l0_flag=0,luma_weight_l0[i]=2luma_log2_weight_denom */ |
2 |
se(v) |
luma_offset_l0[i] /* 用参考序列0预测亮度值时,所用的加权系数的偏移,[-128-..127],如果luma_weight_l0_flag=0,该值0 */ |
2 |
se(v) |
} |
|
|
chroma_weight_l0_flag /* 同Luma相似,但用于色度 */ |
2 |
u(1) |
if(chroma_weight_l0_flag){ |
|
|
for(j=0;j<2;j++) |
|
|
chroma_weight_l0[i][j] |
2 |
se(v) |
chroma_offset_l0[i][j] |
2 |
se(v) |
} |
|
|
} |
|
|
if(slice_type==B) |
|
|
for(i=0;i<=num_ref_idx_l1_active_minus1;i++){ |
|
|
luma_weight_l1_flag |
2 |
u(1) |
if(luma_weight_l1_flag){ |
|
|
luma_weight_l1[i] |
2 |
se(v) |
luma_offset_l1[i] |
2 |
se(v) |
} |
|
|
chroma_weight_l1_flag |
2 |
u(1) |
if(chroma_weight_l1_flag) |
|
|
for(j=0;j<2;j++){ |
|
|
chroma_weight_l1[i][j] |
2 |
se(v) |
chroma_offset_l1[i][j] |
2 |
se(v) |
} |
|
|
} |
|
|
} |
|
|
表15
9 参考图像序列标记
句法 |
C |
Desc |
dec_ref_pic_marking(){ /* 前文介绍的重排序操作是对参考帧队列重新排序,而标记操作负责将参考图像移入或移出参考帧队列 */ |
|
|
if( nal_unit_type ==5){ |
|
|
no_output_of_prior_pics_flag /* IDR时,1:将前面已经解码的图像全部输出 */ |
2|5 |
u(1) |
long_term_reference_flag /* IDR时,1:使用长期参考,并且每个IDR图像解码后自动成为长期参考帧,0:IDR图像解码后自动成为短期参考帧 */ |
2|5 |
u(1) |
}else{ |
|
|
adaptive_ref_pic_marking_mode_flag /* 0:FIFO,使用滑动窗的机制,先入先出,在这种模式下,无法对长期参考帧进行操作,1:自适应标记,后续码流中会有一系列句法元素显式指明操作的步骤。 */ |
|
u(1) |
if(adaptive_ref_pic_marking_mode_flag){ |
|
|
do{ |
|
|
memory_management_control_operation /* 自适应模式下,指明本次操作的具体内容,详细描述见表17 */ |
2|5 |
ue(v) |
if(memory_management_control_operation == 1 ||memory_management_control_operation==3) |
|
|
difference_of_pic_nums_minus1 /* 通过该元素可以计算出需要操作的图像在短期参考队列中的序号。 */ |
2|5 |
ue(v) |
if(memory_management_control_operation == 2) |
|
|
long_term_pic_num /* 得到所要操作的长期参考图像的序号 */ |
2|5 |
ue(v) |
if(memory_management_control_operation == 3 ||memory_management_control_operation == 6) |
|
|
long_term_frame_idx /* 分配一个长期参考帧的序号给一个图像 */ |
2|5 |
ue(v) |
if(memory_management_control_operation == 4) |
|
|
max_long_tewrm_frame_idx_plus1 /* 此元素减1,指明长期参考队列的最大数目,[0..num_ref_frames] */ |
2|5 |
ue(v) |
}while(memory_management_control_operation != 0) |
|
|
} |
|
|
} |
|
|
表16
memory_management_control_operation |
操作 |
0 |
结束循环 |
1 |
将一个短期参考图像标记为非参考图像,也即将一个短期参考图像移出参考帧队列 |
2 |
将一个长期参考图像标记为非参考图像,也即将一个长期参考图像移出参考帧队列 |
3 |
将一个短期参考图像转为长期参考图像 |
4 |
指明长期参考帧的最大数目 |
5 |
清空参考帧队列,将所有参考图像移参考帧队列,并禁用长期参考机制 |
6 |
将当前图像存存为一个长期参考帧 |
表17标记操作