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