avc_utils.cpp revision 6a63a939601645404fd98f58c19cc38ca818d99e
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 if (profile_idc == 100 || profile_idc == 110 45 || profile_idc == 122 || profile_idc == 244 46 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { 47 unsigned chroma_format_idc = parseUE(&br); 48 if (chroma_format_idc == 3) { 49 br.skipBits(1); // residual_colour_transform_flag 50 } 51 parseUE(&br); // bit_depth_luma_minus8 52 parseUE(&br); // bit_depth_chroma_minus8 53 br.skipBits(1); // qpprime_y_zero_transform_bypass_flag 54 CHECK_EQ(br.getBits(1), 0u); // seq_scaling_matrix_present_flag 55 } 56 57 parseUE(&br); // log2_max_frame_num_minus4 58 unsigned pic_order_cnt_type = parseUE(&br); 59 60 if (pic_order_cnt_type == 0) { 61 parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 62 } else if (pic_order_cnt_type == 1) { 63 // offset_for_non_ref_pic, offset_for_top_to_bottom_field and 64 // offset_for_ref_frame are technically se(v), but since we are 65 // just skipping over them the midpoint does not matter. 66 67 br.getBits(1); // delta_pic_order_always_zero_flag 68 parseUE(&br); // offset_for_non_ref_pic 69 parseUE(&br); // offset_for_top_to_bottom_field 70 71 unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); 72 for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { 73 parseUE(&br); // offset_for_ref_frame 74 } 75 } 76 77 parseUE(&br); // num_ref_frames 78 br.getBits(1); // gaps_in_frame_num_value_allowed_flag 79 80 unsigned pic_width_in_mbs_minus1 = parseUE(&br); 81 unsigned pic_height_in_map_units_minus1 = parseUE(&br); 82 unsigned frame_mbs_only_flag = br.getBits(1); 83 84 *width = pic_width_in_mbs_minus1 * 16 + 16; 85 86 *height = (2 - frame_mbs_only_flag) 87 * (pic_height_in_map_units_minus1 * 16 + 16); 88} 89 90} // namespace android 91 92