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