120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
179806555d3930be43e11106281dee354820ac1c88Andreas Huber//#define LOG_NDEBUG 0
189806555d3930be43e11106281dee354820ac1c88Andreas Huber#define LOG_TAG "Utils"
199806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <utils/Log.h>
20a1df816c0677185534babba6ffc29970b048e52eLajos Molnar#include <ctype.h>
2183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen#include <stdio.h>
2283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen#include <sys/stat.h>
239806555d3930be43e11106281dee354820ac1c88Andreas Huber
2407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar#include <utility>
2507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
269806555d3930be43e11106281dee354820ac1c88Andreas Huber#include "include/ESDS.h"
279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include "include/HevcUtils.h"
289806555d3930be43e11106281dee354820ac1c88Andreas Huber
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
30cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#include <cutils/properties.h>
312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad#include <media/openmax/OMX_Audio.h>
3207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar#include <media/openmax/OMX_Video.h>
3307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar#include <media/openmax/OMX_VideoExt.h>
34caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu#include <media/stagefright/CodecBase.h>
359806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
369806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h>
3707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar#include <media/stagefright/foundation/ALookup.h>
389806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h>
399806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h>
4094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/MediaDefs.h>
4194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioSystem.h>
4294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/MediaPlayerInterface.h>
4394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <hardware/audio.h>
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
4594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioParameter.h>
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) {
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ptr[0] << 8 | ptr[1];
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) {
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) {
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
61ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) {
62ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ptr[0] | (ptr[1] << 8);
63ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
64ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
65ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) {
66ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
67ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
68ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
69ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) {
70ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
71ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
72ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host.
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) {
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) {
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
829c170c076382096b9e767da0e3f9f37dafa76546Wei Jiastatic status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
869c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
879c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
889c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
899c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        tmpBuffer->setRange(0, (*buffer)->size());
909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        (*buffer) = tmpBuffer;
919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    }
929c170c076382096b9e767da0e3f9f37dafa76546Wei Jia
939c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
949c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
959c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    return OK;
979c170c076382096b9e767da0e3f9f37dafa76546Wei Jia}
989c170c076382096b9e767da0e3f9f37dafa76546Wei Jia
99d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#if 0
100caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageInt32(
101caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
102caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
103caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (meta->findInt32(key, &value)) {
104caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32(name, value);
105caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
106caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
107d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#endif
108caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
109caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
110caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
111caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0;
112caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t primaries = 0;
113caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t transferFunction = 0;
114caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t colorMatrix = 0;
115caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorRange, &range);
116caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorPrimaries, &primaries);
117caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyTransferFunction, &transferFunction);
118caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorMatrix, &colorMatrix);
119caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
120caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
121caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mRange = (ColorAspects::Range)range;
122caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
123caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
124caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
125caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
126caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t rangeMsg, standardMsg, transferMsg;
127caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertCodecColorAspectsToPlatformAspects(
128caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
129caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
130caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
131caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
132caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to msg
133caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (rangeMsg != 0) {
134caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-range", rangeMsg);
135caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
136caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (standardMsg != 0) {
137caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-standard", standardMsg);
138caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
139caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (transferMsg != 0) {
140caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-transfer", transferMsg);
141caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
142caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
143caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
144127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnarstatic bool isHdr(const sp<AMessage> &format) {
145127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR
146127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key
147127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // in the format.
148127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    int32_t isHdr;
149127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    if (format->findInt32("android._is-hdr", &isHdr)) {
150127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        return isHdr;
151127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    }
152127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
153127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // if user/container supplied HDR static info without transfer set, assume true
154127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
155127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        return true;
156127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    }
157127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // otherwise, verify that an HDR transfer function is set
158127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    int32_t transfer;
159127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    if (format->findInt32("color-transfer", &transfer)) {
160127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        return transfer == ColorUtils::kColorTransferST2084
161127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                || transfer == ColorUtils::kColorTransferHLG;
162127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    }
163127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    return false;
164127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar}
165127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
16607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
16707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (csd->size() < 2) {
16807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
16907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
17007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
17107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
17207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if ((audioObjectType & 0xF800) == 0xF800) {
17307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
17407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    } else {
17507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        audioObjectType >>= 11;
17607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
17707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
17807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
17907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1,  OMX_AUDIO_AACObjectMain     },
18007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2,  OMX_AUDIO_AACObjectLC       },
18107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 3,  OMX_AUDIO_AACObjectSSR      },
18207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 4,  OMX_AUDIO_AACObjectLTP      },
18307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 5,  OMX_AUDIO_AACObjectHE       },
18407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 6,  OMX_AUDIO_AACObjectScalable },
18507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 17, OMX_AUDIO_AACObjectERLC     },
18607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 23, OMX_AUDIO_AACObjectLD       },
18707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 29, OMX_AUDIO_AACObjectHE_PS    },
18807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 39, OMX_AUDIO_AACObjectELD      },
18907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
19007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
19107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_AUDIO_AACPROFILETYPE profile;
19207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(audioObjectType, &profile)) {
19307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", profile);
19407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
19507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
19607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
19707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
19807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 4 || ptr[0] != 1) {  // configurationVersion == 1
19907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
20007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
20107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[1];
20207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t constraints = ptr[2];
20307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[3];
20407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
20507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
20607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        {  9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
20707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 10, OMX_VIDEO_AVCLevel1  },
20807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
20907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 11, OMX_VIDEO_AVCLevel1b },
21007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 12, OMX_VIDEO_AVCLevel12 },
21107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 13, OMX_VIDEO_AVCLevel13 },
21207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 20, OMX_VIDEO_AVCLevel2  },
21307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 21, OMX_VIDEO_AVCLevel21 },
21407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 22, OMX_VIDEO_AVCLevel22 },
21507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 30, OMX_VIDEO_AVCLevel3  },
21607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 31, OMX_VIDEO_AVCLevel31 },
21707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 32, OMX_VIDEO_AVCLevel32 },
21807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 40, OMX_VIDEO_AVCLevel4  },
21907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 41, OMX_VIDEO_AVCLevel41 },
22007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 42, OMX_VIDEO_AVCLevel42 },
22107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 50, OMX_VIDEO_AVCLevel5  },
22207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 51, OMX_VIDEO_AVCLevel51 },
22307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 52, OMX_VIDEO_AVCLevel52 },
22407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
22507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
22607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 66, OMX_VIDEO_AVCProfileBaseline },
22707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 77, OMX_VIDEO_AVCProfileMain     },
22807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 88, OMX_VIDEO_AVCProfileExtended },
22907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 100, OMX_VIDEO_AVCProfileHigh    },
23007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 110, OMX_VIDEO_AVCProfileHigh10  },
23107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 122, OMX_VIDEO_AVCProfileHigh422 },
23207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 244, OMX_VIDEO_AVCProfileHigh444 },
23307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
23407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
23507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
23607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_AVCPROFILETYPE codecProfile;
23707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_AVCLEVELTYPE codecLevel;
23807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(profile, &codecProfile)) {
23907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", codecProfile);
24007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (levels.map(level, &codecLevel)) {
24107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            // for 9 && 11 decide level based on profile and constraint_set3 flag
24207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
24307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
24407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
24507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", codecLevel);
24607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
24707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
24807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
24907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
25007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
25107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 7) {
25207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
25307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
25407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
25507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[6];
25607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[5];
25707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
25807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
25907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 0, OMX_VIDEO_H263ProfileBaseline },
26007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1, OMX_VIDEO_H263ProfileH320Coding },
26107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
26207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 3, OMX_VIDEO_H263ProfileISWV2 },
26307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 4, OMX_VIDEO_H263ProfileISWV3 },
26407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 5, OMX_VIDEO_H263ProfileHighCompression },
26507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 6, OMX_VIDEO_H263ProfileInternet },
26607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 7, OMX_VIDEO_H263ProfileInterlace },
26707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 8, OMX_VIDEO_H263ProfileHighLatency },
26807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
26907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
27007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
27107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 10, OMX_VIDEO_H263Level10 },
27207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 20, OMX_VIDEO_H263Level20 },
27307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 30, OMX_VIDEO_H263Level30 },
27407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 40, OMX_VIDEO_H263Level40 },
27507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 45, OMX_VIDEO_H263Level45 },
27607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 50, OMX_VIDEO_H263Level50 },
27707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 60, OMX_VIDEO_H263Level60 },
27807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 70, OMX_VIDEO_H263Level70 },
27907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
28007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
28107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
28207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_H263PROFILETYPE codecProfile;
28307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_H263LEVELTYPE codecLevel;
28407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(profile, &codecProfile)) {
28507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", codecProfile);
28607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (levels.map(level, &codecLevel)) {
28707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", codecLevel);
28807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
28907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
29007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
29107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
29207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
29307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 13 || ptr[0] != 1) {  // configurationVersion == 1
29407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
29507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
29607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
29707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[1] & 0x1F;
29807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t tier = (ptr[1] & 0x20) >> 5;
29907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[12];
30007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
30107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
30207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 30  }, OMX_VIDEO_HEVCMainTierLevel1  },
30307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 60  }, OMX_VIDEO_HEVCMainTierLevel2  },
30407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 63  }, OMX_VIDEO_HEVCMainTierLevel21 },
30507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 90  }, OMX_VIDEO_HEVCMainTierLevel3  },
30607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 93  }, OMX_VIDEO_HEVCMainTierLevel31 },
30707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4  },
30807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
30907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5  },
31007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
31107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
31207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6  },
31307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
31407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
31507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 30  }, OMX_VIDEO_HEVCHighTierLevel1  },
31607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 60  }, OMX_VIDEO_HEVCHighTierLevel2  },
31707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 63  }, OMX_VIDEO_HEVCHighTierLevel21 },
31807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 90  }, OMX_VIDEO_HEVCHighTierLevel3  },
31907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 93  }, OMX_VIDEO_HEVCHighTierLevel31 },
32007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4  },
32107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
32207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5  },
32307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
32407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
32507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6  },
32607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
32707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
32807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
32907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
33007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
33107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1, OMX_VIDEO_HEVCProfileMain   },
33207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2, OMX_VIDEO_HEVCProfileMain10 },
33307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
33407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
33507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
33607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_HEVCPROFILETYPE codecProfile;
33707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_HEVCLEVELTYPE codecLevel;
33807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (!profiles.map(profile, &codecProfile)) {
33907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
34007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            codecProfile = OMX_VIDEO_HEVCProfileMain;
34107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
34207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            codecProfile = OMX_VIDEO_HEVCProfileMain10;
34307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else {
34407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            return;
34507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
34607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
347127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
348127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    // bump to HDR profile
349127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) {
350127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
351127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar    }
352127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
35307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    format->setInt32("profile", codecProfile);
35407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (levels.map(std::make_pair(tier, level), &codecLevel)) {
35507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("level", codecLevel);
35607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
35707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
35807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
35907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg2ProfileLevelFromHeader(
36007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t *data, size_t size, sp<AMessage> &format) {
36107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // find sequence extension
36207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
36307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (seq != NULL && seq + 5 < data + size) {
36407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t start_code = seq[4] >> 4;
36507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (start_code != 1 /* sequence extension ID */) {
36607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            return;
36707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
36807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);
36907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
37007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
37107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x50, OMX_VIDEO_MPEG2ProfileSimple  },
37207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x40, OMX_VIDEO_MPEG2ProfileMain    },
37307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x30, OMX_VIDEO_MPEG2ProfileSNR     },
37407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
37507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x10, OMX_VIDEO_MPEG2ProfileHigh    },
37607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
37707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
37807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
37907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x0A, OMX_VIDEO_MPEG2LevelLL  },
38007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x08, OMX_VIDEO_MPEG2LevelML  },
38107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x06, OMX_VIDEO_MPEG2LevelH14 },
38207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x04, OMX_VIDEO_MPEG2LevelHL  },
38307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x02, OMX_VIDEO_MPEG2LevelHP  },
38407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
38507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
38607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t,
38707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
38807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
38907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL  } },
39007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML  } },
39107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
39207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL  } }, */
39307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML  } },
39407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL  } },
39507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
39607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
39707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2PROFILETYPE profile;
39807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2LEVELTYPE level;
39907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
40007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (escapes.map(indication, &profileLevel)) {
40107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profileLevel.first);
40207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", profileLevel.second);
40307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (profiles.map(indication & 0x70, &profile)) {
40407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profile);
40507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (levels.map(indication & 0xF, &level)) {
40607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                format->setInt32("level", level);
40707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
40807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
40907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
41007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
41107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
41207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
41307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // esds seems to only contain the profile for MPEG-2
41407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    uint8_t objType;
41507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (esds.getObjectTypeIndication(&objType) == OK) {
41607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
41707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x60, OMX_VIDEO_MPEG2ProfileSimple  },
41807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x61, OMX_VIDEO_MPEG2ProfileMain    },
41907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x62, OMX_VIDEO_MPEG2ProfileSNR     },
42007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
42107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x64, OMX_VIDEO_MPEG2ProfileHigh    },
42207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x65, OMX_VIDEO_MPEG2Profile422     },
42307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
42407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
42507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2PROFILETYPE profile;
42607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (profiles.map(objType, &profile)) {
42707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profile);
42807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
42907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
43007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
43107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
43207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
43307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *data = csd->data();
43407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // find visual object sequence
43507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
43607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (seq != NULL && seq + 4 < data + csd->size()) {
43707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t indication = seq[4];
43807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
43907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t,
44007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
44107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level1  } },
44207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level2  } },
44307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level3  } },
44407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level4a } },
44507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level5  } },
44607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level6  } },
44707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0  } },
44807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0b } },
44907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level0  } },
45007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level1  } },
45107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level2  } },
45207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
45307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level0  } },
45407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level1  } },
45507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level2  } }, */
45607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level1  } },
45707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level2  } },
45807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level2  } },
45907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level3  } },
46007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level4  } },
46107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* deprecated
46207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit,              OMX_VIDEO_MPEG4Level2  } }, */
46307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture,   OMX_VIDEO_MPEG4Level1  } },
46407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level1  } },
46507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level2  } },
46607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level1  } },
46707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level2  } },
46807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level1  } },
46907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level2  } },
47007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level1  } },
47107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level2  } },
47207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level1  } },
47307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level2  } },
47407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level3  } },
47507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level4  } },
47607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level1  } },
47707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level2  } },
47807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level3  } },
47907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level1  } },
48007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level2  } },
48107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level3  } },
48207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level4  } },
48307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level1  } },
48407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level2  } },
48507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level1  } },
48607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level2  } },
48707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level3  } },
48807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
48907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100001, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level1  } },
49007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100010, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level2  } },
49107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level3  } },
49207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level4  } },
49307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100101, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level1  } },
49407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100110, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level2  } },
49507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100111, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level3  } },
49607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101000, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level4  } },
49707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level5  } },
49807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level6  } }, */
49907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level0  } },
50007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level1  } },
50107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level2  } },
50207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3  } },
50307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level4  } },
50407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level5  } },
50507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3b } },
50607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* deprecated
50707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0  } },
50807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1  } },
50907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2  } },
51007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3  } },
51107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4  } },
51207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5  } }, */
51307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
51407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
51507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
51607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (table.map(indication, &profileLevel)) {
51707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profileLevel.first);
51807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", profileLevel.second);
51907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
52007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
52107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
52207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
52307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
52407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *data = csd->data();
52507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    size_t remaining = csd->size();
52607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
52707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    while (remaining >= 2) {
52807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t id = data[0];
52907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t length = data[1];
53007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        remaining -= 2;
53107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        data += 2;
53207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (length > remaining) {
53307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            break;
53407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
53507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        switch (id) {
53607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            case 1 /* profileId */:
53707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (length >= 1) {
53807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
53907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 0, OMX_VIDEO_VP9Profile0 },
54007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 1, OMX_VIDEO_VP9Profile1 },
54107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 2, OMX_VIDEO_VP9Profile2 },
54207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 3, OMX_VIDEO_VP9Profile3 },
54307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    };
54407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
545127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                    const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr {
546127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                        { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR },
547127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                        { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR },
548127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                    };
549127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
55007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    OMX_VIDEO_VP9PROFILETYPE profile;
55107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    if (profiles.map(data[0], &profile)) {
552127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                        // convert to HDR profile
553127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                        if (isHdr(format)) {
554127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                            toHdr.lookup(profile, &profile);
555127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                        }
556127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
55707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        format->setInt32("profile", profile);
55807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    }
55907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                }
56007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
56107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            case 2 /* levelId */:
56207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (length >= 1) {
56307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
56407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 10, OMX_VIDEO_VP9Level1  },
56507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 11, OMX_VIDEO_VP9Level11 },
56607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 20, OMX_VIDEO_VP9Level2  },
56707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 21, OMX_VIDEO_VP9Level21 },
56807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 30, OMX_VIDEO_VP9Level3  },
56907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 31, OMX_VIDEO_VP9Level31 },
57007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 40, OMX_VIDEO_VP9Level4  },
57107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 41, OMX_VIDEO_VP9Level41 },
57207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 50, OMX_VIDEO_VP9Level5  },
57307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 51, OMX_VIDEO_VP9Level51 },
57407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 52, OMX_VIDEO_VP9Level52 },
57507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 60, OMX_VIDEO_VP9Level6  },
57607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 61, OMX_VIDEO_VP9Level61 },
57707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 62, OMX_VIDEO_VP9Level62 },
57807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    };
57907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
58007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    OMX_VIDEO_VP9LEVELTYPE level;
58107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    if (levels.map(data[0], &level)) {
58207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        format->setInt32("level", level);
58307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    }
58407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                }
58507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
58607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            default:
58707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
58807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
58907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        remaining -= length;
59007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        data += length;
59107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
59207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
59307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
5949806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage(
5959806555d3930be43e11106281dee354820ac1c88Andreas Huber        const sp<MetaData> &meta, sp<AMessage> *format) {
59659e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
5979806555d3930be43e11106281dee354820ac1c88Andreas Huber    format->clear();
5989806555d3930be43e11106281dee354820ac1c88Andreas Huber
59959e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    if (meta == NULL) {
60059e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        ALOGE("convertMetaDataToMessage: NULL input");
60159e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        return BAD_VALUE;
60259e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    }
60359e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
6049806555d3930be43e11106281dee354820ac1c88Andreas Huber    const char *mime;
605f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    if (!meta->findCString(kKeyMIMEType, &mime)) {
606f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        return BAD_VALUE;
607f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    }
6089806555d3930be43e11106281dee354820ac1c88Andreas Huber
6099806555d3930be43e11106281dee354820ac1c88Andreas Huber    sp<AMessage> msg = new AMessage;
6109806555d3930be43e11106281dee354820ac1c88Andreas Huber    msg->setString("mime", mime);
6119806555d3930be43e11106281dee354820ac1c88Andreas Huber
6129806555d3930be43e11106281dee354820ac1c88Andreas Huber    int64_t durationUs;
6139806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt64(kKeyDuration, &durationUs)) {
6149806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt64("durationUs", durationUs);
6159806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
6169806555d3930be43e11106281dee354820ac1c88Andreas Huber
617ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t avgBitRate = 0;
618ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
61946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        msg->setInt32("bitrate", avgBitRate);
62046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    }
62146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
62246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    int32_t maxBitRate;
623ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
624ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            && maxBitRate > 0 && maxBitRate >= avgBitRate) {
62546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        msg->setInt32("max-bitrate", maxBitRate);
626bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
627bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
6288c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
6298c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
6308c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        msg->setInt32("is-sync-frame", 1);
6318c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
6328c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
633faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    // this only needs to be translated from meta to message as it is an extractor key
634faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    int32_t trackID;
635faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (meta->findInt32(kKeyTrackID, &trackID)) {
636faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        msg->setInt32("track-id", trackID);
637faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
638faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar
6399806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (!strncasecmp("video/", mime, 6)) {
6409806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t width, height;
641f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyWidth, &width)
642f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeyHeight, &height)) {
643f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
644f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
6459806555d3930be43e11106281dee354820ac1c88Andreas Huber
6469806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("width", width);
6479806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("height", height);
648516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
649516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
650516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (meta->findInt32(kKeySARWidth, &sarWidth)
651516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && meta->findInt32(kKeySARHeight, &sarHeight)) {
652516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-width", sarWidth);
653516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-height", sarHeight);
654516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
655475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
656475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
657475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
658475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("color-format", colorFormat);
659475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
660475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
661475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
662475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findRect(kKeyCropRect,
663475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropLeft,
664475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropTop,
665475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropRight,
666475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropBottom)) {
667475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
668475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
669475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
670475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
671475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
672475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("rotation-degrees", rotationDegrees);
673475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
674caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
675d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        uint32_t type;
676d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        const void *data;
677d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        size_t size;
678d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
679d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
680d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
681d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
682d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
683caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageColorAspects(meta, msg);
6849806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (!strncasecmp("audio/", mime, 6)) {
6859806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t numChannels, sampleRate;
686f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyChannelCount, &numChannels)
687f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeySampleRate, &sampleRate)) {
688f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
689f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
6909806555d3930be43e11106281dee354820ac1c88Andreas Huber
6919806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("channel-count", numChannels);
6929806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("sample-rate", sampleRate);
6939806555d3930be43e11106281dee354820ac1c88Andreas Huber
6949806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t channelMask;
6959806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
6969806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("channel-mask", channelMask);
6979806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
6989806555d3930be43e11106281dee354820ac1c88Andreas Huber
6999806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t delay = 0;
7009806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
7019806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-delay", delay);
7029806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
7039806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t padding = 0;
7049806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
7059806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-padding", padding);
7069806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
7079806555d3930be43e11106281dee354820ac1c88Andreas Huber
7089806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t isADTS;
7099806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
7102954bca7bdec618da2b94a7e8ac62595b56598a3Pawin Vongmasa            msg->setInt32("is-adts", isADTS);
7119806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
712ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad
713ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        int32_t aacProfile = -1;
714ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
715ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad            msg->setInt32("aac-profile", aacProfile);
716ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        }
71778bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
71878bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
71978bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
72078bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            msg->setInt32("pcm-encoding", pcmEncoding);
72178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
7229806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
7239806555d3930be43e11106281dee354820ac1c88Andreas Huber
7249806555d3930be43e11106281dee354820ac1c88Andreas Huber    int32_t maxInputSize;
7259806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
7269806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("max-input-size", maxInputSize);
7279806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
7289806555d3930be43e11106281dee354820ac1c88Andreas Huber
729a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
730a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
731a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-width", maxWidth);
732a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
733a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
734a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
735a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
736a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-height", maxHeight);
737a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
738a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
739e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    int32_t rotationDegrees;
740e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
741e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        msg->setInt32("rotation-degrees", rotationDegrees);
742e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
743e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
7448f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
7452a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
7468f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        msg->setInt32("frame-rate", fps);
7478f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
7488f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
7499806555d3930be43e11106281dee354820ac1c88Andreas Huber    uint32_t type;
7509806555d3930be43e11106281dee354820ac1c88Andreas Huber    const void *data;
7519806555d3930be43e11106281dee354820ac1c88Andreas Huber    size_t size;
7529806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
7539806555d3930be43e11106281dee354820ac1c88Andreas Huber        // Parse the AVCDecoderConfigurationRecord
7549806555d3930be43e11106281dee354820ac1c88Andreas Huber
7559806555d3930be43e11106281dee354820ac1c88Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
7569806555d3930be43e11106281dee354820ac1c88Andreas Huber
7577bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
7587bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
7597bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
7607bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
76107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
76207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseAvcProfileLevelFromAvcc(ptr, size, msg);
7639806555d3930be43e11106281dee354820ac1c88Andreas Huber
7649806555d3930be43e11106281dee354820ac1c88Andreas Huber        // There is decodable content out there that fails the following
7659806555d3930be43e11106281dee354820ac1c88Andreas Huber        // assertion, let's be lenient for now...
7669806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
7679806555d3930be43e11106281dee354820ac1c88Andreas Huber
768b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t lengthSize __unused = 1 + (ptr[4] & 3);
7699806555d3930be43e11106281dee354820ac1c88Andreas Huber
7709806555d3930be43e11106281dee354820ac1c88Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
7719806555d3930be43e11106281dee354820ac1c88Andreas Huber        // violates it...
7729806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
7739806555d3930be43e11106281dee354820ac1c88Andreas Huber
7749806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
7759806555d3930be43e11106281dee354820ac1c88Andreas Huber
7769806555d3930be43e11106281dee354820ac1c88Andreas Huber        ptr += 6;
7779806555d3930be43e11106281dee354820ac1c88Andreas Huber        size -= 6;
7789806555d3930be43e11106281dee354820ac1c88Andreas Huber
7799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
7809c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
7819c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
7829c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
7839806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
7849806555d3930be43e11106281dee354820ac1c88Andreas Huber
7859806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
7867bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
7877bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
7887bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
7897bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
7909806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
7919806555d3930be43e11106281dee354820ac1c88Andreas Huber
7929806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
7939806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
7949806555d3930be43e11106281dee354820ac1c88Andreas Huber
7959c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
7969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
7979c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
7989c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
7999c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
8009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
8019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
8029806555d3930be43e11106281dee354820ac1c88Andreas Huber
8039806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
8049806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
8059806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
8069806555d3930be43e11106281dee354820ac1c88Andreas Huber
8079806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
8089806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
8099806555d3930be43e11106281dee354820ac1c88Andreas Huber
8109806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
8119806555d3930be43e11106281dee354820ac1c88Andreas Huber
8129c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(1024);
8139c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
8149c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
8159c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
8169806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
8179806555d3930be43e11106281dee354820ac1c88Andreas Huber
8187bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 1) {
8197bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
8207bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
8217bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
8229806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numPictureParameterSets = *ptr;
8239806555d3930be43e11106281dee354820ac1c88Andreas Huber        ++ptr;
8249806555d3930be43e11106281dee354820ac1c88Andreas Huber        --size;
8259806555d3930be43e11106281dee354820ac1c88Andreas Huber
8269806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
8277bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
8287bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
8297bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
8307bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
8319806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
8329806555d3930be43e11106281dee354820ac1c88Andreas Huber
8339806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
8349806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
8359806555d3930be43e11106281dee354820ac1c88Andreas Huber
8369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
8379c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
8389c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
8399c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
8409c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
8419c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
8429c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
8439806555d3930be43e11106281dee354820ac1c88Andreas Huber
8449806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
8459806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
8469806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
8479806555d3930be43e11106281dee354820ac1c88Andreas Huber
8489806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
8499806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
8509806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
8513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
8523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
8533b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8547bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
8557bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
8567bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
8577bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
85807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
859127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        const size_t dataSize = size; // save for later
8603b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 22;
8613b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 22;
8623b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t numofArrays = (char)ptr[0];
8643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 1;
8653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 1;
8663b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t j = 0, i = 0;
8673b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8689c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
8699c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
8709c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
8719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
8723b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->setRange(0, 0);
8733b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
874127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        HevcParameterSets hvcc;
875127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
8763b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        for (i = 0; i < numofArrays; i++) {
8777bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 3) {
8787bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
8797bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
8807bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
8813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 1;
8823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 1;
8833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            //Num of nals
8853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size_t numofNals = U16_AT(ptr);
8863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 2;
8883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 2;
8893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            for (j = 0; j < numofNals; j++) {
8917bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                if (size < 2) {
8927bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    ALOGE("b/23680780");
8937bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    return BAD_VALUE;
8947bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                }
8953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size_t length = U16_AT(ptr);
8963b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += 2;
8983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= 2;
8993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
9009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (size < length) {
9019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return BAD_VALUE;
9029c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
9039c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                status_t err = copyNALUToABuffer(&buffer, ptr, length);
9049c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (err != OK) {
9059c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return err;
9069c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
907127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar                (void)hvcc.addNalUnit(ptr, length);
9083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
9093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += length;
9103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= length;
9113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
9123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
9133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt32("csd", true);
9143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt64("timeUs", 0);
9153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        msg->setBuffer("csd-0", buffer);
9163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
917127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        // if we saw VUI color information we know whether this is HDR because VUI trumps other
918127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        // format parameters for HEVC.
919127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        HevcParameterSets::Info info = hvcc.getInfo();
920127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        if (info & hvcc.kInfoHasColorDescription) {
921127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar            msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
922127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        }
923127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar
924127a749a59b1953cb0601f1806c0a0eee92baea9Lajos Molnar        parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
9259806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
9269806555d3930be43e11106281dee354820ac1c88Andreas Huber        ESDS esds((const char *)data, size);
927f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (esds.InitCheck() != (status_t)OK) {
928f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
929f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
9309806555d3930be43e11106281dee354820ac1c88Andreas Huber
9319806555d3930be43e11106281dee354820ac1c88Andreas Huber        const void *codec_specific_data;
9329806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t codec_specific_data_size;
9339806555d3930be43e11106281dee354820ac1c88Andreas Huber        esds.getCodecSpecificInfo(
9349806555d3930be43e11106281dee354820ac1c88Andreas Huber                &codec_specific_data, &codec_specific_data_size);
9359806555d3930be43e11106281dee354820ac1c88Andreas Huber
9369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
9379c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9389c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9399c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9409806555d3930be43e11106281dee354820ac1c88Andreas Huber
9419806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), codec_specific_data,
9429806555d3930be43e11106281dee354820ac1c88Andreas Huber               codec_specific_data_size);
9439806555d3930be43e11106281dee354820ac1c88Andreas Huber
9449806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
9459806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
9469806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
94746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
94807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
94907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseMpeg4ProfileLevelFromCsd(buffer, msg);
95007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
95107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseMpeg2ProfileLevelFromEsds(esds, msg);
95207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
95307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
95407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
95507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
95607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseAacProfileFromCsd(buffer, msg);
95707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
95807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
95946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        uint32_t maxBitrate, avgBitrate;
96046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
96146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (!meta->hasData(kKeyBitRate)
96246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                    && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
96346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                msg->setInt32("bitrate", (int32_t)avgBitrate);
964ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            } else {
965ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
966ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            }
967ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            if (!meta->hasData(kKeyMaxBitRate)
968ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                    && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
969ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
97046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
97146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        }
97207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    } else if (meta->findData(kTypeD263, &type, &data, &size)) {
97307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t *ptr = (const uint8_t *)data;
97407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseH263ProfileLevelFromD263(ptr, size, msg);
9759806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
9769c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
9779c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9789c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9809806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
9819806555d3930be43e11106281dee354820ac1c88Andreas Huber
9829806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
9839806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
9849806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
9859806555d3930be43e11106281dee354820ac1c88Andreas Huber
9869806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
9879806555d3930be43e11106281dee354820ac1c88Andreas Huber            return -EINVAL;
9889806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
9899806555d3930be43e11106281dee354820ac1c88Andreas Huber
9909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
9919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9929c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9939c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9949806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
9959806555d3930be43e11106281dee354820ac1c88Andreas Huber
9969806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
9979806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
9989806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
999bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
10009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
10019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
10029c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
10039c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
1004bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
1005bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian
1006bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
1007bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
1008bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
10099b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10109b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
10119b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
10129b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
10139b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10149c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
10159c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
10169c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
10179c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
10189b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
10199b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10209b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
10219b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
10229b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-1", buffer);
10239b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10249b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
10259b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
10269b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
10279b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10289c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
10299c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
10309c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
10319c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
10329b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
10339b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
10349b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
10359b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
10369b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-2", buffer);
1037d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian    } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
1038d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1039d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        if (buffer.get() == NULL || buffer->base() == NULL) {
1040d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian            return NO_MEMORY;
1041d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        }
1042d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
1043d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian
1044d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
1045d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
1046d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
104707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
104807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseVp9ProfileLevelFromCsd(buffer, msg);
10499806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10509806555d3930be43e11106281dee354820ac1c88Andreas Huber
1051793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // TODO expose "crypto-key"/kKeyCryptoKey through public api
1052793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
1053793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
1054793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        msg->setBuffer("crypto-key", buffer);
1055793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(buffer->data(), data, size);
1056793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
1057793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
10589806555d3930be43e11106281dee354820ac1c88Andreas Huber    *format = msg;
10599806555d3930be43e11106281dee354820ac1c88Andreas Huber
10609806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
10619806555d3930be43e11106281dee354820ac1c88Andreas Huber}
10629806555d3930be43e11106281dee354820ac1c88Andreas Huber
106347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnarconst uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
106447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    uint8_t *res = NULL;
106547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    if (length > 4) {
106647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        // minus 1 as to not match NAL start code at end
106747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
106847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    }
106947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    return res != NULL && res < data + length - 4 ? res : &data[length];
107047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar}
107147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar
107256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
107356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[0] = 1;        // version
107446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[1] = 0x64;     // profile (default to high)
107546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[2] = 0;        // constraints (default to none)
107646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[3] = 0xd;      // level (default to 1.3)
107756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[4] = 0xff;     // reserved+size
107856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
107956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    size_t i = 0;
108056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numparams = 0;
108156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int lastparamoffset = 0;
108256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int avccidx = 6;
108356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
108447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
108547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        ALOGV("block at %zu, last was %d", i, lastparamoffset);
108647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        if (lastparamoffset > 0) {
108747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            const uint8_t *lastparam = csd0->data() + lastparamoffset;
108847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            int size = i - lastparamoffset;
108947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            if (size > 3) {
109047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
109147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
109247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                            avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
109347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                } else if (!numparams) {
109447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    // fill in profile, constraints and level
109547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    memcpy(avcc + 1, lastparam + 1, 3);
109647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                }
109756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
109847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size >> 8;
109947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size & 0xff;
110047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            memcpy(avcc+avccidx, lastparam, size);
110147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avccidx += size;
110247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            numparams++;
110347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        }
110447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i += 4;
110547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        lastparamoffset = i;
110656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd0->size());
110756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGV("csd0 contains %d params", numparams);
110856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
110956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[5] = 0xe0 | numparams;
111056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    //and now csd-1
111156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    i = 0;
111256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    numparams = 0;
111356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    lastparamoffset = 0;
111456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numpicparamsoffset = avccidx;
111556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avccidx++;
111656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
11177d58810be46a86fa5c66d6d53d2453a5accc76f8Lajos Molnar        i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
111847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        ALOGV("block at %zu, last was %d", i, lastparamoffset);
111947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        if (lastparamoffset > 0) {
112047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            int size = i - lastparamoffset;
112147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size >> 8;
112247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size & 0xff;
112347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
112447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avccidx += size;
112547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            numparams++;
112647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        }
112747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i += 4;
112847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        lastparamoffset = i;
112956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd1->size());
113056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[numpicparamsoffset] = numparams;
113156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    return avccidx;
113256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
113356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
113456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
113556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int csd0size = csd0->size();
113656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[0] = 3; // kTag_ESDescriptor;
113756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int esdescriptorsize = 26 + csd0size;
113856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
113956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[1] = 0x80 | (esdescriptorsize >> 21);
114056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
114156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
114256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[4] = (esdescriptorsize & 0x7f);
114356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[5] = esds[6] = 0; // es id
114456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[7] = 0; // flags
114556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[8] = 4; // kTag_DecoderConfigDescriptor
114656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int configdescriptorsize = 18 + csd0size;
114756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[9] = 0x80 | (configdescriptorsize >> 21);
114856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
114956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
115056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[12] = (configdescriptorsize & 0x7f);
115156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[13] = 0x40; // objectTypeIndication
115246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
115346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[14] = 0x15; // streamType(5), upStream(0),
115446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
115556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[16] = 0x18;
115656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[17] = 0x00;
115746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
115856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[19] = 0x00;
115956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[20] = 0xfa;
116056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[21] = 0x00;
116146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
116256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[23] = 0x00;
116356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[24] = 0xfa;
116456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[25] = 0x00;
116556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[26] = 5; // kTag_DecoderSpecificInfo;
116656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[27] = 0x80 | (csd0size >> 21);
116756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
116856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
116956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[30] = (csd0size & 0x7f);
117056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    memcpy((void*)&esds[31], csd0->data(), csd0size);
117156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // data following this is ignored, so don't bother appending it
117256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
117356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
11749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
11759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    HevcParameterSets paramSets;
11769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    uint8_t* data = csd0->data();
11779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (csd0->size() < 4) {
11789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 too small");
11799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11819aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
11829aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 doesn't start with a start code");
11839aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11849aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11859aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t prevNalOffset = 4;
11869aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    status_t err = OK;
11879aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    for (size_t i = 1; i < csd0->size() - 4; ++i) {
11889aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
11899aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            continue;
11909aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
11919aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
11929aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (err != OK) {
11939aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            return 0;
11949aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
11959aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        prevNalOffset = i + 4;
11969aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
11989aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
11999aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
12009aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
12019aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t size = hvccSize;
12029aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
12039aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
12049aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
12059aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
12069aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    return size;
12079aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}
12089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim
1209d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#if 0
1210caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataInt32(
1211caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
1212caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
1213caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (msg->findInt32(name, &value)) {
1214caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(key, value);
1215caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1216caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
1217d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar#endif
1218caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1219caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
1220caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
1221caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0, standard = 0, transfer = 0;
1222caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-range", &range);
1223caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-standard", &standard);
1224caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-transfer", &transfer);
1225caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1226caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
1227caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
1228caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
1229caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            range, standard, transfer, colorAspects) != OK) {
1230caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
1231caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1232caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1233caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to meta
1234caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mRange != 0) {
1235caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorRange, colorAspects.mRange);
1236caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1237caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mPrimaries != 0) {
1238caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
1239caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1240caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mTransfer != 0) {
1241caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
1242caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1243caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mMatrixCoeffs != 0) {
1244caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
1245caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1246caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
1247caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
124856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
124956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    AString mime;
125056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findString("mime", &mime)) {
125156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setCString(kKeyMIMEType, mime.c_str());
125256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else {
125356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        ALOGW("did not find mime type");
125456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
125556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
125656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int64_t durationUs;
125756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt64("durationUs", &durationUs)) {
125856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt64(kKeyDuration, durationUs);
125956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
126056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
12618c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
12628c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
12638c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        meta->setInt32(kKeyIsSyncFrame, 1);
12648c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
12658c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
1266ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t avgBitrate = 0;
1267ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t maxBitrate;
1268ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
1269ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar        meta->setInt32(kKeyBitRate, avgBitrate);
1270ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    }
1271ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
1272ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar        meta->setInt32(kKeyMaxBitRate, maxBitrate);
1273ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    }
1274ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar
127556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (mime.startsWith("video/")) {
127656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t width;
127756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t height;
127856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
127956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyWidth, width);
128056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyHeight, height);
128156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
128256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            ALOGW("did not find width and/or height");
128356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
1284516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
1285516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
1286516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (msg->findInt32("sar-width", &sarWidth)
1287516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && msg->findInt32("sar-height", &sarHeight)) {
1288516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARWidth, sarWidth);
1289516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARHeight, sarHeight);
1290516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
1291475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1292475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
1293475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("color-format", &colorFormat)) {
1294475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyColorFormat, colorFormat);
1295475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1296475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1297475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
1298475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findRect("crop",
1299475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropLeft,
1300475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropTop,
1301475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropRight,
1302475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropBottom)) {
1303475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
1304475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1305475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1306475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
1307475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1308475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyRotation, rotationDegrees);
1309475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1310caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1311d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        if (msg->contains("hdr-static-info")) {
1312d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            HDRStaticInfo info;
1313d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
1314d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar                meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
1315d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar            }
1316d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar        }
1317d637d296bb0954756d3d231633fad73fadd70316Lajos Molnar
1318caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataColorAspects(msg, meta);
131956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else if (mime.startsWith("audio/")) {
132056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t numChannels;
132156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-count", &numChannels)) {
132256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelCount, numChannels);
132356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
132456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t sampleRate;
132556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("sample-rate", &sampleRate)) {
132656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeySampleRate, sampleRate);
132756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
132856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t channelMask;
132956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-mask", &channelMask)) {
133056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelMask, channelMask);
133156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
133256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t delay = 0;
133356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-delay", &delay)) {
133456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderDelay, delay);
133556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
133656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t padding = 0;
133756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-padding", &padding)) {
133856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderPadding, padding);
133956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
134056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
134156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t isADTS;
134256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("is-adts", &isADTS)) {
134356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyIsADTS, isADTS);
134456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
134578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
134678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
134778bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
134878bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            meta->setInt32(kKeyPcmEncoding, pcmEncoding);
134978bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
135056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
135156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
135256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int32_t maxInputSize;
135356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt32("max-input-size", &maxInputSize)) {
135456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt32(kKeyMaxInputSize, maxInputSize);
135556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
135656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1357a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
1358a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-width", &maxWidth)) {
1359a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxWidth, maxWidth);
1360a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
1361a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
1362a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
1363a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-height", &maxHeight)) {
1364a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxHeight, maxHeight);
1365a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
1366a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
13678f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
136894e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    float fpsFloat;
13692a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
13708f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        meta->setInt32(kKeyFrameRate, fps);
137194e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    } else if (msg->findFloat("frame-rate", &fpsFloat)
137294e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
137394e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        // truncate values to distinguish between e.g. 24 vs 23.976 fps
137494e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
13758f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
13768f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
137756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // reassemble the csd data into its original form
1378d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar    sp<ABuffer> csd0, csd1, csd2;
137956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findBuffer("csd-0", &csd0)) {
138077f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
138156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            sp<ABuffer> csd1;
138256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (msg->findBuffer("csd-1", &csd1)) {
138356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                char avcc[1024]; // that oughta be enough, right?
138456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
138556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
138656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
138777f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
138856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            int csd0size = csd0->size();
138956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            char esds[csd0size + 31];
139077f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // The written ESDS is actually for an audio stream, but it's enough
139177f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // for transporting the CSD to muxers.
139256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            reassembleESDS(csd0, esds);
139356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
13949aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
13959aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            uint8_t hvcc[1024]; // that oughta be enough, right?
13969aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
13979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
1398d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar        } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
1399d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
1400d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar        } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
1401d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            meta->setData(kKeyOpusHeader, 0, csd0->data(), csd0->size());
1402d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            if (msg->findBuffer("csd-1", &csd1)) {
1403d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar                meta->setData(kKeyOpusCodecDelay, 0, csd1->data(), csd1->size());
1404d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            }
1405d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            if (msg->findBuffer("csd-2", &csd2)) {
1406d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar                meta->setData(kKeyOpusSeekPreRoll, 0, csd2->data(), csd2->size());
1407d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            }
1408d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar        } else if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
1409d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            meta->setData(kKeyVorbisInfo, 0, csd0->data(), csd0->size());
1410d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            if (msg->findBuffer("csd-1", &csd1)) {
1411d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar                meta->setData(kKeyVorbisBooks, 0, csd1->data(), csd1->size());
1412d218dde936336037026cb45ff5f5748caf73f4f9Lajos Molnar            }
141356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
141456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
141556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
14162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    int32_t timeScale;
14172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (msg->findInt32("time-scale", &timeScale)) {
14182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        meta->setInt32(kKeyTimeScale, timeScale);
14192c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
14202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
142156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // XXX TODO add whatever other keys there are
142256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
142356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0
142456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGI("converted %s to:", msg->debugString(0).c_str());
142556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    meta->dumpToLog();
142656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif
142756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
142856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1429cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() {
1430cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    AString ua;
1431cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
1432cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1433cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8)
1434cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
1435cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif
1436cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1437cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    char value[PROPERTY_VALUE_MAX];
1438cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    property_get("ro.build.version.release", value, "Unknown");
1439cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(value);
1440cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(")");
1441cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1442cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    return ua;
1443cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber}
144456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1445ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
1446ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                           const sp<MetaData>& meta)
1447ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
144894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t sampleRate = 0;
144994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t bitRate = 0;
145094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t channelMask = 0;
145194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t delaySamples = 0;
145294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t paddingSamples = 0;
145394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
145494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    AudioParameter param = AudioParameter();
145594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
145694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
145794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
145894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
145994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
146094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
146194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
146294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyBitRate, &bitRate)) {
146394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
146494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
146594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
146694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
146794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
146894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
146994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
147094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
147194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
147294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
147394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          "delaySample %d, paddingSample %d", bitRate, sampleRate,
147494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          channelMask, delaySamples, paddingSamples);
147594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
147694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    sink->setParameters(param.toString());
1477ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return OK;
1478ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1479ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
148094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t {
148194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char* mime;
148294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t format;
148394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
148494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
148594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = {
148694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
148794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
148894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
148994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
149094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
149194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
1492bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
149394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { 0, AUDIO_FORMAT_INVALID }
149494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
149594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
149694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
1497ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
149894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0];
149994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    while (p->mime != NULL) {
150094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (0 == strcasecmp(mime, p->mime)) {
150194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            format = p->format;
150294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return OK;
150394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
150494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ++p;
150594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
150694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
1507ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return BAD_VALUE;
1508ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1509ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
15102829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t {
15112829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
15122829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    audio_format_t format;
15132829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
15142829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
15152829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = {
15162829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
15172829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
15182829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
15192829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
15202829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
15212829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
15222829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
15232829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
15242829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
15252829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
15262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
15272829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
15282829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
15292829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
15302829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{
15312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0];
15322829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
15332829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if (eAacProfile == p->eAacProfileType) {
15342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            format = p->format;
15352829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            return;
15362829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
15372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        ++p;
15382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    }
15392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    format = AUDIO_FORMAT_AAC;
15402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    return;
15412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}
15422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
154322612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
154422612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent                      bool isStreaming, audio_stream_type_t streamType)
1545ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
154694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char *mime;
1547cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    if (meta == NULL) {
1548cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia        return false;
1549cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    }
155094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(meta->findCString(kKeyMIMEType, &mime));
155194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
155294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
155394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
155494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.format = AUDIO_FORMAT_INVALID;
155594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mapMimeToAudioFormat(info.format, mime) != OK) {
155694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
155794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
155894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
155994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
156094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
156194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
156294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (AUDIO_FORMAT_INVALID == info.format) {
156394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // can't offload if we don't know what the source format is
156494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE("mime type \"%s\" not a known audio format", mime);
156594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
156694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
156794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
15682829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Redefine aac format according to its profile
15692829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Offloading depends on audio DSP capabilities.
1570db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    int32_t aacaot = -1;
1571db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
15722829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1573db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    }
1574db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
157594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t srate = -1;
157694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeySampleRate, &srate)) {
157794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish sample rate", mime);
157894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
157994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.sample_rate = srate;
158094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
158194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t cmask = 0;
158294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
158394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish channel mask", mime);
158494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
158594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // Try a channel count instead
158694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        int32_t channelCount;
158794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
158894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("track of type '%s' does not publish channel count", mime);
158994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
159094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            cmask = audio_channel_out_mask_from_count(channelCount);
159194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
159294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
159394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.channel_mask = cmask;
159494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
159594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int64_t duration = 0;
159694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt64(kKeyDuration, &duration)) {
159794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish duration", mime);
159894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
159994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.duration_us = duration;
160094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
160194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t brate = -1;
160294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyBitRate, &brate)) {
160394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish bitrate", mime);
160446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    }
160594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.bit_rate = brate;
160694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
160794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
160822612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent    info.stream_type = streamType;
160994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.has_video = hasVideo;
161094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.is_streaming = isStreaming;
161194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
161294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // Check if offload is possible for given format, stream type, sample rate,
161394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // bit rate, duration, video and streaming
161494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return AudioSystem::isOffloadSupported(info);
1615ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1616ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
1617a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) {
1618a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (incognito) {
1619a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return AString("<URI suppressed>");
1620a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1621a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1622a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    char prop[PROPERTY_VALUE_MAX];
1623a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (property_get("media.stagefright.log-uri", prop, "false") &&
1624a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
1625a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return uri;
1626a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1627a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1628a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    // find scheme
1629a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    AString scheme;
1630a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    const char *chars = uri.c_str();
1631a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    for (size_t i = 0; i < uri.size(); i++) {
1632a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        const char c = chars[i];
1633a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        if (!isascii(c)) {
1634a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1635a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isalpha(c)) {
1636a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1637a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (i == 0) {
1638a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            // first character must be a letter
1639a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1640a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
1641a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1642a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (c != ':') {
1643a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1644a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        }
1645a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme = AString(uri, 0, i);
1646a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme.append("://<suppressed>");
1647a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return scheme;
1648a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1649a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    return AString("<no-scheme URI suppressed>");
1650a1df816c0677185534babba6ffc29970b048e52eLajos Molnar}
1651a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1652d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) :
1653d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mSeq(-1),
1654d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mTimeUs(-1ll),
1655d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mMeta(meta) {
1656d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (meta != NULL) {
1657d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
1658d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt64("timeUs", &mTimeUs));
1659d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1660d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1661d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1662978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const {
1663d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t segmentStartTimeUs = -1ll;
1664d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (mMeta != NULL) {
1665d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
1666978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1667978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t segmentFirstTimeUs;
1668978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
1669978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
1670978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        }
1671978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1672978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        // adjust segment time by playlist age (for live streaming)
1673978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t playlistTimeUs;
1674978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
1675978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
1676978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1677d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t durationUs;
1678d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
1679978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1680978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            // round to nearest whole segment
1681978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            playlistAgeUs = (playlistAgeUs + durationUs / 2)
1682978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                    / durationUs * durationUs;
1683978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1684978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs -= playlistAgeUs;
1685978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            if (segmentStartTimeUs < 0) {
1686978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                segmentStartTimeUs = 0;
1687978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            }
1688d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1689d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1690d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return segmentStartTimeUs;
1691d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1692d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1693d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) {
1694d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // we can only compare discontinuity sequence and timestamp.
1695d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // (mSegmentTimeUs is not reliable in live streaming case, it's the
1696d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // time starting from beginning of playlist but playlist could change.)
1697d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return t0.mSeq < t1.mSeq
1698d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
1699d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1700d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
17013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
17023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("speed", rate.mSpeed);
17033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("pitch", rate.mPitch);
17043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
17053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
17063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
17073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
17083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
17093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
17103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("speed", &rate->mSpeed));
17113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("pitch", &rate->mPitch));
17123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
17133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
17143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
17153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
17163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
17173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("sync-source", sync.mSource);
17183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
17193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("tolerance", sync.mTolerance);
17203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("video-fps", videoFpsHint);
17213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
17223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
17233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(
17243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        const sp<AMessage> &msg,
17253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings *sync /* nonnull */,
17263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        float *videoFps /* nonnull */) {
17273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    AVSyncSettings settings;
17283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
17293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
17303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
17313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("video-fps", videoFps));
17323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *sync = settings;
17333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
17343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
173583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) {
173683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    const size_t SIZE = 256;
173783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    char buffer[SIZE];
173883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    AString result;
173983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
174083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    struct stat s;
174183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    if (lstat(buffer, &s) == 0) {
174283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        if ((s.st_mode & S_IFMT) == S_IFLNK) {
174383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            char linkto[256];
174483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            int len = readlink(buffer, linkto, sizeof(linkto));
174583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            if(len > 0) {
174683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                if(len > 255) {
174783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[252] = '.';
174883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[253] = '.';
174983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[254] = '.';
175083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[255] = 0;
175183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                } else {
175283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[len] = 0;
175383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                }
175483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                result.append(linkto);
175583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            }
175683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        } else {
175783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append("unexpected type for ");
175883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append(buffer);
175983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        }
176083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    } else {
176183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append("couldn't open ");
176283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append(buffer);
176383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    }
176483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    return result;
176583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen}
176683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
176720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
176820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1769