avc_utils.cpp revision 2d511ff0eb4c6127659795b642825c55879a15bc
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "include/avc_utils.h" 18 19#include <media/stagefright/foundation/ABitReader.h> 20#include <media/stagefright/foundation/ADebug.h> 21 22namespace android { 23 24unsigned parseUE(ABitReader *br) { 25 unsigned numZeroes = 0; 26 while (br->getBits(1) == 0) { 27 ++numZeroes; 28 } 29 30 unsigned x = br->getBits(numZeroes); 31 32 return x + (1u << numZeroes) - 1; 33} 34 35// Determine video dimensions from the sequence parameterset. 36void FindAVCDimensions( 37 const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height) { 38 ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); 39 40 unsigned profile_idc = br.getBits(8); 41 br.skipBits(16); 42 parseUE(&br); // seq_parameter_set_id 43 44 unsigned chroma_format_idc = 1; // 4:2:0 chroma format 45 46 if (profile_idc == 100 || profile_idc == 110 47 || profile_idc == 122 || profile_idc == 244 48 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { 49 chroma_format_idc = parseUE(&br); 50 if (chroma_format_idc == 3) { 51 br.skipBits(1); // residual_colour_transform_flag 52 } 53 parseUE(&br); // bit_depth_luma_minus8 54 parseUE(&br); // bit_depth_chroma_minus8 55 br.skipBits(1); // qpprime_y_zero_transform_bypass_flag 56 CHECK_EQ(br.getBits(1), 0u); // seq_scaling_matrix_present_flag 57 } 58 59 parseUE(&br); // log2_max_frame_num_minus4 60 unsigned pic_order_cnt_type = parseUE(&br); 61 62 if (pic_order_cnt_type == 0) { 63 parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 64 } else if (pic_order_cnt_type == 1) { 65 // offset_for_non_ref_pic, offset_for_top_to_bottom_field and 66 // offset_for_ref_frame are technically se(v), but since we are 67 // just skipping over them the midpoint does not matter. 68 69 br.getBits(1); // delta_pic_order_always_zero_flag 70 parseUE(&br); // offset_for_non_ref_pic 71 parseUE(&br); // offset_for_top_to_bottom_field 72 73 unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); 74 for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { 75 parseUE(&br); // offset_for_ref_frame 76 } 77 } 78 79 parseUE(&br); // num_ref_frames 80 br.getBits(1); // gaps_in_frame_num_value_allowed_flag 81 82 unsigned pic_width_in_mbs_minus1 = parseUE(&br); 83 unsigned pic_height_in_map_units_minus1 = parseUE(&br); 84 unsigned frame_mbs_only_flag = br.getBits(1); 85 86 *width = pic_width_in_mbs_minus1 * 16 + 16; 87 88 *height = (2 - frame_mbs_only_flag) 89 * (pic_height_in_map_units_minus1 * 16 + 16); 90 91 if (!frame_mbs_only_flag) { 92 br.getBits(1); // mb_adaptive_frame_field_flag 93 } 94 95 br.getBits(1); // direct_8x8_inference_flag 96 97 if (br.getBits(1)) { // frame_cropping_flag 98 unsigned frame_crop_left_offset = parseUE(&br); 99 unsigned frame_crop_right_offset = parseUE(&br); 100 unsigned frame_crop_top_offset = parseUE(&br); 101 unsigned frame_crop_bottom_offset = parseUE(&br); 102 103 unsigned cropUnitX, cropUnitY; 104 if (chroma_format_idc == 0 /* monochrome */) { 105 cropUnitX = 1; 106 cropUnitY = 2 - frame_mbs_only_flag; 107 } else { 108 unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2; 109 unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1; 110 111 cropUnitX = subWidthC; 112 cropUnitY = subHeightC * (2 - frame_mbs_only_flag); 113 } 114 115 LOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u", 116 frame_crop_left_offset, frame_crop_right_offset, 117 frame_crop_top_offset, frame_crop_bottom_offset, 118 cropUnitX, cropUnitY); 119 120 *width -= 121 (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX; 122 *height -= 123 (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; 124 } 125} 126 127} // namespace android 128 129