/*----------------------------------------------------------------------
| AP4_HevcSequenceParameterSet::AP4_HevcSequenceParameterSet
+---------------------------------------------------------------------*/
AP4_HevcSequenceParameterSet::AP4_HevcSequenceParameterSet() :
sps_video_parameter_set_id(0),
sps_max_sub_layers_minus1(0),
sps_temporal_id_nesting_flag(0),
sps_seq_parameter_set_id(0),
chroma_format_idc(0),
separate_colour_plane_flag(0),
pic_width_in_luma_samples(0),
pic_height_in_luma_samples(0),
conformance_window_flag(0),
conf_win_left_offset(0),
conf_win_right_offset(0),
conf_win_top_offset(0),
conf_win_bottom_offset(0),
bit_depth_luma_minus8(0),
bit_depth_chroma_minus8(0),
log2_max_pic_order_cnt_lsb_minus4(0),
sps_sub_layer_ordering_info_present_flag(0),
log2_min_luma_coding_block_size_minus3(0),
log2_diff_max_min_luma_coding_block_size(0),
log2_min_transform_block_size_minus2(0),
log2_diff_max_min_transform_block_size(0),
max_transform_hierarchy_depth_inter(0),
max_transform_hierarchy_depth_intra(0),
scaling_list_enabled_flag(0),
sps_scaling_list_data_present_flag(0),
amp_enabled_flag(0),
sample_adaptive_offset_enabled_flag(0),
pcm_enabled_flag(0),
pcm_sample_bit_depth_luma_minus1(0),
pcm_sample_bit_depth_chroma_minus1(0),
log2_min_pcm_luma_coding_block_size_minus3(0),
log2_diff_max_min_pcm_luma_coding_block_size(0),
pcm_loop_filter_disabled_flag(0),
num_short_term_ref_pic_sets(0),
long_term_ref_pics_present_flag(0),
num_long_term_ref_pics_sps(0),
sps_temporal_mvp_enabled_flag(0),
strong_intra_smoothing_enabled_flag(0),
vui_parameters_present_flag(0)
{
AP4_SetMemory(&profile_tier_level, 0, sizeof(profile_tier_level));
for (unsigned int i=0; i<8; i++) {
sps_max_dec_pic_buffering_minus1[i] = 0;
sps_max_num_reorder_pics[i] = 0;
sps_max_latency_increase_plus1[i] = 0;
}
AP4_SetMemory(short_term_ref_pic_sets, 0, sizeof(short_term_ref_pic_sets));
}
/*----------------------------------------------------------------------
| AP4_HevcSequenceParameterSet::Parse
+---------------------------------------------------------------------*/
AP4_Result
AP4_HevcSequenceParameterSet::Parse(const unsigned char* data, unsigned int data_size)
{
raw_bytes.SetData(data, data_size);
AP4_DataBuffer unescaped(data, data_size);
AP4_NalParser::Unescape(unescaped);
AP4_BitReader bits(unescaped.GetData(), unescaped.GetDataSize());
bits.SkipBits(16); // NAL Unit Header
sps_video_parameter_set_id = bits.ReadBits(4);
if (sps_video_parameter_set_id > AP4_HEVC_VPS_MAX_ID) {
DBG_PRINTF_2("sps_video_parameter_set_id[%d] > AP4_HEVC_VPS_MAX_ID[%d]\n",
sps_video_parameter_set_id, AP4_HEVC_VPS_MAX_ID);
return AP4_ERROR_INVALID_FORMAT;
}
sps_max_sub_layers_minus1 = bits.ReadBits(3);
sps_temporal_id_nesting_flag = bits.ReadBit();
AP4_Result result = profile_tier_level.Parse(bits, sps_max_sub_layers_minus1);
if (AP4_FAILED(result)) {
return result;
}
sps_seq_parameter_set_id = ReadGolomb(bits);
if (sps_seq_parameter_set_id > AP4_HEVC_SPS_MAX_ID) {
DBG_PRINTF_2("sps_seq_parameter_set_id[%d] > AP4_HEVC_SPS_MAX_ID[%d]\n",
sps_seq_parameter_set_id, AP4_HEVC_SPS_MAX_ID);
return AP4_ERROR_INVALID_FORMAT;
}
chroma_format_idc = ReadGolomb(bits);
if (chroma_format_idc == 3) {
separate_colour_plane_flag = bits.ReadBit();
}
pic_width_in_luma_samples = ReadGolomb(bits);
pic_height_in_luma_samples = ReadGolomb(bits);
conformance_window_flag = bits.ReadBit();
if (conformance_window_flag) {
conf_win_left_offset = ReadGolomb(bits);
conf_win_right_offset = ReadGolomb(bits);
conf_win_top_offset = ReadGolomb(bits);
conf_win_bottom_offset = ReadGolomb(bits);
}
bit_depth_luma_minus8 = ReadGolomb(bits);
bit_depth_chroma_minus8 = ReadGolomb(bits);
log2_max_pic_order_cnt_lsb_minus4 = ReadGolomb(bits);
if (log2_max_pic_order_cnt_lsb_minus4 > 16) {
DBG_PRINTF_1("log2_max_pic_order_cnt_lsb_minus4[%d] > 16\n",
log2_max_pic_order_cnt_lsb_minus4);
return AP4_ERROR_INVALID_FORMAT;
}
sps_sub_layer_ordering_info_present_flag = bits.ReadBit();
for (unsigned int i = (sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1);
i <= sps_max_sub_layers_minus1;
i++) {
sps_max_dec_pic_buffering_minus1[i] = ReadGolomb(bits);
sps_max_num_reorder_pics[i] = ReadGolomb(bits);
sps_max_latency_increase_plus1[i] = ReadGolomb(bits);
}
log2_min_luma_coding_block_size_minus3 = ReadGolomb(bits);
log2_diff_max_min_luma_coding_block_size = ReadGolomb(bits);
log2_min_transform_block_size_minus2 = ReadGolomb(bits);
log2_diff_max_min_transform_block_size = ReadGolomb(bits);
max_transform_hierarchy_depth_inter = ReadGolomb(bits);
max_transform_hierarchy_depth_intra = ReadGolomb(bits);
scaling_list_enabled_flag = bits.ReadBit();
if (scaling_list_enabled_flag) {
sps_scaling_list_data_present_flag = bits.ReadBit();
if (sps_scaling_list_data_present_flag) {
scaling_list_data(bits);
}
}
amp_enabled_flag = bits.ReadBit();
sample_adaptive_offset_enabled_flag = bits.ReadBit();
pcm_enabled_flag = bits.ReadBit();
if (pcm_enabled_flag) {
pcm_sample_bit_depth_luma_minus1 = bits.ReadBits(4);
pcm_sample_bit_depth_chroma_minus1 = bits.ReadBits(4);
log2_min_pcm_luma_coding_block_size_minus3 = ReadGolomb(bits);
log2_diff_max_min_pcm_luma_coding_block_size = ReadGolomb(bits);
pcm_loop_filter_disabled_flag = bits.ReadBit();
}
num_short_term_ref_pic_sets = ReadGolomb(bits);
if (num_short_term_ref_pic_sets > AP4_HEVC_SPS_MAX_RPS) {
DBG_PRINTF_2("num_short_term_ref_pic_sets[%d] > AP4_HEVC_SPS_MAX_RPS[%d]\n",
num_short_term_ref_pic_sets, AP4_HEVC_SPS_MAX_RPS);
return AP4_ERROR_INVALID_FORMAT;
}
for (unsigned int i=0; i<num_short_term_ref_pic_sets; i++) {
AP4_Result result = parse_st_ref_pic_set(&short_term_ref_pic_sets[i], this, i, num_short_term_ref_pic_sets, bits);
if (AP4_FAILED(result)) return result;
}
long_term_ref_pics_present_flag = bits.ReadBit();
if (long_term_ref_pics_present_flag) {
num_long_term_ref_pics_sps = ReadGolomb(bits);
for (unsigned int i=0; i<num_long_term_ref_pics_sps; i++) {
/* lt_ref_pic_poc_lsb_sps[i] = */ bits.ReadBits(log2_max_pic_order_cnt_lsb_minus4 + 4);
/* used_by_curr_pic_lt_sps_flag[i] = */ bits.ReadBit();
}
}
sps_temporal_mvp_enabled_flag = bits.ReadBit();
strong_intra_smoothing_enabled_flag = bits.ReadBit();
vui_parameters_present_flag = bits.ReadBit();
if (vui_parameters_present_flag) {
AP4_Result result = vui_parameters.Parse(bits);
if (AP4_FAILED(result)) return result;
}
return AP4_SUCCESS;
}
详细注释上述代码