h265 sps 解析视频宽高
一、NALU 解析
首先来介绍下h265(HEVC)nal单元头,与h264的nal层相比,h265的nal unit header有两个字节构成,如下图所示
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| F | Type | LayerId | TID |
+------------ - +---------------- - +
其语法如下表中的定义:
从图中可以看出hevc的nal包结构与h264有明显的不同,hevc加入了nal所在的时间层的ID,去除了nal_ref_idc,此信息合并到了naltype中,
通常情况下F为0,layerid为0, TID为1。
H265 帧类型判断:
和264的&0x1f不同。265是 :
int type = (code & 0x7E)>>1;
在文件中查找00 00 00 01NALU头,发现在有6种开头分别为:
再根据H265的NALU类型定义分析,
00 00 00 01 40 01 的nuh_unit_type的值为 32, 语义为视频参数集 VPS
00 00 00 01 42 01 的nuh_unit_type的值为 33, 语义为序列参数集 SPS
00 00 00 01 44 01 的nuh_unit_type的值为 34, 语义为图像参数集 PPS
00 00 00 01 4E 01 的nuh_unit_type的值为 39, 语义为补充增强信息 SEI
00 00 00 01 26 01 的nuh_unit_type的值为 19, 语义为可能有RADL图像的IDR图像的SS编码数据 IDR
00 00 00 01 02 01 的nuh_unit_type的值为1, 语义为被参考的后置图像,且非TSA、非STSA的SS编码数据
在编码过程中,从编码器获取码流的时候,1、2、3、4、5是在一帧数据当中。相当于H264的I帧。
Nalu Type的定义
enum NalUnitType
{
NAL_UNIT_CODED_SLICE_TRAIL_N = 0, // 0
NAL_UNIT_CODED_SLICE_TRAIL_R, // 1
NAL_UNIT_CODED_SLICE_TSA_N, // 2
NAL_UNIT_CODED_SLICE_TLA, // 3 // Current name in the spec: TSA_R
NAL_UNIT_CODED_SLICE_STSA_N, // 4
NAL_UNIT_CODED_SLICE_STSA_R, // 5
NAL_UNIT_CODED_SLICE_RADL_N, // 6
NAL_UNIT_CODED_SLICE_DLP, // 7 // Current name in the spec: RADL_R
NAL_UNIT_CODED_SLICE_RASL_N, // 8
NAL_UNIT_CODED_SLICE_TFD, // 9 // Current name in the spec: RASL_R
NAL_UNIT_RESERVED_10,
NAL_UNIT_RESERVED_11,
NAL_UNIT_RESERVED_12,
NAL_UNIT_RESERVED_13,
NAL_UNIT_RESERVED_14,
NAL_UNIT_RESERVED_15, NAL_UNIT_CODED_SLICE_BLA, // 16 // Current name in the spec: BLA_W_LP
NAL_UNIT_CODED_SLICE_BLA, // 16 // Current name in the spec: BLA_W_LP
NAL_UNIT_CODED_SLICE_BLANT, // 17 // Current name in the spec: BLA_W_DLP
NAL_UNIT_CODED_SLICE_BLA_N_LP, // 18
NAL_UNIT_CODED_SLICE_IDR, // 19 // Current name in the spec: IDR_W_DLP
NAL_UNIT_CODED_SLICE_IDR_N_LP, // 20
NAL_UNIT_CODED_SLICE_CRA, // 21
NAL_UNIT_RESERVED_22,
NAL_UNIT_RESERVED_23,
NAL_UNIT_RESERVED_24,
NAL_UNIT_RESERVED_25,
NAL_UNIT_RESERVED_26,
NAL_UNIT_RESERVED_27,
NAL_UNIT_RESERVED_28,
NAL_UNIT_RESERVED_29,
NAL_UNIT_RESERVED_30,
NAL_UNIT_RESERVED_31,
NAL_UNIT_VPS, // 32
NAL_UNIT_SPS, // 33
NAL_UNIT_PPS, // 34
NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35
NAL_UNIT_EOS, // 36
NAL_UNIT_EOB, // 37
NAL_UNIT_FILLER_DATA, // 38
NAL_UNIT_SEI, // 39 Prefix SEI
NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI
NAL_UNIT_RESERVED_41,
NAL_UNIT_RESERVED_42,
NAL_UNIT_RESERVED_43,
NAL_UNIT_RESERVED_44,
NAL_UNIT_RESERVED_45,
NAL_UNIT_RESERVED_46,
NAL_UNIT_RESERVED_47,
NAL_UNIT_UNSPECIFIED_48,
NAL_UNIT_UNSPECIFIED_49,
NAL_UNIT_UNSPECIFIED_50,
NAL_UNIT_UNSPECIFIED_51,
NAL_UNIT_UNSPECIFIED_52,
NAL_UNIT_UNSPECIFIED_53,
NAL_UNIT_UNSPECIFIED_54,
NAL_UNIT_UNSPECIFIED_55,
NAL_UNIT_UNSPECIFIED_56,
NAL_UNIT_UNSPECIFIED_57,
NAL_UNIT_UNSPECIFIED_58,
NAL_UNIT_UNSPECIFIED_59,
NAL_UNIT_UNSPECIFIED_60,
NAL_UNIT_UNSPECIFIED_61,
NAL_UNIT_UNSPECIFIED_62,
NAL_UNIT_UNSPECIFIED_63,
NAL_UNIT_INVALID,
};
二、sps解析代码
bool ParseSequenceParameterSet(BYTE* data,int size, vc_params_t& params)
{
if (size < 20)
{
return false;
}
NALBitstream bs(data, size);
// seq_parameter_set_rbsp()
bs.GetWord(4);// sps_video_parameter_set_id
int sps_max_sub_layers_minus1 = bs.GetWord(3); // "The value of sps_max_sub_layers_minus1 shall be in the range of 0 to 6, inclusive."
if (sps_max_sub_layers_minus1 > 6)
{
return false;
}
bs.GetWord(1);// sps_temporal_id_nesting_flag
// profile_tier_level( sps_max_sub_layers_minus1 )
{
bs.GetWord(2);// general_profile_space
bs.GetWord(1);// general_tier_flag
params.profile = bs.GetWord(5);// general_profile_idc
bs.GetWord(32);// general_profile_compatibility_flag[32]
bs.GetWord(1);// general_progressive_source_flag
bs.GetWord(1);// general_interlaced_source_flag
bs.GetWord(1);// general_non_packed_constraint_flag
bs.GetWord(1);// general_frame_only_constraint_flag
bs.GetWord(44);// general_reserved_zero_44bits
params.level = bs.GetWord(8);// general_level_idc
uint8 sub_layer_profile_present_flag[6] = {0};
uint8 sub_layer_level_present_flag[6] = {0};
for (int i = 0; i < sps_max_sub_layers_minus1; i++)
{
sub_layer_profile_present_flag[i]= bs.GetWord(1);
sub_layer_level_present_flag[i]= bs.GetWord(1);
}
if (sps_max_sub_layers_minus1 > 0)
{
for (int i = sps_max_sub_layers_minus1; i < 8; i++)
{
uint8 reserved_zero_2bits = bs.GetWord(2);
}
}
for (int i = 0; i < sps_max_sub_layers_minus1; i++)
{
if (sub_layer_profile_present_flag[i])
{
bs.GetWord(2);// sub_layer_profile_space[i]
bs.GetWord(1);// sub_layer_tier_flag[i]
bs.GetWord(5);// sub_layer_profile_idc[i]
bs.GetWord(32);// sub_layer_profile_compatibility_flag[i][32]
bs.GetWord(1);// sub_layer_progressive_source_flag[i]
bs.GetWord(1);// sub_layer_interlaced_source_flag[i]
bs.GetWord(1);// sub_layer_non_packed_constraint_flag[i]
bs.GetWord(1);// sub_layer_frame_only_constraint_flag[i]
bs.GetWord(44);// sub_layer_reserved_zero_44bits[i]
}
if (sub_layer_level_present_flag[i])
{
bs.GetWord(8);// sub_layer_level_idc[i]
}
}
}
uint32 sps_seq_parameter_set_id= bs.GetUE(); // "The value of sps_seq_parameter_set_id shall be in the range of 0 to 15, inclusive."
if (sps_seq_parameter_set_id > 15)
{
return false;
}
uint32 chroma_format_idc = bs.GetUE(); // "The value of chroma_format_idc shall be in the range of 0 to 3, inclusive."
if (sps_seq_parameter_set_id > 3)
{
return false;
}
if (chroma_format_idc == 3)
{
bs.GetWord(1);// separate_colour_plane_flag
}
params.width = bs.GetUE(); // pic_width_in_luma_samples
params.height = bs.GetUE(); // pic_height_in_luma_samples
if (bs.GetWord(1))
{// conformance_window_flag
bs.GetUE(); // conf_win_left_offset
bs.GetUE(); // conf_win_right_offset
bs.GetUE(); // conf_win_top_offset
bs.GetUE(); // conf_win_bottom_offset
}
uint32 bit_depth_luma_minus8= bs.GetUE();
uint32 bit_depth_chroma_minus8= bs.GetUE();
if (bit_depth_luma_minus8 != bit_depth_chroma_minus8)
{
return false;
}
//...
return true;
}
三、测试代码
int main(int argc, _TCHAR* argv[])
{
vc_params_t params = {0};
BYTE sps1080[] = {0x42,0x01,0x01,0x01,0x60,0x00,0x00,0x03,0x00,0xb0,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x7b,0xa0,0x03,0xc0,0x80,0x10,0xe5,0x8d,0xae,0x49,0x32,0xf4,0xdc,0x04,0x04,0x04,0x02};
BYTE sps720[]={0x42,0x01,0x01,0x01,0x60,0x00,0x00,0x03,0x00,0xb0,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x5d,0xa0,0x02,0x80,0x80,0x2d,0x16,0x36,0xb9,0x24,0xcb,0xd3,0x70,0x10,0x10,0x10,0x08};
BYTE spsD1[]={0x42,0x01,0x01,0x01,0x60,0x00,0x00,0x03,0x00,0xb0,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x5a,0xa0,0x05,0xa2,0x00,0x90,0x58,0xda,0xe4,0x93,0x2f,0x4d,0xc0,0x40,0x40,0x40,0x20};
ParseSequenceParameterSet(sps1080,sizeof(sps1080),params);
printf("%d-%d-%d\n",params.width,params.height,params.level);
ParseSequenceParameterSet(sps720,sizeof(sps720),params);
printf("%d-%d-%d\n",params.width,params.height,params.level);
ParseSequenceParameterSet(spsD1,sizeof(spsD1),params);
printf("%d-%d-%d\n",params.width,params.height,params.level);
return 0;
}
- 分享
- 举报
-
浏览量:1179次2023-06-12 14:34:40
-
浏览量:2630次2024-01-22 11:16:26
-
浏览量:5525次2020-08-20 14:18:11
-
2021-07-30 17:20:54
-
2024-01-22 16:35:19
-
浏览量:3099次2019-06-27 08:53:15
-
浏览量:2421次2022-01-19 09:00:17
-
浏览量:1101次2024-01-08 16:40:50
-
浏览量:1080次2023-12-26 16:33:04
-
浏览量:908次2024-01-02 17:24:57
-
浏览量:3209次2020-08-05 20:32:31
-
浏览量:5222次2019-12-28 10:17:47
-
浏览量:3294次2020-08-25 18:13:09
-
浏览量:4761次2021-09-22 16:21:48
-
浏览量:5461次2021-04-27 16:33:54
-
浏览量:2577次2022-03-24 09:00:15
-
浏览量:13183次2020-11-14 10:44:48
-
浏览量:1804次2018-02-01 19:43:47
-
浏览量:1591次2023-12-29 17:51:55
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
gcp
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明