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> 29d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang#include <utils/misc.h> 3085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3185f12e9b9062402d6110df3f7099707912040edbAndreas Hubernamespace android { 3285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 336a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberunsigned parseUE(ABitReader *br) { 3485f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned numZeroes = 0; 3585f12e9b9062402d6110df3f7099707912040edbAndreas Huber while (br->getBits(1) == 0) { 3685f12e9b9062402d6110df3f7099707912040edbAndreas Huber ++numZeroes; 3785f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 3885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3985f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned x = br->getBits(numZeroes); 4085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 4185f12e9b9062402d6110df3f7099707912040edbAndreas Huber return x + (1u << numZeroes) - 1; 4285f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 4385f12e9b9062402d6110df3f7099707912040edbAndreas Huber 442f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnarunsigned parseUEWithFallback(ABitReader *br, unsigned fallback) { 452f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar unsigned numZeroes = 0; 462f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar while (br->getBitsWithFallback(1, 1) == 0) { 472f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar ++numZeroes; 482f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } 492f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar uint32_t x; 502f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar if (numZeroes < 32) { 512f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar if (br->getBitsGraceful(numZeroes, &x)) { 522f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar return x + (1u << numZeroes) - 1; 532f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } else { 542f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar return fallback; 552f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } 562f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } else { 572f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar br->skipBits(numZeroes); 582f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar return fallback; 592f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } 602f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar} 612f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar 626dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Hubersigned parseSE(ABitReader *br) { 636dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber unsigned codeNum = parseUE(br); 646dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 650bdc87aafc5dfe094680c0c7e77131ac20c22a84Marco Nelissen return (codeNum & 1) ? (codeNum + 1) / 2 : -signed(codeNum / 2); 666dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber} 676dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 682f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnarsigned parseSEWithFallback(ABitReader *br, signed fallback) { 692f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar // NOTE: parseUE cannot normally return ~0 as the max supported value is 0xFFFE 702f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar unsigned codeNum = parseUEWithFallback(br, ~0U); 712f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar if (codeNum == ~0U) { 722f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar return fallback; 732f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar } 740bdc87aafc5dfe094680c0c7e77131ac20c22a84Marco Nelissen return (codeNum & 1) ? (codeNum + 1) / 2 : -signed(codeNum / 2); 752f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar} 762f4555e2080b7bd9933924840e70a1d4fc87ecb2Lajos Molnar 776dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huberstatic void skipScalingList(ABitReader *br, size_t sizeOfScalingList) { 786dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber size_t lastScale = 8; 796dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber size_t nextScale = 8; 806dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber for (size_t j = 0; j < sizeOfScalingList; ++j) { 816dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (nextScale != 0) { 826dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber signed delta_scale = parseSE(br); 836dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber nextScale = (lastScale + delta_scale + 256) % 256; 846dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 856dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 866dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber lastScale = (nextScale == 0) ? lastScale : nextScale; 876dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 886dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber} 896dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 9085f12e9b9062402d6110df3f7099707912040edbAndreas Huber// Determine video dimensions from the sequence parameterset. 9185f12e9b9062402d6110df3f7099707912040edbAndreas Hubervoid FindAVCDimensions( 92516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber const sp<ABuffer> &seqParamSet, 93516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t *width, int32_t *height, 94516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t *sarWidth, int32_t *sarHeight) { 9585f12e9b9062402d6110df3f7099707912040edbAndreas Huber ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); 9685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 9785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned profile_idc = br.getBits(8); 9885f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(16); 9985f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // seq_parameter_set_id 10085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 1012d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned chroma_format_idc = 1; // 4:2:0 chroma format 1022d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 10385f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (profile_idc == 100 || profile_idc == 110 10485f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 122 || profile_idc == 244 10585f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { 1062d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber chroma_format_idc = parseUE(&br); 10785f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (chroma_format_idc == 3) { 10885f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // residual_colour_transform_flag 10985f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 11085f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_luma_minus8 11185f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_chroma_minus8 11285f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // qpprime_y_zero_transform_bypass_flag 1136dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 1146dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (br.getBits(1)) { // seq_scaling_matrix_present_flag 1156dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber for (size_t i = 0; i < 8; ++i) { 1166dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (br.getBits(1)) { // seq_scaling_list_present_flag[i] 1176dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 1186dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // WARNING: the code below has not ever been exercised... 1196dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // need a real-world example. 1206dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber 1216dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber if (i < 6) { 1226dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // ScalingList4x4[i],16,... 1236dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber skipScalingList(&br, 16); 1246dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } else { 1256dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber // ScalingList8x8[i-6],64,... 1266dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber skipScalingList(&br, 64); 1276dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1286dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1296dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 1306dc91c957cfad4393b205a3c2f8421e549fa7e85Andreas Huber } 13185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 13285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 13385f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_frame_num_minus4 13485f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_order_cnt_type = parseUE(&br); 13585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 13685f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (pic_order_cnt_type == 0) { 13785f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 13885f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (pic_order_cnt_type == 1) { 13985f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_non_ref_pic, offset_for_top_to_bottom_field and 14085f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_ref_frame are technically se(v), but since we are 14185f12e9b9062402d6110df3f7099707912040edbAndreas Huber // just skipping over them the midpoint does not matter. 14285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 14385f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // delta_pic_order_always_zero_flag 14485f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_non_ref_pic 14585f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_top_to_bottom_field 14685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 14785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); 14885f12e9b9062402d6110df3f7099707912040edbAndreas Huber for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { 14985f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_ref_frame 15085f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 15185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 15285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 15385f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // num_ref_frames 15485f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // gaps_in_frame_num_value_allowed_flag 15585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 15685f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_width_in_mbs_minus1 = parseUE(&br); 15785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_height_in_map_units_minus1 = parseUE(&br); 15885f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned frame_mbs_only_flag = br.getBits(1); 15985f12e9b9062402d6110df3f7099707912040edbAndreas Huber 16085f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = pic_width_in_mbs_minus1 * 16 + 16; 16185f12e9b9062402d6110df3f7099707912040edbAndreas Huber 16285f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = (2 - frame_mbs_only_flag) 16385f12e9b9062402d6110df3f7099707912040edbAndreas Huber * (pic_height_in_map_units_minus1 * 16 + 16); 1642d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1652d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (!frame_mbs_only_flag) { 1662d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // mb_adaptive_frame_field_flag 1672d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1682d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1692d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // direct_8x8_inference_flag 1702d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1712d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (br.getBits(1)) { // frame_cropping_flag 1722d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_left_offset = parseUE(&br); 1732d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_right_offset = parseUE(&br); 1742d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_top_offset = parseUE(&br); 1752d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_bottom_offset = parseUE(&br); 1762d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1772d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned cropUnitX, cropUnitY; 1782d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (chroma_format_idc == 0 /* monochrome */) { 1792d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = 1; 1802d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = 2 - frame_mbs_only_flag; 1812d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } else { 1822d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2; 1832d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1; 1842d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1852d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = subWidthC; 1862d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = subHeightC * (2 - frame_mbs_only_flag); 1872d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1882d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u", 1902d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_left_offset, frame_crop_right_offset, 1912d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_top_offset, frame_crop_bottom_offset, 1922d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX, cropUnitY); 1932d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1942d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *width -= 1952d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX; 1962d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *height -= 1972d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; 1982d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 199516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 200516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarWidth != NULL) { 201516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarWidth = 0; 202516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 203516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 204516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarHeight != NULL) { 205516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarHeight = 0; 206516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 207516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 208516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (br.getBits(1)) { // vui_parameters_present_flag 209516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber unsigned sar_width = 0, sar_height = 0; 210516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 211516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (br.getBits(1)) { // aspect_ratio_info_present_flag 212516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber unsigned aspect_ratio_idc = br.getBits(8); 213516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 214516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (aspect_ratio_idc == 255 /* extendedSAR */) { 215516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_width = br.getBits(16); 216516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sar_height = br.getBits(16); 217d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang } else { 218d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang static const struct { unsigned width, height; } kFixedSARs[] = { 219d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 0, 0 }, // Invalid 220d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 1, 1 }, 221d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 12, 11 }, 222d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 10, 11 }, 223d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 16, 11 }, 224d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 40, 33 }, 225d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 24, 11 }, 226d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 20, 11 }, 227d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 32, 11 }, 228d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 80, 33 }, 229d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 18, 11 }, 230d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 15, 11 }, 231d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 64, 33 }, 232d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 160, 99 }, 233d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 4, 3 }, 234d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 3, 2 }, 235d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang { 2, 1 }, 236516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber }; 237516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 238d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang if (aspect_ratio_idc > 0 && aspect_ratio_idc < NELEM(kFixedSARs)) { 239d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang sar_width = kFixedSARs[aspect_ratio_idc].width; 240d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang sar_height = kFixedSARs[aspect_ratio_idc].height; 241d2c8413d26c9c24d7c6458dfd1fd273b73d968d9Chong Zhang } 242516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 244516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 245516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGV("sample aspect ratio = %u : %u", sar_width, sar_height); 246516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 247516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarWidth != NULL) { 248516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarWidth = sar_width; 249516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 251516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (sarHeight != NULL) { 252516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber *sarHeight = sar_height; 253516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 25585f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 25685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 257c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberstatus_t getNextNALUnit( 258c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **_data, size_t *_size, 259c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **nalStart, size_t *nalSize, 260c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool startCodeFollows) { 261c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = *_data; 262c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = *_size; 263c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 264c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = NULL; 265c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = 0; 266c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 26715ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (size < 3) { 268c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 269c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 270c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 271c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t offset = 0; 272c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 273c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // A valid startcode consists of at least two 0x00 bytes followed by 0x01. 27415ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia for (; offset + 2 < size; ++offset) { 27515ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (data[offset + 2] == 0x01 && data[offset] == 0x00 27615ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia && data[offset + 1] == 0x00) { 27715ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia break; 27815ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia } 279c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 28015ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia if (offset + 2 >= size) { 28115ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia *_data = &data[offset]; 28215ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia *_size = 2; 28315ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia return -EAGAIN; 28415ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia } 28515ebd70bdb7aeb3d5ce309710dbd64c0ea038113Wei Jia offset += 3; 286c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 287c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t startOffset = offset; 288c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 289c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber for (;;) { 290c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (offset < size && data[offset] != 0x01) { 291c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 292c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 293c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 294c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset == size) { 295c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (startCodeFollows) { 296c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber offset = size + 2; 297c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 298c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 299c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 300c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 301c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 302c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 303c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) { 304c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 305c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 306c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 307c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 308c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 309c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 310c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t endOffset = offset - 2; 3117f048fdd69753e0ba95d3ef1484b30bcf39164c0Andreas Huber while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) { 312c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber --endOffset; 313c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 314c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 315c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = &data[startOffset]; 316c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = endOffset - startOffset; 317c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 318c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset + 2 < size) { 319c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = &data[offset - 2]; 320c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = size - offset + 2; 321c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } else { 322c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = NULL; 323c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = 0; 324c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 325c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 326c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return OK; 327c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 328c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 32984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatic sp<ABuffer> FindNAL(const uint8_t *data, size_t size, unsigned nalType) { 330c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 331c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 332c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 333c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if ((nalStart[0] & 0x1f) == nalType) { 334c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> buffer = new ABuffer(nalSize); 335c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(buffer->data(), nalStart, nalSize); 336c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return buffer; 337c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 338c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 339c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 340c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 341c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 342c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 343bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huberconst char *AVCProfileToString(uint8_t profile) { 344bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber switch (profile) { 345bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileBaseline: 346bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Baseline"; 347bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileMain: 348bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Main"; 349bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileExtended: 350bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Extended"; 351bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh: 352bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High"; 353bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh10: 354bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 10"; 355bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh422: 356bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 422"; 357bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh444: 358bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 444"; 359bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileCAVLC444Intra: 360bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "CAVLC 444 Intra"; 361bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber default: return "Unknown"; 362bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber } 363bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber} 364bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 365c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Hubersp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) { 366c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = accessUnit->data(); 367c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = accessUnit->size(); 368c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 36984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber sp<ABuffer> seqParamSet = FindNAL(data, size, 7); 370c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (seqParamSet == NULL) { 371c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 372c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 373c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 374c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber int32_t width, height; 375516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 376516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber FindAVCDimensions( 377516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber seqParamSet, &width, &height, &sarWidth, &sarHeight); 378c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 37984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber sp<ABuffer> picParamSet = FindNAL(data, size, 8); 380c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber CHECK(picParamSet != NULL); 381c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 382c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t csdSize = 383c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 1 + 3 + 1 + 1 384c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 2 * 1 + seqParamSet->size() 385c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 1 + 2 * 1 + picParamSet->size(); 386c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 387c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 388c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber uint8_t *out = csd->data(); 389c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 390c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0x01; // configurationVersion 391c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data() + 1, 3); // profile/level... 392bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 393bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t profile = out[0]; 394bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t level = out[2]; 395bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 396c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += 3; 397c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 398c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0xe0 | 1; 399c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 400c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() >> 8; 401c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() & 0xff; 402c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data(), seqParamSet->size()); 403c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += seqParamSet->size(); 404c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 405c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 1; 406c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 407c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() >> 8; 408c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() & 0xff; 409c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, picParamSet->data(), picParamSet->size()); 410c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 411c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#if 0 412df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("AVC seq param set"); 413c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber hexdump(seqParamSet->data(), seqParamSet->size()); 414c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#endif 415c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 416c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<MetaData> meta = new MetaData; 417c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 418c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 419c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size()); 420c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyWidth, width); 421c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyHeight, height); 422c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 423095bc25818904fa31ae30c454d011f33cc936530Wei Jia if ((sarWidth > 0 && sarHeight > 0) && (sarWidth != 1 || sarHeight != 1)) { 424095bc25818904fa31ae30c454d011f33cc936530Wei Jia // We treat *:0 and 0:* (unspecified) as 1:1. 425516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 426516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARWidth, sarWidth); 427516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARHeight, sarHeight); 428516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 429516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) " 430516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber "SAR %d : %d", 431516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber width, 432516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber height, 433516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber AVCProfileToString(profile), 434516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level / 10, 435516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level % 10, 436516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sarWidth, 437516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber sarHeight); 438516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } else { 439516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)", 440516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber width, 441516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber height, 442516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber AVCProfileToString(profile), 443516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level / 10, 444516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber level % 10); 445516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 446c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 447c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return meta; 448c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 449c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 4507e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimtemplate <typename T> 4517e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimbool IsIDRInternal(const sp<T> &buffer) { 452c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = buffer->data(); 453c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = buffer->size(); 454c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 455c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool foundIDR = false; 456c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 457c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 458c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 459c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 46091fe76a157847825601b8f7a627efd1c9cbadcaeRobert Shih if (nalSize == 0u) { 46191fe76a157847825601b8f7a627efd1c9cbadcaeRobert Shih ALOGW("skipping empty nal unit from potentially malformed bitstream"); 46291fe76a157847825601b8f7a627efd1c9cbadcaeRobert Shih continue; 46391fe76a157847825601b8f7a627efd1c9cbadcaeRobert Shih } 464c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 465c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber unsigned nalType = nalStart[0] & 0x1f; 466c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 467c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (nalType == 5) { 468c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber foundIDR = true; 469c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 470c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 471c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 472c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 473c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return foundIDR; 474c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 475c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 4767e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimbool IsIDR(const sp<ABuffer> &buffer) { 4777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim return IsIDRInternal(buffer); 4787e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim} 4797e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 4807e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimbool IsIDR(const sp<MediaCodecBuffer> &buffer) { 4817e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim return IsIDRInternal(buffer); 4827e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim} 4837e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim 4843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huberbool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) { 4853fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *data = accessUnit->data(); 4863fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t size = accessUnit->size(); 48762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania if (data == NULL) { 48862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania ALOGE("IsAVCReferenceFrame: called on NULL data (%p, %zu)", accessUnit.get(), size); 48962dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania return false; 49062dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania } 4913fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 4923fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *nalStart; 4933fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t nalSize; 4943fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 49562dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania if (nalSize == 0) { 49662dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania ALOGE("IsAVCReferenceFrame: invalid nalSize: 0 (%p, %zu)", accessUnit.get(), size); 49762dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania return false; 49862dec9555ec832b1a8c63c70e4df745aa8635488Hassan Shojania } 4993fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 5003fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nalType = nalStart[0] & 0x1f; 5013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 5023fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (nalType == 5) { 5033fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 5043fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else if (nalType == 1) { 5053fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nal_ref_idc = (nalStart[0] >> 5) & 3; 5063fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return nal_ref_idc != 0; 5073fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 5083fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 5093fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 5103fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 5113fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber} 5123fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 5134dbff11975e737482537e1636051690188f3fbc4Praveen Chavanuint32_t FindAVCLayerId(const uint8_t *data, size_t size) { 5144dbff11975e737482537e1636051690188f3fbc4Praveen Chavan CHECK(data != NULL); 5154dbff11975e737482537e1636051690188f3fbc4Praveen Chavan 5164dbff11975e737482537e1636051690188f3fbc4Praveen Chavan const unsigned kSvcNalType = 0xE; 5174dbff11975e737482537e1636051690188f3fbc4Praveen Chavan const unsigned kSvcNalSearchRange = 32; 5184dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // SVC NAL 5194dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // |---0 1110|1--- ----|---- ----|iii- ---| 5204dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // ^ ^ 5214dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // NAL-type = 0xE layer-Id 5224dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // 5234dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // layer_id 0 is for base layer, while 1, 2, ... are enhancement layers. 5244dbff11975e737482537e1636051690188f3fbc4Praveen Chavan // Layer n uses reference frames from layer 0, 1, ..., n-1. 5254dbff11975e737482537e1636051690188f3fbc4Praveen Chavan 5264dbff11975e737482537e1636051690188f3fbc4Praveen Chavan uint32_t layerId = 0; 5274dbff11975e737482537e1636051690188f3fbc4Praveen Chavan sp<ABuffer> svcNAL = FindNAL( 5284dbff11975e737482537e1636051690188f3fbc4Praveen Chavan data, size > kSvcNalSearchRange ? kSvcNalSearchRange : size, kSvcNalType); 5294dbff11975e737482537e1636051690188f3fbc4Praveen Chavan if (svcNAL != NULL && svcNAL->size() >= 4) { 5304dbff11975e737482537e1636051690188f3fbc4Praveen Chavan layerId = (*(svcNAL->data() + 3) >> 5) & 0x7; 5314dbff11975e737482537e1636051690188f3fbc4Praveen Chavan } 5324dbff11975e737482537e1636051690188f3fbc4Praveen Chavan return layerId; 5334dbff11975e737482537e1636051690188f3fbc4Praveen Chavan} 5344dbff11975e737482537e1636051690188f3fbc4Praveen Chavan 53550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> MakeAACCodecSpecificData( 53650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned profile, unsigned sampling_freq_index, 53750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned channel_configuration) { 53850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<MetaData> meta = new MetaData; 53950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 54050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 54150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang CHECK_LE(sampling_freq_index, 11u); 54250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const int32_t kSamplingFreq[] = { 54350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 54450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 16000, 12000, 11025, 8000 54550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 54650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]); 54750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeyChannelCount, channel_configuration); 54850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 54950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const uint8_t kStaticESDS[] = { 55050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x03, 22, 55150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, // ES_ID 55250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 55350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 55450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x04, 17, 55550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x40, // Audio ISO/IEC 14496-3 55650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 55750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 55850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 55950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 56050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x05, 2, 56150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // AudioSpecificInfo follows 56250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 56350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // oooo offf fccc c000 56450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // o - audioObjectType 56550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // f - samplingFreqIndex 56650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // c - channelConfig 56750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 56850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 56950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 57050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 57150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS)] = 57250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((profile + 1) << 3) | (sampling_freq_index >> 1); 57350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 57450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS) + 1] = 57550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3); 57650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 57750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setData(kKeyESDS, 0, csd->data(), csd->size()); 57850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 57950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return meta; 58050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 58150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 582386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool ExtractDimensionsFromVOLHeader( 583386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber const uint8_t *data, size_t size, int32_t *width, int32_t *height) { 584386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ABitReader br(&data[4], size - 4); 585386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // random_accessible_vol 586386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_type_indication = br.getBits(8); 587386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 588386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_NE(video_object_type_indication, 589386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 0x21u /* Fine Granularity Scalable */); 590386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 591b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe unsigned video_object_layer_verid __unused; 592b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe unsigned video_object_layer_priority __unused; 593386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { 594386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_verid = br.getBits(4); 595386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_priority = br.getBits(3); 596386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 597386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned aspect_ratio_info = br.getBits(4); 598386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (aspect_ratio_info == 0x0f /* extended PAR */) { 599386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_width 600386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_height 601386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 602386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vol_control_parameters 603386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(2); // chroma_format 604386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // low_delay 605386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vbv_parameters 606386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_bit_rate 607386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 608386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_bit_rate 609386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_vbv_buffer_size 611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(3); // latter_half_vbv_buffer_size 613386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(11); // first_half_vbv_occupancy 614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_vbv_occupancy 616386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_shape = br.getBits(2); 620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */); 621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned vop_time_increment_resolution = br.getBits(16); 624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // fixed_vop_rate 627386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // range [0..vop_time_increment_resolution) 628386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 629386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // vop_time_increment_resolution 630386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 2 => 0..1, 1 bit 631386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 3 => 0..2, 2 bits 632386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 4 => 0..3, 2 bits 633386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 5 => 0..4, 3 bits 634386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // ... 635386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 636386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_GT(vop_time_increment_resolution, 0u); 637386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber --vop_time_increment_resolution; 638386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 639386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned numBits = 0; 640386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber while (vop_time_increment_resolution > 0) { 641386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ++numBits; 642386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber vop_time_increment_resolution >>= 1; 643386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 644386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 645386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(numBits); // fixed_vop_time_increment 646386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 647386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 648386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 649386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_width = br.getBits(13); 650386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 651386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_height = br.getBits(13); 652386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 653386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 654b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe unsigned interlaced __unused = br.getBits(1); 655386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 656386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *width = video_object_layer_width; 657386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *height = video_object_layer_height; 658386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 659386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 660386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 661386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 662386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool GetMPEGAudioFrameSize( 663386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber uint32_t header, size_t *frame_size, 664386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_sampling_rate, int *out_channels, 665386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_bitrate, int *out_num_samples) { 666386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 0; 667386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 668386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 669386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = 0; 670386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 671386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 672386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 673386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = 0; 674386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 675386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 676386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 677386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = 0; 678386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 679386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 680386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 681386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 682386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 683386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 684386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if ((header & 0xffe00000) != 0xffe00000) { 685386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 686386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 687386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 688386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned version = (header >> 19) & 3; 689386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 690386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 0x01) { 691386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 692386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 693386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 694386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned layer = (header >> 17) & 3; 695386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 696386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 0x00) { 697386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 698386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 699386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 700b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe unsigned protection __unused = (header >> 16) & 1; 701386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 702386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned bitrate_index = (header >> 12) & 0x0f; 703386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 704386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (bitrate_index == 0 || bitrate_index == 0x0f) { 705386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // Disallow "free" bitrate. 706386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 707386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 708386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 709386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned sampling_rate_index = (header >> 10) & 3; 710386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 711386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (sampling_rate_index == 3) { 712386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 713386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 714386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 715386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; 716386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int sampling_rate = kSamplingRateV1[sampling_rate_index]; 717386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 2 /* V2 */) { 718386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 2; 719386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else if (version == 0 /* V2.5 */) { 720386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 4; 721386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 722386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 723386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned padding = (header >> 9) & 1; 724386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 725386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 3) { 726386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer I 727386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 728386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1[] = { 729386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 64, 96, 128, 160, 192, 224, 256, 730386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 288, 320, 352, 384, 416, 448 731386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 732386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 733386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 734386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 735386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 144, 160, 176, 192, 224, 256 736386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 737386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 738386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate = 739386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber (version == 3 /* V1 */) 740386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1[bitrate_index - 1] 741386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV2[bitrate_index - 1]; 742386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 743386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 744386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 745386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 746386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 747386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; 748386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 749386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 750386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 384; 751386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 752386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 753386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer II or III 754386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 755386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L2[] = { 756386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 757386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 160, 192, 224, 256, 320, 384 758386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 759386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 760386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L3[] = { 761386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 40, 48, 56, 64, 80, 96, 112, 762386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 128, 160, 192, 224, 256, 320 763386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 764386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 765386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 766386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 8, 16, 24, 32, 40, 48, 56, 64, 767386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 80, 96, 112, 128, 144, 160 768386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 769386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 770386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate; 771386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 772386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = (layer == 2 /* L2 */) 773386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1L2[bitrate_index - 1] 774386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV1L3[bitrate_index - 1]; 775386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 776386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 777386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 778386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 779386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 780386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 (or 2.5) 781386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 782386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = kBitrateV2[bitrate_index - 1]; 783386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 784a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152; 785386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 786386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 787386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 788386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 789386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 790386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 791386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 792386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 793386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 144000 * bitrate / sampling_rate + padding; 794386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 795386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 or V2.5 796a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000; 797a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *frame_size = tmp * bitrate / sampling_rate + padding; 798386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 799386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 800386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 801386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 802386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = sampling_rate; 803386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 804386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 805386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 806386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int channel_mode = (header >> 6) & 3; 807386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 808386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = (channel_mode == 3) ? 1 : 2; 809386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 810386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 811386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 812386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 813386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 81485f12e9b9062402d6110df3f7099707912040edbAndreas Huber} // namespace android 81585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 816