bit_buffer是我自己写的一个数据缓存器,功能简单,看调用方法也能猜到干了什么,读者可以自行实现
if len(frm.Sps) > 0 {
bf := bit_buffer.NewBitBuffer()
bf.FromBytes(frm.Sps[5:])
profile_idc := bf.Read1Byte()
bf.SkipNBits(8) // constraint_setx_flag + reserved
level_idc := bf.Read1Byte()
sps_id := bf.ReadUExpGolomb()
if profile_idc == 100 || profile_idc == 110 ||
profile_idc == 122 || profile_idc == 244 || profile_idc == 44 ||
profile_idc == 83 || profile_idc == 86 || profile_idc == 118 ||
profile_idc == 128 {
chroma_format_idc := bf.ReadUExpGolomb()
if chroma_format_idc == 3 {
sparate_colour_plane_flag := bf.ReadNBits(1)
_ = sparate_colour_plane_flag
}
bit_depth_luma_minus8 := bf.ReadUExpGolomb()
bit_depth_chroma_minus8 := bf.ReadUExpGolomb()
qpprime_y_zoro_transform_bypass_flag := bf.ReadNBits(1)
seq_scalling_matrix_present_flag := bf.ReadNBits(1)
if seq_scalling_matrix_present_flag != 0 {
forlimit := 0
if chroma_format_idc != 3 {
forlimit = 8
} else {
forlimit = 12
}
for i := 0; i < forlimit; i++ {
seq_scaling_list_present_flag := bf.ReadNBits(1)
_ = seq_scaling_list_present_flag
}
}
_ = bit_depth_luma_minus8
_ = bit_depth_chroma_minus8
_ = qpprime_y_zoro_transform_bypass_flag
_ = seq_scalling_matrix_present_flag
}
log2_max_frame_num_minus4 := bf.ReadUExpGolomb()
pic_order_cnt_type := bf.ReadUExpGolomb()
if pic_order_cnt_type == 0 {
log2_max_pic_order_cnt_lsb_minus4 := bf.ReadUExpGolomb()
_ = log2_max_pic_order_cnt_lsb_minus4
} else if pic_order_cnt_type == 1 {
delta_pic_order_always_zero_flag := bf.ReadNBits(1)
offset_for_non_ref_pic := bf.ReadSExpGolomb()
offset_for_top_to_bottom_field := bf.ReadSExpGolomb()
num_ref_frames_in_pic_order_cnt_cycle := bf.ReadUExpGolomb()
for i := 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ {
offset_for_ref_frame := bf.ReadSExpGolomb()
_ = offset_for_ref_frame
}
_ = delta_pic_order_always_zero_flag
_ = offset_for_non_ref_pic
_ = offset_for_top_to_bottom_field
}
max_num_ref_frames := bf.ReadUExpGolomb()
gaps_in_frame_num_value_allowed_flag := bf.ReadNBits(1)
pic_width_in_mbs_minus1 := bf.ReadUExpGolomb()
pic_height_in_map_units_minus1 := bf.ReadUExpGolomb()
frame_mbs_only_flag := bf.ReadNBits(1)
if frame_mbs_only_flag == 0 {
mb_adaptive_frame_field_flag := bf.ReadNBits(1)
_ = mb_adaptive_frame_field_flag
}
direct_8x8_inference_flag := bf.ReadNBits(1)
frame_cropping_flag := bf.ReadNBits(1)
if frame_cropping_flag != 0 {
frame_crop_left_offset := bf.ReadUExpGolomb()
frame_crop_right_offset := bf.ReadUExpGolomb()
frame_crop_top_offset := bf.ReadUExpGolomb()
frame_crop_bottom_offset := bf.ReadUExpGolomb()
// 计算分辨率
width = (pic_width_in_mbs_minus1 + 1) * 16
height = (2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16
crop_unit_x := 2
crop_unit_y := 2 * (2 - frame_mbs_only_flag)
width -= crop_unit_x * (frame_crop_left_offset + frame_crop_right_offset)
height -= crop_unit_y * (frame_crop_top_offset + frame_crop_bottom_offset)
} else {
// 计算分辨率
width = (pic_width_in_mbs_minus1 + 1) * 16
height = (2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16
}
_ = max_num_ref_frames
_ = gaps_in_frame_num_value_allowed_flag
_ = frame_mbs_only_flag
_ = direct_8x8_inference_flag
_ = log2_max_frame_num_minus4
_ = level_idc
_ = sps_id
frm.Width = uint(width)
frm.Height = uint(height)
}