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> 25c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MediaDefs.h> 26c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MediaErrors.h> 27c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#include <media/stagefright/MetaData.h> 2885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 2985f12e9b9062402d6110df3f7099707912040edbAndreas Hubernamespace android { 3085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 316a63a939601645404fd98f58c19cc38ca818d99eAndreas Huberunsigned parseUE(ABitReader *br) { 3285f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned numZeroes = 0; 3385f12e9b9062402d6110df3f7099707912040edbAndreas Huber while (br->getBits(1) == 0) { 3485f12e9b9062402d6110df3f7099707912040edbAndreas Huber ++numZeroes; 3585f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 3685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned x = br->getBits(numZeroes); 3885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 3985f12e9b9062402d6110df3f7099707912040edbAndreas Huber return x + (1u << numZeroes) - 1; 4085f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 4185f12e9b9062402d6110df3f7099707912040edbAndreas Huber 4285f12e9b9062402d6110df3f7099707912040edbAndreas Huber// Determine video dimensions from the sequence parameterset. 4385f12e9b9062402d6110df3f7099707912040edbAndreas Hubervoid FindAVCDimensions( 4485f12e9b9062402d6110df3f7099707912040edbAndreas Huber const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height) { 4585f12e9b9062402d6110df3f7099707912040edbAndreas Huber ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); 4685f12e9b9062402d6110df3f7099707912040edbAndreas Huber 4785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned profile_idc = br.getBits(8); 4885f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(16); 4985f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // seq_parameter_set_id 5085f12e9b9062402d6110df3f7099707912040edbAndreas Huber 512d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned chroma_format_idc = 1; // 4:2:0 chroma format 522d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 5385f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (profile_idc == 100 || profile_idc == 110 5485f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 122 || profile_idc == 244 5585f12e9b9062402d6110df3f7099707912040edbAndreas Huber || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) { 562d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber chroma_format_idc = parseUE(&br); 5785f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (chroma_format_idc == 3) { 5885f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // residual_colour_transform_flag 5985f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 6085f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_luma_minus8 6185f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // bit_depth_chroma_minus8 6285f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.skipBits(1); // qpprime_y_zero_transform_bypass_flag 6385f12e9b9062402d6110df3f7099707912040edbAndreas Huber CHECK_EQ(br.getBits(1), 0u); // seq_scaling_matrix_present_flag 6485f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 6585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 6685f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_frame_num_minus4 6785f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_order_cnt_type = parseUE(&br); 6885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 6985f12e9b9062402d6110df3f7099707912040edbAndreas Huber if (pic_order_cnt_type == 0) { 7085f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4 7185f12e9b9062402d6110df3f7099707912040edbAndreas Huber } else if (pic_order_cnt_type == 1) { 7285f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_non_ref_pic, offset_for_top_to_bottom_field and 7385f12e9b9062402d6110df3f7099707912040edbAndreas Huber // offset_for_ref_frame are technically se(v), but since we are 7485f12e9b9062402d6110df3f7099707912040edbAndreas Huber // just skipping over them the midpoint does not matter. 7585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 7685f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // delta_pic_order_always_zero_flag 7785f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_non_ref_pic 7885f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_top_to_bottom_field 7985f12e9b9062402d6110df3f7099707912040edbAndreas Huber 8085f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br); 8185f12e9b9062402d6110df3f7099707912040edbAndreas Huber for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { 8285f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // offset_for_ref_frame 8385f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 8485f12e9b9062402d6110df3f7099707912040edbAndreas Huber } 8585f12e9b9062402d6110df3f7099707912040edbAndreas Huber 8685f12e9b9062402d6110df3f7099707912040edbAndreas Huber parseUE(&br); // num_ref_frames 8785f12e9b9062402d6110df3f7099707912040edbAndreas Huber br.getBits(1); // gaps_in_frame_num_value_allowed_flag 8885f12e9b9062402d6110df3f7099707912040edbAndreas Huber 8985f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_width_in_mbs_minus1 = parseUE(&br); 9085f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned pic_height_in_map_units_minus1 = parseUE(&br); 9185f12e9b9062402d6110df3f7099707912040edbAndreas Huber unsigned frame_mbs_only_flag = br.getBits(1); 9285f12e9b9062402d6110df3f7099707912040edbAndreas Huber 9385f12e9b9062402d6110df3f7099707912040edbAndreas Huber *width = pic_width_in_mbs_minus1 * 16 + 16; 9485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 9585f12e9b9062402d6110df3f7099707912040edbAndreas Huber *height = (2 - frame_mbs_only_flag) 9685f12e9b9062402d6110df3f7099707912040edbAndreas Huber * (pic_height_in_map_units_minus1 * 16 + 16); 972d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 982d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (!frame_mbs_only_flag) { 992d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // mb_adaptive_frame_field_flag 1002d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1012d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1022d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber br.getBits(1); // direct_8x8_inference_flag 1032d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1042d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (br.getBits(1)) { // frame_cropping_flag 1052d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_left_offset = parseUE(&br); 1062d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_right_offset = parseUE(&br); 1072d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_top_offset = parseUE(&br); 1082d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned frame_crop_bottom_offset = parseUE(&br); 1092d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1102d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned cropUnitX, cropUnitY; 1112d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber if (chroma_format_idc == 0 /* monochrome */) { 1122d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = 1; 1132d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = 2 - frame_mbs_only_flag; 1142d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } else { 1152d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2; 1162d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1; 1172d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1182d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX = subWidthC; 1192d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitY = subHeightC * (2 - frame_mbs_only_flag); 1202d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 1212d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u", 1232d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_left_offset, frame_crop_right_offset, 1242d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber frame_crop_top_offset, frame_crop_bottom_offset, 1252d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber cropUnitX, cropUnitY); 1262d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber 1272d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *width -= 1282d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX; 1292d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber *height -= 1302d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; 1312d511ff0eb4c6127659795b642825c55879a15bcAndreas Huber } 13285f12e9b9062402d6110df3f7099707912040edbAndreas Huber} 13385f12e9b9062402d6110df3f7099707912040edbAndreas Huber 134c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberstatus_t getNextNALUnit( 135c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **_data, size_t *_size, 136c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t **nalStart, size_t *nalSize, 137c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool startCodeFollows) { 138c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = *_data; 139c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = *_size; 140c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 141c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = NULL; 142c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = 0; 143c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 144c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (size == 0) { 145c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 146c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 147c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 148c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // Skip any number of leading 0x00. 149c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 150c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t offset = 0; 151c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (offset < size && data[offset] == 0x00) { 152c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 153c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 154c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 155c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset == size) { 156c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 157c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 158c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 159c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber // A valid startcode consists of at least two 0x00 bytes followed by 0x01. 160c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 161c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset < 2 || data[offset] != 0x01) { 162c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return ERROR_MALFORMED; 163c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 164c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 165c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 166c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 167c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t startOffset = offset; 168c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 169c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber for (;;) { 170c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (offset < size && data[offset] != 0x01) { 171c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 172c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 173c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 174c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset == size) { 175c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (startCodeFollows) { 176c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber offset = size + 2; 177c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 178c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 179c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 180c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return -EAGAIN; 181c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 182c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 183c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) { 184c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 185c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 186c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 187c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber ++offset; 188c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 189c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 190c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t endOffset = offset - 2; 1917f048fdd69753e0ba95d3ef1484b30bcf39164c0Andreas Huber while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) { 192c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber --endOffset; 193c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 194c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 195c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalStart = &data[startOffset]; 196c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *nalSize = endOffset - startOffset; 197c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 198c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (offset + 2 < size) { 199c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = &data[offset - 2]; 200c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = size - offset + 2; 201c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } else { 202c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_data = NULL; 203c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *_size = 0; 204c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 205c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 206c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return OK; 207c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 208c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 209c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberstatic sp<ABuffer> FindNAL( 210c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data, size_t size, unsigned nalType, 211c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t *stopOffset) { 212c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 213c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 214c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 215c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if ((nalStart[0] & 0x1f) == nalType) { 216c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> buffer = new ABuffer(nalSize); 217c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(buffer->data(), nalStart, nalSize); 218c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return buffer; 219c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 220c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 221c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 222c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 223c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 224c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 225bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huberconst char *AVCProfileToString(uint8_t profile) { 226bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber switch (profile) { 227bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileBaseline: 228bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Baseline"; 229bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileMain: 230bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Main"; 231bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileExtended: 232bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "Extended"; 233bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh: 234bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High"; 235bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh10: 236bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 10"; 237bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh422: 238bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 422"; 239bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileHigh444: 240bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "High 444"; 241bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber case kAVCProfileCAVLC444Intra: 242bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber return "CAVLC 444 Intra"; 243bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber default: return "Unknown"; 244bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber } 245bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber} 246bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 247c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Hubersp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) { 248c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = accessUnit->data(); 249c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = accessUnit->size(); 250c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 251c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL); 252c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (seqParamSet == NULL) { 253c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return NULL; 254c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 255c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 256c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber int32_t width, height; 257c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber FindAVCDimensions(seqParamSet, &width, &height); 258c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 259c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t stopOffset; 260c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset); 261c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber CHECK(picParamSet != NULL); 262c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 263c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t csdSize = 264c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 1 + 3 + 1 + 1 265c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 2 * 1 + seqParamSet->size() 266c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber + 1 + 2 * 1 + picParamSet->size(); 267c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 268c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<ABuffer> csd = new ABuffer(csdSize); 269c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber uint8_t *out = csd->data(); 270c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 271c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0x01; // configurationVersion 272c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data() + 1, 3); // profile/level... 273bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 274bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t profile = out[0]; 275bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber uint8_t level = out[2]; 276bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber 277c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += 3; 278c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes 279c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 0xe0 | 1; 280c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 281c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() >> 8; 282c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = seqParamSet->size() & 0xff; 283c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, seqParamSet->data(), seqParamSet->size()); 284c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber out += seqParamSet->size(); 285c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 286c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = 1; 287c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 288c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() >> 8; 289c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber *out++ = picParamSet->size() & 0xff; 290c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber memcpy(out, picParamSet->data(), picParamSet->size()); 291c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 292c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#if 0 293df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("AVC seq param set"); 294c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber hexdump(seqParamSet->data(), seqParamSet->size()); 295c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber#endif 296c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 297c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber sp<MetaData> meta = new MetaData; 298c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 299c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 300c639aad6d8894f57c02e620f52ccf49e51b64866Andreas Huber meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size()); 301c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyWidth, width); 302c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber meta->setInt32(kKeyHeight, height); 303c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 304df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)", 305bfd41f33c77c66ead48ee378e4ea4b7bfa5fca1fAndreas Huber width, height, AVCProfileToString(profile), level / 10, level % 10); 306c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 307c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return meta; 308c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 309c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 310c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huberbool IsIDR(const sp<ABuffer> &buffer) { 311c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *data = buffer->data(); 312c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t size = buffer->size(); 313c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 314c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber bool foundIDR = false; 315c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 316c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber const uint8_t *nalStart; 317c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber size_t nalSize; 318c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 319c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber CHECK_GT(nalSize, 0u); 320c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 321c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber unsigned nalType = nalStart[0] & 0x1f; 322c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 323c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber if (nalType == 5) { 324c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber foundIDR = true; 325c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber break; 326c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 327c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber } 328c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 329c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber return foundIDR; 330c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber} 331c68a48c474f609df3eeb7d9738675d6ac8835e0aAndreas Huber 3323fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huberbool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) { 3333fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *data = accessUnit->data(); 3343fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t size = accessUnit->size(); 3353fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3363fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber const uint8_t *nalStart; 3373fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber size_t nalSize; 3383fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 3393fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber CHECK_GT(nalSize, 0u); 3403fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3413fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nalType = nalStart[0] & 0x1f; 3423fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3433fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber if (nalType == 5) { 3443fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 3453fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } else if (nalType == 1) { 3463fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber unsigned nal_ref_idc = (nalStart[0] >> 5) & 3; 3473fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return nal_ref_idc != 0; 3483fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 3493fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber } 3503fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 3513fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber return true; 3523fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber} 3533fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber 35450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wangsp<MetaData> MakeAACCodecSpecificData( 35550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned profile, unsigned sampling_freq_index, 35650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang unsigned channel_configuration) { 35750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<MetaData> meta = new MetaData; 35850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 35950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 36050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang CHECK_LE(sampling_freq_index, 11u); 36150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const int32_t kSamplingFreq[] = { 36250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 36350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 16000, 12000, 11025, 8000 36450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 36550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]); 36650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setInt32(kKeyChannelCount, channel_configuration); 36750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 36850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang static const uint8_t kStaticESDS[] = { 36950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x03, 22, 37050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, // ES_ID 37150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag 37250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 37350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x04, 17, 37450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x40, // Audio ISO/IEC 14496-3 37550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 37650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 37750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x00, 0x00, 0x00, 0x00, 37850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 37950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 0x05, 2, 38050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // AudioSpecificInfo follows 38150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 38250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // oooo offf fccc c000 38350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // o - audioObjectType 38450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // f - samplingFreqIndex 38550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang // c - channelConfig 38650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang }; 38750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2); 38850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS)); 38950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 39050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS)] = 39150c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((profile + 1) << 3) | (sampling_freq_index >> 1); 39250c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 39350c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang csd->data()[sizeof(kStaticESDS) + 1] = 39450c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3); 39550c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 39650c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang meta->setData(kKeyESDS, 0, csd->data(), csd->size()); 39750c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 39850c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang return meta; 39950c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang} 40050c44c79d2d7dd6cd1485d9d939f67f80b8da1caGloria Wang 401386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool ExtractDimensionsFromVOLHeader( 402386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber const uint8_t *data, size_t size, int32_t *width, int32_t *height) { 403386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ABitReader br(&data[4], size - 4); 404386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // random_accessible_vol 405386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_type_indication = br.getBits(8); 406386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 407386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_NE(video_object_type_indication, 408386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 0x21u /* Fine Granularity Scalable */); 409386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 410386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_verid; 411386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_priority; 412386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { 413386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_verid = br.getBits(4); 414386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber video_object_layer_priority = br.getBits(3); 415386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 416386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned aspect_ratio_info = br.getBits(4); 417386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (aspect_ratio_info == 0x0f /* extended PAR */) { 418386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_width 419386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(8); // par_height 420386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 421386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vol_control_parameters 422386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(2); // chroma_format 423386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(1); // low_delay 424386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // vbv_parameters 425386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_bit_rate 426386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 427386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_bit_rate 428386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 429386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // first_half_vbv_buffer_size 430386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 431386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(3); // latter_half_vbv_buffer_size 432386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(11); // first_half_vbv_occupancy 433386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 434386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(15); // latter_half_vbv_occupancy 435386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 436386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 437386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 438386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_shape = br.getBits(2); 439386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */); 440386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 441386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 442386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned vop_time_increment_resolution = br.getBits(16); 443386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 444386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 445386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (br.getBits(1)) { // fixed_vop_rate 446386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // range [0..vop_time_increment_resolution) 447386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 448386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // vop_time_increment_resolution 449386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 2 => 0..1, 1 bit 450386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 3 => 0..2, 2 bits 451386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 4 => 0..3, 2 bits 452386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // 5 => 0..4, 3 bits 453386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // ... 454386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 455386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK_GT(vop_time_increment_resolution, 0u); 456386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber --vop_time_increment_resolution; 457386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 458386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned numBits = 0; 459386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber while (vop_time_increment_resolution > 0) { 460386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ++numBits; 461386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber vop_time_increment_resolution >>= 1; 462386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 463386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 464386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber br.skipBits(numBits); // fixed_vop_time_increment 465386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 466386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 467386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 468386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_width = br.getBits(13); 469386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 470386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned video_object_layer_height = br.getBits(13); 471386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber CHECK(br.getBits(1)); // marker_bit 472386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 473386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned interlaced = br.getBits(1); 474386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 475386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *width = video_object_layer_width; 476386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *height = video_object_layer_height; 477386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 478386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 479386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 480386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 481386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huberbool GetMPEGAudioFrameSize( 482386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber uint32_t header, size_t *frame_size, 483386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_sampling_rate, int *out_channels, 484386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int *out_bitrate, int *out_num_samples) { 485386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 0; 486386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 487386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 488386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = 0; 489386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 490386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 491386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 492386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = 0; 493386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 494386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 495386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 496386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = 0; 497386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 498386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 499386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 500386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 501386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 502386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 503386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if ((header & 0xffe00000) != 0xffe00000) { 504386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 505386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 506386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 507386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned version = (header >> 19) & 3; 508386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 509386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 0x01) { 510386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 511386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 512386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 513386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned layer = (header >> 17) & 3; 514386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 515386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 0x00) { 516386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 517386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 518386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 519386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned protection = (header >> 16) & 1; 520386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 521386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned bitrate_index = (header >> 12) & 0x0f; 522386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 523386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (bitrate_index == 0 || bitrate_index == 0x0f) { 524386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // Disallow "free" bitrate. 525386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 526386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 527386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 528386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned sampling_rate_index = (header >> 10) & 3; 529386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 530386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (sampling_rate_index == 3) { 531386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return false; 532386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 533386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 534386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kSamplingRateV1[] = { 44100, 48000, 32000 }; 535386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int sampling_rate = kSamplingRateV1[sampling_rate_index]; 536386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 2 /* V2 */) { 537386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 2; 538386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else if (version == 0 /* V2.5 */) { 539386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sampling_rate /= 4; 540386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 541386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 542386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned padding = (header >> 9) & 1; 543386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 544386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (layer == 3) { 545386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer I 546386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 547386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1[] = { 548386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 64, 96, 128, 160, 192, 224, 256, 549386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 288, 320, 352, 384, 416, 448 550386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 551386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 552386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 553386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 554386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 144, 160, 176, 192, 224, 256 555386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 556386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 557386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate = 558386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber (version == 3 /* V1 */) 559386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1[bitrate_index - 1] 560386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV2[bitrate_index - 1]; 561386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 562386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 563386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 564386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 565386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 566386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = (12000 * bitrate / sampling_rate + padding) * 4; 567386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 568386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 569386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 384; 570386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 571386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 572386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // layer II or III 573386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 574386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L2[] = { 575386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 48, 56, 64, 80, 96, 112, 128, 576386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 160, 192, 224, 256, 320, 384 577386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 578386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 579386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV1L3[] = { 580386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 32, 40, 48, 56, 64, 80, 96, 112, 581386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 128, 160, 192, 224, 256, 320 582386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 583386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 584386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber static const int kBitrateV2[] = { 585386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 8, 16, 24, 32, 40, 48, 56, 64, 586386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 80, 96, 112, 128, 144, 160 587386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber }; 588386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 589386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int bitrate; 590386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 591386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = (layer == 2 /* L2 */) 592386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ? kBitrateV1L2[bitrate_index - 1] 593386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber : kBitrateV1L3[bitrate_index - 1]; 594386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 595386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 596386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_num_samples = 1152; 597386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 598386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 599386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 (or 2.5) 600386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 601386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bitrate = kBitrateV2[bitrate_index - 1]; 602386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_num_samples) { 603a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152; 604386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 605386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 606386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 607386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_bitrate) { 608386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_bitrate = bitrate; 609386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (version == 3 /* V1 */) { 612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *frame_size = 144000 * bitrate / sampling_rate + padding; 613386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else { 614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber // V2 or V2.5 615a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000; 616a39ad61a1c9c69c2cc60f5d14243dd56040f8571John Grossman *frame_size = tmp * bitrate / sampling_rate + padding; 617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_sampling_rate) { 621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_sampling_rate = sampling_rate; 622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (out_channels) { 625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int channel_mode = (header >> 6) & 3; 626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 627386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber *out_channels = (channel_mode == 3) ? 1 : 2; 628386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 629386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 630386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return true; 631386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber} 632386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 63385f12e9b9062402d6110df3f7099707912040edbAndreas Huber} // namespace android 63485f12e9b9062402d6110df3f7099707912040edbAndreas Huber 635