//7.3.2.1 Sequence parameter set RBSP syntax void read_seq_parameter_set_rbsp(sps_t *sps, bs_t* b) { int i; // NOTE can't read directly into sps because seq_parameter_set_id not yet known and so sps is not selected int profile_idc = bs_read(b, 8); int constraint_set0_flag = bs_read(b, 1); int constraint_set1_flag = bs_read(b, 1); int constraint_set2_flag = bs_read(b, 1); int constraint_set3_flag = bs_read(b, 1); int constraint_set4_flag = bs_read(b, 1); int constraint_set5_flag = bs_read(b, 1); int reserved_zero_2bits = bs_read(b, 2); /* all 0's */ int level_idc = bs_read(b, 8); int seq_parameter_set_id = bs_read_ue(b); memset(sps, 0, sizeof(sps_t)); sps->chroma_format_idc = 1; sps->profile_idc = profile_idc; // bs_read(b, 8); sps->constraint_set0_flag = constraint_set0_flag;//bs_read(b, 1); sps->constraint_set1_flag = constraint_set1_flag;//bs_read(b, 1); sps->constraint_set2_flag = constraint_set2_flag;//bs_read(b, 1); sps->constraint_set3_flag = constraint_set3_flag;//bs_read(b, 1); sps->constraint_set4_flag = constraint_set4_flag;//bs_read(b, 1); sps->constraint_set5_flag = constraint_set5_flag;//bs_read(b, 1); sps->reserved_zero_2bits = reserved_zero_2bits;//bs_read(b,2); sps->level_idc = level_idc; //bs_read(b, 8); sps->seq_parameter_set_id = seq_parameter_set_id; // bs_read_ue(b); if (sps->profile_idc == 100 || sps->profile_idc == 110 || sps->profile_idc == 122 || sps->profile_idc == 144) { sps->chroma_format_idc = bs_read_ue(b); if (sps->chroma_format_idc == 3) { sps->residual_colour_transform_flag = bs_read(b, 1); } sps->bit_depth_luma_minus8 = bs_read_ue(b); sps->bit_depth_chroma_minus8 = bs_read_ue(b); sps->qpprime_y_zero_transform_bypass_flag = bs_read(b, 1); sps->seq_scaling_matrix_present_flag = bs_read(b, 1); if (sps->seq_scaling_matrix_present_flag) { for (i = 0; i < 8; i++) { sps->seq_scaling_list_present_flag[i] = bs_read(b, 1); if (sps->seq_scaling_list_present_flag[i]) { if (i < 6) { read_scaling_list(b, sps->ScalingList4x4[i], 16, sps->UseDefaultScalingMatrix4x4Flag[i]); } else { read_scaling_list(b, sps->ScalingList8x8[i - 6], 64, sps->UseDefaultScalingMatrix8x8Flag[i - 6]); } } } } } sps->log2_max_frame_num_minus4 = bs_read_ue(b); sps->pic_order_cnt_type = bs_read_ue(b); if (sps->pic_order_cnt_type == 0) { sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b); } else if (sps->pic_order_cnt_type == 1) { sps->delta_pic_order_always_zero_flag = bs_read(b, 1); sps->offset_for_non_ref_pic = bs_read_se(b); sps->offset_for_top_to_bottom_field = bs_read_se(b); sps->num_ref_frames_in_pic_order_cnt_cycle = bs_read_ue(b); for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) { sps->offset_for_ref_frame[i] = bs_read_se(b); } } sps->num_ref_frames = bs_read_ue(b); sps->gaps_in_frame_num_value_allowed_flag = bs_read(b, 1); sps->pic_width_in_mbs_minus1 = bs_read_ue(b); sps->pic_height_in_map_units_minus1 = bs_read_ue(b); sps->frame_mbs_only_flag = bs_read(b, 1); if (!sps->frame_mbs_only_flag) { sps->mb_adaptive_frame_field_flag = bs_read(b, 1); } sps->direct_8x8_inference_flag = bs_read(b, 1); sps->frame_cropping_flag = bs_read(b, 1); if (sps->frame_cropping_flag) { sps->frame_crop_left_offset = bs_read_ue(b); sps->frame_crop_right_offset = bs_read_ue(b); sps->frame_crop_top_offset = bs_read_ue(b); sps->frame_crop_bottom_offset = bs_read_ue(b); } sps->vui_parameters_present_flag = bs_read(b, 1); if (sps->vui_parameters_present_flag) { read_vui_parameters(sps, b); } //read_rbsp_trailing_bits(h, b); }
// Determine video dimensions from the sequence parameterset. void FindAVCDimensions( const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height) { ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); unsigned profile_idc = br.getBits(8); br.skipBits(16); parseUE(&br); // seq_parameter_set_id unsigned chroma_format_idc = 1; // 4:2:0 chroma format if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { uint32_t temp = 0; chroma_format_idc = parseUE(&br); if (chroma_format_idc == 3) { br.skipBits(1); // residual_colour_transform_flag } parseUE(&br); // bit_depth_luma_minus8 parseUE(&br); // bit_depth_chroma_minus8 br.skipBits(1); // qpprime_y_zero_transform_bypass_flag temp = br.getBits(1); // seq_scaling_matrix_present_flag if(temp) { int32_t i; for (i = 0; i < 6; i++) { temp = br.getBits(1); ; if (temp) { read_scaling_list(&br, 0); } } for (i = 0; i < 2; i++) { temp = br.getBits(1); ; if (temp) { read_scaling_list(&br, 1); } } } } parseUE(&br); // log2_max_frame_num_minus4 unsigned pic_order_cnt_type = parseUE(&br); if (pic_order_cnt_type == 0) { parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 } else if (pic_order_cnt_type == 1) { // offset_for_non_ref_pic, offset_for_top_to_bottom_field and // offset_for_ref_frame are technically se(v), but since we are // just skipping over them the midpoint does not matter. br.getBits(1); // delta_pic_order_always_zero_flag parseUE(&br); // offset_for_non_ref_pic parseUE(&br); // offset_for_top_to_bottom_field unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { parseUE(&br); // offset_for_ref_frame } } parseUE(&br); // num_ref_frames br.getBits(1); // gaps_in_frame_num_value_allowed_flag unsigned pic_width_in_mbs_minus1 = parseUE(&br); unsigned pic_height_in_map_units_minus1 = parseUE(&br); unsigned frame_mbs_only_flag = br.getBits(1); *width = pic_width_in_mbs_minus1 * 16 + 16; *height = (2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 * 16 + 16); if (!frame_mbs_only_flag) { br.getBits(1); // mb_adaptive_frame_field_flag } br.getBits(1); // direct_8x8_inference_flag if (br.getBits(1)) { // frame_cropping_flag unsigned frame_crop_left_offset = parseUE(&br); unsigned frame_crop_right_offset = parseUE(&br); unsigned frame_crop_top_offset = parseUE(&br); unsigned frame_crop_bottom_offset = parseUE(&br); unsigned cropUnitX, cropUnitY; if (chroma_format_idc == 0 /* monochrome */) { cropUnitX = 1; cropUnitY = 2 - frame_mbs_only_flag; } else { unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2; unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1; cropUnitX = subWidthC; cropUnitY = subHeightC * (2 - frame_mbs_only_flag); } ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u", frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, frame_crop_bottom_offset, cropUnitX, cropUnitY); *width -= (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX; *height -= (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; } }