H.264
H.264标准文档中并没有详细指定码流如何存储与传输,其仅包含了一个Annex,并特别地描述了一种可能采用的格式Annex B,但其并不是一个必须要求的格式形式。
NALU
Network Abstraction Layer Unit,利于网路传输的一种H.264数据组织格式。
StartCode | NALU header | Raw Byte Sequence Payload | ··· |
---|
StartCode (3或4字节)
在编码时,会在每个NALU前面加上(0x00000001或者0x000001)以区分不同的NALU,同时为了防止竞争,在编码NALU时,当出现两个连续的0x00字节,就会在其后插入0x03,其会在解码时丢弃。(非标准:3字节的startcode 仅用在slice分片时,除第一个NALU以外的其他NALU前)
NALU header (1字节)
Field | Type | Comment |
---|---|---|
forbidden_bit | UB[1] | 禁止位,应该为0 |
nal_ref_idc | UB[2] | 表示重要等级,其大于0时可能是SPS/PPS/IDR等 |
nal_unit_type | UB[5] | NALU类型,如下: 0 = 未指定 1 = 一个非 IDR 图像的编码条带 2 = 编码条带数据分割块 A 3 = 编码条带数据分割块 B 4 = 编码条带数据分割块 C 5 = IDR 图像的编码条带 6 = 辅助增强信息 (SEI) 7 = 序列参数集(SPS) 8 = 图像参数集(PPS) 9 = 访问单元分隔符 10 = 序列结尾 11 = 流结尾 12 = 填充数据 13 = 序列参数集扩展 14 ~ 18 保留 19 = 未分割的辅助编码图像的编码条带 20 ~ 31 保留 |
RBSP
实际存储的编码后的视频数据或者参数数据。
SPS/PPS
在flv文件保存及RTMP推流时,sps/pps信息通常封装到AVCDecoderConfigurationRecord结构体中,并置于flv第一个videoTag或RTMP推理流时的AVC sequence 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) lengthSizeMinusOne;
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*sequenceParameterSetLength) pictureParameterSetNALUnit;
}
if ( profile_idc == 100 || profile_idc == 110 ||
profile_idc == 122 || profile_idc == 144 )
{
bit(6) reserved = '111111'b;
unsigned int(2) chroma_format;
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_luma_minus8;
bit(5) reserved = '11111'b;
unsigned int(3) bit_depth_chroma_minus8;
unsigned int(8) numOfSequenceParameterSetEXT;
for (i = 0; i < numOfSequenceParameterSetEXT; i++)
{
unsigned int(16) sequenceParameterSetEXTLength;
bit(8*sequenceParameterSetLength) sequenceParameterSetEXTNALUnit;
}
}
}
AVCProfileIndication 表示H264流的配置信息,根据不同的值划分不同的等级,如profile_idc == 66,baseline(视频会议及移动应用)、profile_idc == 77,main(标清电视)、profile_idc == 100,High(高清电视)等。
AVCLevelIndication 表示H264的等级,可指定最大的图像分辨率,帧率等等。
sequenceParameterSetNALUnit 保存原始sps信息,可以解码出准确的图像长宽(像素),帧率等信息。
----------------------------------------------------------------------------------------------------------------------------
ae(v): 上下文自适应算术熵编码语法元素。
b(8): 任意形式的8比特字节。
ce(v): 左位在先的上下文自适应可变长度熵编码语法元素。
f(n): n位固定模式比特串(由左至右),左位在先, 该描述符的解析过程通过函数read_bits( n )的返
回值来规定。
i(n): 使用n比特的有符号整数。在语法表中,如果n是‘v’,其比特数由其它语法元素值确定。解析
过程由函数read_bits(n)的返回值规定,该返回值用最高有效位在前的2的补码表示。
me(v): 映射的指数哥伦布码编码的语法元素,左位在先。
se(v): 有符号整数指数哥伦布码编码的语法元素位在先。
te(v): 舍位指数哥伦布码编码语法元素,左位在先。
u(n): n位无符号整数。在语法表中,如果n是‘v’,其比特数由其它语法元素值确定。解析过程由函
数read_bits(n)的返回值规定,该返回值用最高有效位在前的二进制表示。
ue(v): 无符号整数指数哥伦布码编码的语法元素,左位在先。
sps
Field | Type |
---|---|
profile_idc | u(8) |
constraint_set0_flag | u(1) |
constraint_set1_flag | u(1) |
constraint_set2_flag | u(1) |
constraint_set3_flag | u(1) |
reserved_zero_4bits | u(4) ’0000‘b |
level_idc | u(8) |
seq_parameter_set_id | ue(v) |
if (profile_idc100||profile_idc110||profile_idc122||profile_idc144) | |
chroma_format_idc | ue(v) |
if ( chroma_format_idc = = 3 ) | |
residual_colour_transform_flag | u(1) |
bit_depth_luma_minus8 | ue(v) |
bit_depth_chroma_minus8 | ue(v) |
qpprime_y_zero_transform_bypass_flag | u(1) |
seq_scaling_matrix_present_flag | u(1) |
log2_max_frame_num_minus4 | ue(v) |
pic_order_cnt_type | ue(v) |
If (pic_order_cnt_type = = 0) | |
log2_max_pic_order_cnt_lsb_minus4 | ue(v) |
else if( pic_order_cnt_type = = 1 ) { | |
delta_pic_order_always_zero_flag | u(1) |
offset_for_non_ref_pic | se(v) |
offset_for_top_to_bottom_field | se(v) |
num_ref_frames_in_pic_order_cnt_cycle | ue(v) |
for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ ) | |
offset_for_ref_frame[ i ] } | se(v) |
num_ref_frames | ue(v) |
gaps_in_frame_num_value_allowed_flag | u(1) |
pic_height_in_map_units_minus1 | ue(v) |
frame_mbs_only_flag | u(1) |
if( !frame_mbs_only_flag ) | |
mb_adaptive_frame_field_flag | u(1) |
direct_8x8_inference_flag | u(1) |
frame_cropping_flag | u(1) |
if( frame_cropping_flag ) { | |
frame_crop_left_offset | ue(v) |
frame_crop_right_offset | ue(v) |
frame_crop_top_offset | ue(v) |
frame_crop_bottom_offset } | ue(v) |
vui_parameters_present_flag | u(1) |
if( vui_parameters_present_flag ) | |
vui_parameters( ) | |
rbsp_trailing_bits( ) |
profile_idc 和level_idc 是指比特流所遵守的配置和级别。
constraint_set0_flag,constraint_set1_flag,constraint_set2_flag,constraint_set3_flag,为1则表示必须遵守标准规范,为0则可以遵守也可不遵守。其规范见H.264标准文档附件A。
reserved_zero_4bits 应等于 0。reserved_zero_4bits 的其他取值将由 ITU-T | ISO/IEC 未来规定。解码器将忽略reserved_zero_4bits 的值。
seq_parameter_set_id 用于识别图像参数集所指的序列参数集。seq_parameter_set_id 的值应在 0-31 的范围 内,包括 0 和 31。
chroma_format_idc是指与亮度取样对应的色度取样。chroma_format_idc 的值应该在 0 到 3 的范围内(包括 0 和 3)。当 chroma_format_idc 不存在时,应推断其值为 1(4:2:0 的色度格式)。
residual_colour_transform_flag的值等于1时,则应用残余颜色变化,其值为0时则不使用,不存在默认为0。
bit_depth_luma_minus8是指亮度队列样值的比特深度以及亮度量化参数范围的取值偏移QpBdOffsetY。
bit_depth_chroma_minus8是指色度队列样值的比特深度以及色度量化参数范围的取值偏移 QpBdOffsetC。
num_ref_frames规定了可能在视频序列中任何图像帧间预测的解码过程中用到的短期参考帧和长期参考帧、互补参考场对以及不成对的参考场的最大数量。
pic_width_in_mbs_minus1 加 1 是指以宏块为单元的每个解码图像的宽度。其中亮度分量宽度一般就是分辨率
以宏块为单元的图像宽度变量: PicWidthInMbs = pic_width_in_mbs_minus1 + 1
亮度分量的图像宽度变量: PicWidthInSamplesL = PicWidthInMbs * 16
色度分量的图像宽度变量: PicWidthInSamplesC = PicWidthInMbs * MbWidthC
pic_height_in_map_units_minus1 加1表示以条带组映射为单位的一个解码帧或场的高度。同理可计算分辨率
以条带为单元的图像高度变量: PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1
图像高度变量: PicHeightInSamples = PicHeightInMapUnits*16
以宏块为单元的图像大小: PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits
frame_mbs_only_flag等于 0 表示编码视频序列的编码图像可能是编码场或编码帧。frame_mbs_only_flag 等于 1 表示编码视频序列的每个编码图像都是一个仅包含帧宏块的编码帧。
mb_adaptive_frame_field_flag等于 0 表示在一个图像的 帧 和 场 宏 块 之 间 没 有交换。等于 1 表示在帧和帧内的场宏块之间可能会有交换。当 mb_adaptive_frame_field_flag 没有特别规定时,默认其值为 0。
direct_8x8_inference_flag表示在B_Skip、B_Direct_16x16 和 B_Direct_8x8 亮度运动矢量的计算过程使用的方法。当 frame_mbs_only_flag 等于 0 时 direct_8x8_inference_flag 应等于 1。
frame_cropping_flag等于 1 表示帧剪切偏移参数遵从视频序列参数集中的下一个值。frame_cropping_flag 等于 0 表示不存在帧剪切偏移参数。
frame_crop_left_offset,frame_crop_right_offset,frame_crop_top_offset,frame_crop_bottom_offset是指从解码过程中输出的编码图像序列中的图像样值以帧坐标中的一个矩阵区域的形式输出。
pps
Field | Type |
---|---|
pic_parameter_set_id | ue(v) |
seq_parameter_set_id | ue(v) |
entropy_coding_mode_flag | u(1) |
pic_order_present_flag | u(1) |
num_slice_groups_minus1 | ue(v) |
if( num_slice_groups_minus1 > 0 ) { | |
slice_group_map_type | ue(v) |
if( slice_group_map_type = = 0 ) | |
for( iGroup = 0; iGroup <= num_slice_groups_minus1; iGroup++ ) | |
run_length_minus1[ iGroup ] | ue(v) |
else if( slice_group_map_type = = 2 ) | |
for( iGroup = 0; iGroup < num_slice_groups_minus1; iGroup++ ) { | |
top_left[ iGroup ] | ue(v) |
bottom_right[ iGroup ] } | ue(v) |
else if( slice_group_map_type = = 3 || slice_group_map_type = = 4 ||slice_group_map_type = = 5 ) { | |
slice_group_change_direction_flag | u(1) |
slice_group_change_rate_minus1 | ue(v) |
} else if( slice_group_map_type = = 6 ) { | |
pic_size_in_map_units_minus1 | ue(v) |
for( i = 0; i <= pic_size_in_map_units_minus1; i++ ) | |
slice_group_id[ i ] } | u(v) |
} | |
num_ref_idx_l0_active_minus1 | ue(v) |
num_ref_idx_l1_active_minus1 | ue(v) |
weighted_pred_flag | u(1) |
weighted_bipred_idc | u(2) |
pic_init_qp_minus26 /* relative to 26 */ | se(v) |
pic_init_qs_minus26 /* relative to 26 */ | se(v) |
chroma_qp_index_offset | se(v) |
deblocking_filter_control_present_flag | u(1) |
constrained_intra_pred_flag | u(1) |
redundant_pic_cnt_present_flag | u(1) |
if( more_rbsp_data( ) ) { | |
transform_8x8_mode_flag | u(1) |
pic_scaling_matrix_present_flag | u(1) |
if( pic_scaling_matrix_present_flag ) | |
for( i = 0; i < 6 + 2* transform_8x8_mode_flag; i++ ) { | |
pic_scaling_list_present_flag[ i ] | u(1) |
if( pic_scaling_list_present_flag[ i ] ) | |
if( i < 6) scaling_list( ScalingList4x4[ i ], 16, UseDefaultScalingMatrix4x4Flag[ i ] ) | |
else scaling_list( ScalingList8x8[ i–6 ], 64,UseDefaultScalingMatrix8x8Flag[ i–6 ] ) | |
} | |
second_chroma_qp_index_offset | se(v) |
} | |
rbsp_trailing_bits( ) |
pic_parameter_set_id标识在条带头中用到的图像参数集。其值应该在 0 到 255 的 范围内(包括 0 和 255)。
seq_parameter_set_id 是指活动的序列参数集。其值应该在 0 到 31 的范围内(包括 0 和 31)。
entropy_coding_mode_flag 用于选取语法元素的熵编码方式,0表示采用CAVLC,1表示采用CABAC。
pic_order_present_flag 等于 1 表示与图像顺序数有关的语法元素将出现于条带头中,0则不会出现。
num_slice_groups_minus1 加 1 表示一个图像中的条带组数。
slice_group_map_type 表示条带组中条带组映射单元的映射是如何编码的。
weighted_pred_flag 等于 0 表示加权的预测不应用于 P 和 SP 条带。weighted_pred_flag 等于 1 表示在 P 和 SP条带中应使用加权的预测。
weighted_bipred_idc 等于 0 表示 B 条带应该采用默认的加权预测。weighted_bipred_idc 等于 1 表示 B 条带应该 采 用具体指 明 的 加 权 预 测 。 weighted_bipred_idc 等 于 2 表 示 B 条 带 应 该 采 用 隐 含 的 加 权 预 测 。
deblocking_filter_control_present_flag 等于 1 表示控制去块效应滤波器的特征的一组语法元素将出现在条带 头中。deblocking_filter_control_present_flag 等于 0 表示控制去块效应滤波器的特征的一组语法元素不会出现在条带头中,并且它们的推定值将会生效。
constrained_intra_pred_flag 等于 0 表示帧内预测允许使用残余数据,且使用帧内宏块预测模式编码的宏块的预测可以使用帧间宏块预测模式编码的相邻宏块的解码样值。
详见 《Advanced video coding for generic audiovisual services》(H.264)