h264码流格式
码流格式
… | NAL头 | RBSP | NAL头 | RBSP | NAL头 | RBSP | … |
---|
H264 传输
SPS | SEI | PPS | I片 | 图像定界符 | P片 | P片 |
---|
NAL头格式
start code ( 3 or 4 ) | forbidden_zero_bit(1) | nal_ref_idc (2) | nal_unit_type( 5) | RBSP |
---|
解释
-
start code,如果NALU对应的Slice为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001
-
forbidden_zero_bit,禁止位,0正常,1错误
-
nal_ref_idc,重要级别,11表示非常重要
-
nal_unit_type,表示该NALU的类型
-
RBSP ,Raw Byte Sequence Payload,原始字节序列负荷
-
为了使NALU主体不包括起始码,在编码时每遇到两个字节(连续)的0,就插入一字节0x03,以和起始码相区别。解码时,则将相应的0x03删除掉。
nal_unit_type NAL类型 0 未使用 1 不区分,非IDR图像的片 2 片分区A 3 片分区B 4 片分区C 5 IDR图像中的片 6 补充增强信息单元(SEI) 7 序列参数集(SPS) 8 图像参数集 (PPS) 9 分界符 10 序列结束 11 码流结束 12 填充 12…23 保留 24…31 未使用 - 流结束符,表明该流中已经没有图像
- 序列结束符,表明下一图像为IDR图像
码流结构图
sps
- (1) profile_idc:
标识当前H.264码流的profile。我们知道,H.264中定义了三种常用的档次profile:
基准档次:baseline profile;
主要档次:main profile;
扩展档次:extended profile;
在H.264的SPS中,第一个字节表示profile_idc,根据profile_idc的值可以确定码流符合哪一种档次。判断规律为:
profile_idc = 66 → baseline profile;
profile_idc = 77 → main profile;
profile_idc = 88 → extended profile;
在新版的标准中,还包括了High、High 10、High 4:2:2、High 4:4:4、High 10 Intra、High 4:2:2 Intra、High 4:4:4 Intra、CAVLC 4:4:4 Intra等,每一种都由不同的profile_idc表示。
另外,constraint_set0_flag ~ constraint_set5_flag是在编码的档次方面对码流增加的其他一些额外限制性条件。
在我们实验码流中,profile_idc = 0x42 = 66,因此码流的档次为baseline profile。 - (2) level_idc
标识当前码流的Level。编码的Level定义了某种条件下的最大视频分辨率、最大视频帧率等参数,码流所遵从的level由level_idc指定。
当前码流中,level_idc = 0x1e = 30,因此码流的级别为3。 - (3) seq_parameter_set_id
表示当前的序列参数集的id。通过该id值,图像参数集pps可以引用其代表的sps中的参数。 - (4) log2_max_frame_num_minus4
用于计算MaxFrameNum的值。计算公式为MaxFrameNum = 2^(log2_max_frame_num_minus4 + 4)。MaxFrameNum是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段。 - (5) pic_order_cnt_type
表示解码picture order count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法。该语法元素的取值为0、1或2。 - (6) log2_max_pic_order_cnt_lsb_minus4
用于计算MaxPicOrderCntLsb的值,该值表示POC的上限。计算方法为MaxPicOrderCntLsb = 2^(log2_max_pic_order_cnt_lsb_minus4 + 4)。 - (7) max_num_ref_frames
用于表示参考帧的最大数目。 - (8) gaps_in_frame_num_value_allowed_flag
标识位,说明frame_num中是否允许不连续的值。 - (9) pic_width_in_mbs_minus1
用于计算图像的宽度。单位为宏块个数,因此图像的实际宽度为:
frame_width = 16 × (pic_width_in_mbs_minus1 + 1); - (10) pic_height_in_map_units_minus1
使用PicHeightInMapUnits来度量视频中一帧图像的高度。PicHeightInMapUnits并非图像明确的以像素或宏块为单位的高度,而需要考虑该宏块是帧编码或场编码。PicHeightInMapUnits的计算方式为:
PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1; - (11) frame_mbs_only_flag
标识位,说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:
FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits - (12) mb_adaptive_frame_field_flag
标识位,说明是否采用了宏块级的帧场自适应编码。当该标识位为0时,不存在帧编码和场编码之间的切换;当标识位为1时,宏块可能在帧编码和场编码模式之间进行选择。 - (13) direct_8x8_inference_flag
标识位,用于B_Skip、B_Direct模式运动矢量的推导计算。 - (14) frame_cropping_flag
标识位,说明是否需要对输出的图像帧进行裁剪。 - (15) vui_parameters_present_flag
标识位,说明SPS中是否存在VUI信息。
PPS
- (1) pic_parameter_set_id
表示当前PPS的id。某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在Slice header中保存PPS的id值。该值的取值范围为[0,255]。 - (2) seq_parameter_set_id
表示当前PPS所引用的激活的SPS的id。通过这种方式,PPS中也可以取到对应SPS中的参数。该值的取值范围为[0,31]。 - (3) entropy_coding_mode_flag
熵编码模式标识,该标识位表示码流中熵编码/解码选择的算法。对于部分语法元素,在不同的编码配置下,选择的熵编码方式不同。例如在一个宏块语法元素中,宏块类型mb_type的语法元素描述符为“ue(v) | ae(v)”,在baseline profile等设置下采用指数哥伦布编码,在main profile等设置下采用CABAC编码。
标识位entropy_coding_mode_flag的作用就是控制这种算法选择。当该值为0时,选择左边的算法,通常为指数哥伦布编码或者CAVLC;当该值为1时,选择右边的算法,通常为CABAC。 - (4) bottom_field_pic_order_in_frame_present_flag
标识位,用于表示另外条带头中的两个语法元素delta_pic_order_cnt_bottom和delta_pic_order_cn是否存在的标识。这两个语法元素表示了某一帧的底场的POC的计算方法。 - (5) num_slice_groups_minus1
表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice group。slice group是一帧中宏块的组合方式,定义在协议文档的3.141部分。 - (6) num_ref_idx_l0_default_active_minus1、num_ref_idx_l0_default_active_minus1
表示当Slice Header中的num_ref_idx_active_override_flag标识位为0时,P/SP/B slice的语法元素num_ref_idx_l0_active_minus1和num_ref_idx_l1_active_minus1的默认值。 - (7) weighted_pred_flag
标识位,表示在P/SP slice中是否开启加权预测。 - (8) weighted_bipred_idc
表示在B Slice中加权预测的方法,取值范围为[0,2]。0表示默认加权预测,1表示显式加权预测,2表示隐式加权预测。 - (9) pic_init_qp_minus26和pic_init_qs_minus26
表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到。 - (10) chroma_qp_index_offset
用于计算色度分量的量化参数,取值范围为[-12,12]。 - (11) deblocking_filter_control_present_flag
标识位,用于表示Slice header中是否存在用于去块滤波器控制的信息。当该标志位为1时,slice header中包含去块滤波相应的信息;当该标识位为0时,slice header中没有相应的信息。 - (12) constrained_intra_pred_flag
若该标识为1,表示I宏块在进行帧内预测时只能使用来自I和SI类型宏块的信息;若该标识位0,表示I宏块可以使用来自Inter类型宏块的信息。 - (13) redundant_pic_cnt_present_flag
标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。当该标志位为1时,slice header中包含redundant_pic_cnt;当该标识位为0时,slice header中没有相应的信息。
aligned(8) class AVCDecoderConfigurationRecord {
unsigned int(8) configurationVersion = 1;
unsigned int(8) AVCProfileIndication;
unsigned int(8) profile_compatibility;
unsigned int(8) AVCLevelIndication;
bit(6) reserved = ‘111111’b;
unsigned int(2) lengthSi*usOne;
bit(3) reserved = ‘111’b;
unsigned int(5) numOfSequenceParameterSets;
for (i=0; i< numOfSequenceParameterSets; i++) {
unsigned int(16) sequenceParameterSetLength ;
bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;
}
unsigned int(8) numOfPictureParameterSets;
for (i=0; i< numOfPictureParameterSets; i++) {
unsigned int(16) pictureParameterSetLength;
bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;
}
}
profile
- H264 主要包括Baseline, - - - Ext,Main,High这几种常用profile和一些特殊用途的profies,如Constrain baseline, SVC,MVC和一系列high-Fidelity profiles 等等,各种profile是根据不同的应用场景设计的,具体余下:
- Baseline主要是用于可视电话,会议电视,无线通讯等实时通信。要实时,就要减少视频decode和display的时延,所以没有B frame;为了提高针对网络丢包的容错能力,特意添加了FMO,ASO和冗余slice;
- Main用于数字广播电视和数字视频存储,侧重点在于提高压缩率,所以有了CABAC,MBAFF,Interlace,B frame等。
Extend用于改进误码性能和码流切换(SP和SI slice),侧重于码流切换(SI,SP slice)和error resilience(数据分割)。 - High主要用于高压缩效率和质量, 引入8x8 DCT,选择量化矩阵等。