in src/source/codec/sps_decode.c [75:202]
void getH264VideoResolution(char *pSps, size_t uSpsLen, uint16_t *puWidth, uint16_t *puHeight)
{
BitStream_t xBitStream = {.pBuf = (unsigned char *)pSps, .xCurrentBit = 0};
int frame_crop_left_offset = 0;
int frame_crop_right_offset = 0;
int frame_crop_top_offset = 0;
int frame_crop_bottom_offset = 0;
int crop_unit_x = 0;
int crop_unit_y = 0;
int chroma_format_idc = 1;
int profile_idc = uReadBits(&xBitStream, 8);
int constraint_set0_flag = uReadBit(&xBitStream);
int constraint_set1_flag = uReadBit(&xBitStream);
int constraint_set2_flag = uReadBit(&xBitStream);
int constraint_set3_flag = uReadBit(&xBitStream);
int constraint_set4_flag = uReadBit(&xBitStream);
int constraint_set5_flag = uReadBit(&xBitStream);
int reserved_zero_2bits = uReadBits(&xBitStream, 2);
int level_idc = uReadBits(&xBitStream, 8);
int seq_parameter_set_id = uReadExponentialGolombCode(&xBitStream);
int xWidth = 0;
int xHeight = 0;
/* Please refer to https://www.itu.int/rec/T-REC-H.264/ Section 7.4.2.1.1 Sequence parameter set data semantics */
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 || profile_idc == 138 || profile_idc == 139 || profile_idc == 134 || profile_idc == 135)
{
chroma_format_idc = uReadExponentialGolombCode(&xBitStream);
if (chroma_format_idc == 3)
{
int residual_colour_transform_flag = uReadBit(&xBitStream);
}
int bit_depth_luma_minus8 = uReadExponentialGolombCode(&xBitStream);
int bit_depth_chroma_minus8 = uReadExponentialGolombCode(&xBitStream);
int qpprime_y_zero_transform_bypass_flag = uReadBit(&xBitStream);
int seq_scaling_matrix_present_flag = uReadBit(&xBitStream);
if (seq_scaling_matrix_present_flag)
{
int i = 0;
for (i = 0; i < 8; i++)
{
int seq_scaling_list_present_flag = uReadBit(&xBitStream);
if (seq_scaling_list_present_flag)
{
int sizeOfScalingList = (i < 6) ? 16 : 64;
int lastScale = 8;
int nextScale = 8;
int j = 0;
for (j = 0; j < sizeOfScalingList; j++)
{
if (nextScale != 0)
{
int delta_scale = uReadSE(&xBitStream);
nextScale = (lastScale + delta_scale + 256) % 256;
}
lastScale = (nextScale == 0) ? lastScale : nextScale;
}
}
}
}
}
int log2_max_frame_num_minus4 = uReadExponentialGolombCode(&xBitStream);
int pic_order_cnt_type = uReadExponentialGolombCode(&xBitStream);
if (pic_order_cnt_type == 0)
{
int log2_max_pic_order_cnt_lsb_minus4 = uReadExponentialGolombCode(&xBitStream);
}
else if (pic_order_cnt_type == 1)
{
int delta_pic_order_always_zero_flag = uReadBit(&xBitStream);
int offset_for_non_ref_pic = uReadSE(&xBitStream);
int offset_for_top_to_bottom_field = uReadSE(&xBitStream);
int num_ref_frames_in_pic_order_cnt_cycle = uReadExponentialGolombCode(&xBitStream);
int i;
for (i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++)
{
uReadSE(&xBitStream);
}
}
int max_num_ref_frames = uReadExponentialGolombCode(&xBitStream);
int gaps_in_frame_num_value_allowed_flag = uReadBit(&xBitStream);
int pic_width_in_mbs_minus1 = uReadExponentialGolombCode(&xBitStream);
int pic_height_in_map_units_minus1 = uReadExponentialGolombCode(&xBitStream);
int frame_mbs_only_flag = uReadBit(&xBitStream);
if (!frame_mbs_only_flag)
{
int mb_adaptive_frame_field_flag = uReadBit(&xBitStream);
}
int direct_8x8_inference_flag = uReadBit(&xBitStream);
int frame_cropping_flag = uReadBit(&xBitStream);
if (frame_cropping_flag)
{
frame_crop_left_offset = uReadExponentialGolombCode(&xBitStream);
frame_crop_right_offset = uReadExponentialGolombCode(&xBitStream);
frame_crop_top_offset = uReadExponentialGolombCode(&xBitStream);
frame_crop_bottom_offset = uReadExponentialGolombCode(&xBitStream);
if (0 == chroma_format_idc)
{
crop_unit_x = 1;
crop_unit_y = 2 - frame_mbs_only_flag;
}
else if (1 == chroma_format_idc)
{
crop_unit_x = 2;
crop_unit_y = 2 * (2 - frame_mbs_only_flag);
}
else if (2 == chroma_format_idc)
{
crop_unit_x = 2;
crop_unit_y = 2 - frame_mbs_only_flag;
}
else
{
crop_unit_x = 1;
crop_unit_y = 2 - frame_mbs_only_flag;
}
}
xWidth = ((pic_width_in_mbs_minus1 + 1) * 16) - crop_unit_x * (frame_crop_left_offset + frame_crop_right_offset);
xHeight = ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16) - crop_unit_y * (frame_crop_top_offset + frame_crop_bottom_offset);
*puWidth = (uint16_t)xWidth;
*puHeight = (uint16_t)xHeight;
}