185f12e9b9062402d6110df3f7099707912040edbAndreas Huber/* 285f12e9b9062402d6110df3f7099707912040edbAndreas Huber * Copyright (C) 2010 The Android Open Source Project 385f12e9b9062402d6110df3f7099707912040edbAndreas Huber * 485f12e9b9062402d6110df3f7099707912040edbAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 585f12e9b9062402d6110df3f7099707912040edbAndreas Huber * you may not use this file except in compliance with the License. 685f12e9b9062402d6110df3f7099707912040edbAndreas Huber * You may obtain a copy of the License at 785f12e9b9062402d6110df3f7099707912040edbAndreas Huber * 885f12e9b9062402d6110df3f7099707912040edbAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 985f12e9b9062402d6110df3f7099707912040edbAndreas Huber * 1085f12e9b9062402d6110df3f7099707912040edbAndreas Huber * Unless required by applicable law or agreed to in writing, software 1185f12e9b9062402d6110df3f7099707912040edbAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1285f12e9b9062402d6110df3f7099707912040edbAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1385f12e9b9062402d6110df3f7099707912040edbAndreas Huber * See the License for the specific language governing permissions and 1485f12e9b9062402d6110df3f7099707912040edbAndreas Huber * limitations under the License. 1585f12e9b9062402d6110df3f7099707912040edbAndreas Huber */ 1685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 175bc087c573c70c84c6a39946457590b42d392a33Andreas Huber//#define LOG_NDEBUG 0 185bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#define LOG_TAG "avc_utils" 195bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#include <utils/Log.h> 205bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 2185f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "include/avc_utils.h" 2285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 2385f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include <media/stagefright/foundation/ABitReader.h> 2485f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include <media/stagefright/foundation/ADebug.h> 25516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber#include <media/stagefright/foundation/hexdump.h> 26c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MediaDefs.h> 27c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MediaErrors.h> 28c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MetaData.h> 2985f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3085f12e9b9062402d6110df3f7099707912040edbAndreas Hubernamespace android { 3185f12e9b9062402d6110df3f7099707912040edbAndreas Huber 326a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberunsigned parseUE(ABitReader *br) { 3385f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned numZeroes = 0; 3485f12e9b9062402d6110df3f7099707912040edbAndreas Huber while (br->getBits(1) == 0) { 3585f12e9b9062402d6110df3f7099707912040edbAndreas Huber ++numZeroes; 3685f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 3785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3885f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned x = br->getBits(numZeroes); 3985f12e9b9062402d6110df3f7099707912040edbAndreas Huber 4085f12e9b9062402d6110df3f7099707912040edbAndreas Huber return x + (1u << numZeroes) - 1; 4185f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 4285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 436dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Hubersigned parseSE(ABitReader *br) { 446dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber unsigned codeNum = parseUE(br); 456dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 466dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber return (codeNum & 1) ? (codeNum + 1) / 2 : -(codeNum / 2); 476dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber} 486dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 496dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huberstatic void skipScalingList(ABitReader *br, size_t sizeOfScalingList) { 506dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber size_t lastScale = 8; 516dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber size_t nextScale = 8; 526dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber for (size_t j = 0; j < sizeOfScalingList; ++j) { 536dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (nextScale != 0) { 546dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber signed delta_scale = parseSE(br); 556dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber nextScale = (lastScale + delta_scale + 256) % 256; 566dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 576dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 586dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber lastScale = (nextScale == 0) ? lastScale : nextScale; 596dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 606dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber} 616dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 6285f12e9b9062402d6110df3f7099707912040edbAndreas Huber// Determine video dimensions from the sequence parameterset. 6385f12e9b9062402d6110df3f7099707912040edbAndreas Hubervoid FindAVCDimensions( 64516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber const sp<ABuffer> &seqParamSet, 65516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t *width, int32_t *height, 66516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t *sarWidth, int32_t *sarHeight) { 6785f12e9b9062402d6110df3f7099707912040edbAndreas Huber ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); 6885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 6985f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned profile_idc = br.getBits(8); 7085f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(16); 7185f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // seq_parameter_set_id 7285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 732d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned chroma_format_idc = 1; // 4:2:0 chroma format 742d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 7585f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (profile_idc == 100 || profile_idc == 110 7685f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 122 || profile_idc == 244 7785f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { 782d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber chroma_format_idc = parseUE(&br); 7985f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (chroma_format_idc == 3) { 8085f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // residual_colour_transform_flag 8185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 8285f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_luma_minus8 8385f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_chroma_minus8 8485f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // qpprime_y_zero_transform_bypass_flag 856dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 866dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (br.getBits(1)) { // seq_scaling_matrix_present_flag 876dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber for (size_t i = 0; i < 8; ++i) { 886dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (br.getBits(1)) { // seq_scaling_list_present_flag[i] 896dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 906dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // WARNING: the code below has not ever been exercised... 916dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // need a real-world example. 926dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 936dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (i < 6) { 946dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // ScalingList4x4[i],16,... 956dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber skipScalingList(&br, 16); 966dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } else { 976dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // ScalingList8x8[i-6],64,... 986dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber skipScalingList(&br, 64); 996dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1006dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1016dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1026dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_frame_num_minus4 10685f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_order_cnt_type = parseUE(&br); 10785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 10885f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (pic_order_cnt_type == 0) { 10985f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 11085f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (pic_order_cnt_type == 1) { 11185f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_non_ref_pic, offset_for_top_to_bottom_field and 11285f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_ref_frame are technically se(v), but since we are 11385f12e9b9062402d6110df3f7099707912040edbAndreas Huber // just skipping over them the midpoint does not matter. 11485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 11585f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // delta_pic_order_always_zero_flag 11685f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_non_ref_pic 11785f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_top_to_bottom_field 11885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 11985f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); 12085f12e9b9062402d6110df3f7099707912040edbAndreas Huber for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { 12185f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_ref_frame 12285f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 12385f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 12485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 12585f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // num_ref_frames 12685f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // gaps_in_frame_num_value_allowed_flag 12785f12e9b9062402d6110df3f7099707912040edbAndreas Huber 12885f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_width_in_mbs_minus1 = parseUE(&br); 12985f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_height_in_map_units_minus1 = parseUE(&br); 13085f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned frame_mbs_only_flag = br.getBits(1); 13185f12e9b9062402d6110df3f7099707912040edbAndreas Huber 13285f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = pic_width_in_mbs_minus1 * 16 + 16; 13385f12e9b9062402d6110df3f7099707912040edbAndreas Huber 13485f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = (2 - frame_mbs_only_flag) 13585f12e9b9062402d6110df3f7099707912040edbAndreas Huber * (pic_height_in_map_units_minus1 * 16 + 16); 1362d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1372d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (!frame_mbs_only_flag) { 1382d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // mb_adaptive_frame_field_flag 1392d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1402d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1412d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // direct_8x8_inference_flag 1422d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1432d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (br.getBits(1)) { // frame_cropping_flag 1442d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_left_offset = parseUE(&br); 1452d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_right_offset = parseUE(&br); 1462d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_top_offset = parseUE(&br); 1472d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_bottom_offset = parseUE(&br); 1482d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1492d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned cropUnitX, cropUnitY; 1502d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (chroma_format_idc == 0 /* monochrome */) { 1512d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = 1; 1522d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = 2 - frame_mbs_only_flag; 1532d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } else { 1542d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2; 1552d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1; 1562d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1572d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = subWidthC; 1582d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = subHeightC * (2 - frame_mbs_only_flag); 1592d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1602d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u", 1622d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_left_offset, frame_crop_right_offset, 1632d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_top_offset, frame_crop_bottom_offset, 1642d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX, cropUnitY); 1652d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1662d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *width -= 1672d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX; 1682d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *height -= 1692d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; 1702d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 171516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 172516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarWidth != NULL) { 173516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarWidth = 0; 174516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 175516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 176516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarHeight != NULL) { 177516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarHeight = 0; 178516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 180516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (br.getBits(1)) { // vui_parameters_present_flag 181516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber unsigned sar_width = 0, sar_height = 0; 182516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (br.getBits(1)) { // aspect_ratio_info_present_flag 184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber unsigned aspect_ratio_idc = br.getBits(8); 185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 186516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (aspect_ratio_idc == 255 /* extendedSAR */) { 187516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_width = br.getBits(16); 188516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_height = br.getBits(16); 189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } else if (aspect_ratio_idc > 0 && aspect_ratio_idc < 14) { 190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber static const int32_t kFixedSARWidth[] = { 191516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160 192516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber }; 193516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 194516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber static const int32_t kFixedSARHeight[] = { 195516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99 196516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber }; 197516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 198516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_width = kFixedSARWidth[aspect_ratio_idc - 1]; 199516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_height = kFixedSARHeight[aspect_ratio_idc - 1]; 200516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 201516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 202516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 203516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGV("sample aspect ratio = %u : %u", sar_width, sar_height); 204516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 205516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarWidth != NULL) { 206516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarWidth = sar_width; 207516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 208516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 209516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarHeight != NULL) { 210516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarHeight = sar_height; 211516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 212516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 21385f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 21485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 215c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberstatus_t getNextNALUnit( 216c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **_data, size_t *_size, 217c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **nalStart, size_t *nalSize, 218c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool startCodeFollows) { 219c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = *_data; 220c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = *_size; 221c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 222c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = NULL; 223c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = 0; 224c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 22515ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (size < 3) { 226c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 227c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 228c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 229c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t offset = 0; 230c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 231c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // A valid startcode consists of at least two 0x00 bytes followed by 0x01. 23215ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia for (; offset + 2 < size; ++offset) { 23315ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (data[offset + 2] == 0x01 && data[offset] == 0x00 23415ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia && data[offset + 1] == 0x00) { 23515ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia break; 23615ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia } 237c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 23815ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (offset + 2 >= size) { 23915ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia *_data = &data[offset]; 24015ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia *_size = 2; 24115ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia return -EAGAIN; 24215ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia } 24315ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia offset += 3; 244c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 245c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t startOffset = offset; 246c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 247c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber for (;;) { 248c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (offset < size && data[offset] != 0x01) { 249c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 250c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 251c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 252c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset == size) { 253c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (startCodeFollows) { 254c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber offset = size + 2; 255c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 256c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 257c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 258c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 259c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 260c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 261c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) { 262c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 263c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 264c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 265c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 266c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 267c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 268c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t endOffset = offset - 2; 2697f048fdd69753e0ba95d3ef1484b30bcf39164c0Andreas Huber while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) { 270c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber --endOffset; 271c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 272c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 273c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = &data[startOffset]; 274c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = endOffset - startOffset; 275c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 276c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset + 2 < size) { 277c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = &data[offset - 2]; 278c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = size - offset + 2; 279c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } else { 280c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = NULL; 281c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = 0; 282c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 283c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 284c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return OK; 285c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 286c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 28784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatic sp<ABuffer> FindNAL(const uint8_t *data, size_t size, unsigned nalType) { 288c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 289c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 290c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 291c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if ((nalStart[0] & 0x1f) == nalType) { 292c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> buffer = new ABuffer(nalSize); 293c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(buffer->data(), nalStart, nalSize); 294c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return buffer; 295c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 296c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 297c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 298c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 299c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 300c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 301bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huberconst char *AVCProfileToString(uint8_t profile) { 302bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber switch (profile) { 303bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileBaseline: 304bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Baseline"; 305bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileMain: 306bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Main"; 307bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileExtended: 308bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Extended"; 309bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh: 310bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High"; 311bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh10: 312bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 10"; 313bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh422: 314bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 422"; 315bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh444: 316bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 444"; 317bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileCAVLC444Intra: 318bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "CAVLC 444 Intra"; 319bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber default: return "Unknown"; 320bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber } 321bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber} 322bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 323c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Hubersp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) { 324c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = accessUnit->data(); 325c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = accessUnit->size(); 326c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 32784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber sp<ABuffer> seqParamSet = FindNAL(data, size, 7); 328c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (seqParamSet == NULL) { 329c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 330c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 331c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 332c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber int32_t width, height; 333516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 334516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber FindAVCDimensions( 335516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber seqParamSet, &width, &height, &sarWidth, &sarHeight); 336c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 33784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber sp<ABuffer> picParamSet = FindNAL(data, size, 8); 338c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber CHECK(picParamSet != NULL); 339c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 340c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t csdSize = 341c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 1 + 3 + 1 + 1 342c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 2 * 1 + seqParamSet->size() 343c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 1 + 2 * 1 + picParamSet->size(); 344c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 345c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 346c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber uint8_t *out = csd->data(); 347c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 348c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0x01; // configurationVersion 349c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data() + 1, 3); // profile/level... 350bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 351bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t profile = out[0]; 352bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t level = out[2]; 353bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 354c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += 3; 355c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 356c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0xe0 | 1; 357c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 358c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() >> 8; 359c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() & 0xff; 360c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data(), seqParamSet->size()); 361c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += seqParamSet->size(); 362c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 363c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 1; 364c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 365c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() >> 8; 366c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() & 0xff; 367c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, picParamSet->data(), picParamSet->size()); 368c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 369c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#if 0 370df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("AVC seq param set"); 371c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber hexdump(seqParamSet->data(), seqParamSet->size()); 372c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#endif 373c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 374c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<MetaData> meta = new MetaData; 375c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 376c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 377c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size()); 378c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyWidth, width); 379c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyHeight, height); 380c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 381516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarWidth > 1 || sarHeight > 1) { 382516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber // We treat 0:0 (unspecified) as 1:1. 383516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 384516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARWidth, sarWidth); 385516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARHeight, sarHeight); 386516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 387516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) " 388516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber "SAR %d : %d", 389516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber width, 390516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber height, 391516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber AVCProfileToString(profile), 392516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level / 10, 393516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level % 10, 394516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sarWidth, 395516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sarHeight); 396516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } else { 397516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)", 398516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber width, 399516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber height, 400516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber AVCProfileToString(profile), 401516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level / 10, 402516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level % 10); 403516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 404c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 405c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return meta; 406c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 407c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 408c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberbool IsIDR(const sp<ABuffer> &buffer) { 409c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = buffer->data(); 410c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = buffer->size(); 411c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 412c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool foundIDR = false; 413c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 414c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 415c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 416c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 417c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber CHECK_GT(nalSize, 0u); 418c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 419c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber unsigned nalType = nalStart[0] & 0x1f; 420c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 421c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (nalType == 5) { 422c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber foundIDR = true; 423c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 424c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 425c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 426c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 427c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return foundIDR; 428c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 429c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 4303fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huberbool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) { 4313fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *data = accessUnit->data(); 4323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t size = accessUnit->size(); 4333fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4343fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *nalStart; 4353fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t nalSize; 4363fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 4373fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber CHECK_GT(nalSize, 0u); 4383fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nalType = nalStart[0] & 0x1f; 4403fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4413fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (nalType == 5) { 4423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 4433fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else if (nalType == 1) { 4443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nal_ref_idc = (nalStart[0] >> 5) & 3; 4453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return nal_ref_idc != 0; 4463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 4473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 4483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4493fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 4503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber} 4513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 45250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> MakeAACCodecSpecificData( 45350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned profile, unsigned sampling_freq_index, 45450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned channel_configuration) { 45550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<MetaData> meta = new MetaData; 45650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 45750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 45850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang CHECK_LE(sampling_freq_index, 11u); 45950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const int32_t kSamplingFreq[] = { 46050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 46150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 16000, 12000, 11025, 8000 46250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 46350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]); 46450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeyChannelCount, channel_configuration); 46550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 46650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const uint8_t kStaticESDS[] = { 46750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x03, 22, 46850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, // ES_ID 46950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 47050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 47150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x04, 17, 47250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x40, // Audio ISO/IEC 14496-3 47350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 47450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 47550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 47650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 47750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x05, 2, 47850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // AudioSpecificInfo follows 47950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 48050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // oooo offf fccc c000 48150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // o - audioObjectType 48250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // f - samplingFreqIndex 48350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // c - channelConfig 48450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 48550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 48650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 48750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 48850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS)] = 48950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((profile + 1) << 3) | (sampling_freq_index >> 1); 49050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 49150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS) + 1] = 49250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3); 49350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 49450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setData(kKeyESDS, 0, csd->data(), csd->size()); 49550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 49650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return meta; 49750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 49850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 499386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool ExtractDimensionsFromVOLHeader( 500386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber const uint8_t *data, size_t size, int32_t *width, int32_t *height) { 501386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ABitReader br(&data[4], size - 4); 502386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // random_accessible_vol 503386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_type_indication = br.getBits(8); 504386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 505386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_NE(video_object_type_indication, 506386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 0x21u /* Fine Granularity Scalable */); 507386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 508386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_verid; 509386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_priority; 510386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { 511386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_verid = br.getBits(4); 512386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_priority = br.getBits(3); 513386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 514386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned aspect_ratio_info = br.getBits(4); 515386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (aspect_ratio_info == 0x0f /* extended PAR */) { 516386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_width 517386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_height 518386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 519386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vol_control_parameters 520386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(2); // chroma_format 521386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // low_delay 522386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vbv_parameters 523386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_bit_rate 524386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 525386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_bit_rate 526386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 527386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_vbv_buffer_size 528386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 529386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(3); // latter_half_vbv_buffer_size 530386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(11); // first_half_vbv_occupancy 531386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 532386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_vbv_occupancy 533386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 534386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 535386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 536386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_shape = br.getBits(2); 537386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */); 538386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 539386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 540386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned vop_time_increment_resolution = br.getBits(16); 541386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 542386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 543386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // fixed_vop_rate 544386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // range [0..vop_time_increment_resolution) 545386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 546386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // vop_time_increment_resolution 547386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 2 => 0..1, 1 bit 548386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 3 => 0..2, 2 bits 549386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 4 => 0..3, 2 bits 550386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 5 => 0..4, 3 bits 551386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // ... 552386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 553386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_GT(vop_time_increment_resolution, 0u); 554386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber --vop_time_increment_resolution; 555386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 556386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned numBits = 0; 557386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber while (vop_time_increment_resolution > 0) { 558386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ++numBits; 559386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber vop_time_increment_resolution >>= 1; 560386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 561386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 562386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(numBits); // fixed_vop_time_increment 563386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 564386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 565386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 566386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_width = br.getBits(13); 567386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 568386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_height = br.getBits(13); 569386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 570386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 571386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned interlaced = br.getBits(1); 572386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 573386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *width = video_object_layer_width; 574386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *height = video_object_layer_height; 575386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 576386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 577386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 578386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 579386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool GetMPEGAudioFrameSize( 580386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber uint32_t header, size_t *frame_size, 581386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_sampling_rate, int *out_channels, 582386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_bitrate, int *out_num_samples) { 583386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 0; 584386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 585386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 586386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = 0; 587386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 588386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 589386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 590386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = 0; 591386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 592386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 593386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 594386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = 0; 595386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 596386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 597386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 598386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 599386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 600386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 601386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if ((header & 0xffe00000) != 0xffe00000) { 602386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 603386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 604386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 605386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned version = (header >> 19) & 3; 606386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 607386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 0x01) { 608386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 609386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned layer = (header >> 17) & 3; 612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 613386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 0x00) { 614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 616386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned protection = (header >> 16) & 1; 618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned bitrate_index = (header >> 12) & 0x0f; 620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (bitrate_index == 0 || bitrate_index == 0x0f) { 622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // Disallow "free" bitrate. 623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned sampling_rate_index = (header >> 10) & 3; 627386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 628386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (sampling_rate_index == 3) { 629386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 630386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 631386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 632386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; 633386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int sampling_rate = kSamplingRateV1[sampling_rate_index]; 634386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 2 /* V2 */) { 635386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 2; 636386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else if (version == 0 /* V2.5 */) { 637386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 4; 638386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 639386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 640386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned padding = (header >> 9) & 1; 641386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 642386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 3) { 643386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer I 644386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 645386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1[] = { 646386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 64, 96, 128, 160, 192, 224, 256, 647386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 288, 320, 352, 384, 416, 448 648386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 649386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 650386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 651386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 652386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 144, 160, 176, 192, 224, 256 653386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 654386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 655386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate = 656386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber (version == 3 /* V1 */) 657386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1[bitrate_index - 1] 658386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV2[bitrate_index - 1]; 659386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 660386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 661386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 662386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 663386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 664386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; 665386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 666386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 667386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 384; 668386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 669386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 670386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer II or III 671386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 672386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L2[] = { 673386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 674386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 160, 192, 224, 256, 320, 384 675386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 676386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 677386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L3[] = { 678386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 40, 48, 56, 64, 80, 96, 112, 679386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 128, 160, 192, 224, 256, 320 680386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 681386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 682386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 683386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 8, 16, 24, 32, 40, 48, 56, 64, 684386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 80, 96, 112, 128, 144, 160 685386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 686386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 687386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate; 688386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 689386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = (layer == 2 /* L2 */) 690386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1L2[bitrate_index - 1] 691386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV1L3[bitrate_index - 1]; 692386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 693386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 694386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 695386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 696386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 697386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 (or 2.5) 698386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 699386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = kBitrateV2[bitrate_index - 1]; 700386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 701a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152; 702386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 703386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 704386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 705386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 706386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 707386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 708386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 709386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 710386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 144000 * bitrate / sampling_rate + padding; 711386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 712386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 or V2.5 713a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000; 714a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *frame_size = tmp * bitrate / sampling_rate + padding; 715386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 716386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 717386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 718386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 719386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = sampling_rate; 720386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 721386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 722386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 723386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int channel_mode = (header >> 6) & 3; 724386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 725386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = (channel_mode == 3) ? 1 : 2; 726386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 727386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 728386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 729386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 730386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 73185f12e9b9062402d6110df3f7099707912040edbAndreas Huber} // namespace android 73285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 733