Utils.cpp revision ad91cd24427222dccd90487fba5fef7e9400b5c4
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
99caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageInt32(
100caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
101caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
102caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (meta->findInt32(key, &value)) {
103caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32(name, value);
104caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
105caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
106caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
107caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
108caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
109caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0;
110caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t primaries = 0;
111caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t transferFunction = 0;
112caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t colorMatrix = 0;
113caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorRange, &range);
114caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorPrimaries, &primaries);
115caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyTransferFunction, &transferFunction);
116caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorMatrix, &colorMatrix);
117caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
118caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
119caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mRange = (ColorAspects::Range)range;
120caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
121caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
122caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
123caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
124caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t rangeMsg, standardMsg, transferMsg;
125caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertCodecColorAspectsToPlatformAspects(
126caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
127caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
128caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
129caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
130caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to msg
131caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (rangeMsg != 0) {
132caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-range", rangeMsg);
133caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
134caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (standardMsg != 0) {
135caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-standard", standardMsg);
136caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
137caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (transferMsg != 0) {
138caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-transfer", transferMsg);
139caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
140caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
141caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
14207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
14307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (csd->size() < 2) {
14407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
14507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
14607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
14707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
14807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if ((audioObjectType & 0xF800) == 0xF800) {
14907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
15007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    } else {
15107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        audioObjectType >>= 11;
15207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
15307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
15407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
15507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1,  OMX_AUDIO_AACObjectMain     },
15607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2,  OMX_AUDIO_AACObjectLC       },
15707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 3,  OMX_AUDIO_AACObjectSSR      },
15807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 4,  OMX_AUDIO_AACObjectLTP      },
15907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 5,  OMX_AUDIO_AACObjectHE       },
16007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 6,  OMX_AUDIO_AACObjectScalable },
16107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 17, OMX_AUDIO_AACObjectERLC     },
16207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 23, OMX_AUDIO_AACObjectLD       },
16307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 29, OMX_AUDIO_AACObjectHE_PS    },
16407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 39, OMX_AUDIO_AACObjectELD      },
16507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
16607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
16707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_AUDIO_AACPROFILETYPE profile;
16807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(audioObjectType, &profile)) {
16907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", profile);
17007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
17107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
17207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
17307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
17407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 4 || ptr[0] != 1) {  // configurationVersion == 1
17507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
17607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
17707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[1];
17807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t constraints = ptr[2];
17907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[3];
18007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
18107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
18207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        {  9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
18307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 10, OMX_VIDEO_AVCLevel1  },
18407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
18507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 11, OMX_VIDEO_AVCLevel1b },
18607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 12, OMX_VIDEO_AVCLevel12 },
18707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 13, OMX_VIDEO_AVCLevel13 },
18807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 20, OMX_VIDEO_AVCLevel2  },
18907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 21, OMX_VIDEO_AVCLevel21 },
19007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 22, OMX_VIDEO_AVCLevel22 },
19107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 30, OMX_VIDEO_AVCLevel3  },
19207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 31, OMX_VIDEO_AVCLevel31 },
19307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 32, OMX_VIDEO_AVCLevel32 },
19407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 40, OMX_VIDEO_AVCLevel4  },
19507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 41, OMX_VIDEO_AVCLevel41 },
19607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 42, OMX_VIDEO_AVCLevel42 },
19707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 50, OMX_VIDEO_AVCLevel5  },
19807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 51, OMX_VIDEO_AVCLevel51 },
19907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 52, OMX_VIDEO_AVCLevel52 },
20007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
20107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
20207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 66, OMX_VIDEO_AVCProfileBaseline },
20307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 77, OMX_VIDEO_AVCProfileMain     },
20407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 88, OMX_VIDEO_AVCProfileExtended },
20507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 100, OMX_VIDEO_AVCProfileHigh    },
20607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 110, OMX_VIDEO_AVCProfileHigh10  },
20707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 122, OMX_VIDEO_AVCProfileHigh422 },
20807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 244, OMX_VIDEO_AVCProfileHigh444 },
20907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
21007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
21107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
21207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_AVCPROFILETYPE codecProfile;
21307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_AVCLEVELTYPE codecLevel;
21407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(profile, &codecProfile)) {
21507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", codecProfile);
21607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (levels.map(level, &codecLevel)) {
21707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            // for 9 && 11 decide level based on profile and constraint_set3 flag
21807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
21907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
22007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
22107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", codecLevel);
22207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
22307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
22407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
22507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
22607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
22707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 7) {
22807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
22907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
23007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
23107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[6];
23207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[5];
23307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
23407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
23507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 0, OMX_VIDEO_H263ProfileBaseline },
23607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1, OMX_VIDEO_H263ProfileH320Coding },
23707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
23807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 3, OMX_VIDEO_H263ProfileISWV2 },
23907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 4, OMX_VIDEO_H263ProfileISWV3 },
24007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 5, OMX_VIDEO_H263ProfileHighCompression },
24107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 6, OMX_VIDEO_H263ProfileInternet },
24207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 7, OMX_VIDEO_H263ProfileInterlace },
24307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 8, OMX_VIDEO_H263ProfileHighLatency },
24407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
24507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
24607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
24707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 10, OMX_VIDEO_H263Level10 },
24807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 20, OMX_VIDEO_H263Level20 },
24907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 30, OMX_VIDEO_H263Level30 },
25007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 40, OMX_VIDEO_H263Level40 },
25107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 45, OMX_VIDEO_H263Level45 },
25207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 50, OMX_VIDEO_H263Level50 },
25307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 60, OMX_VIDEO_H263Level60 },
25407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 70, OMX_VIDEO_H263Level70 },
25507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
25607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
25707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
25807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_H263PROFILETYPE codecProfile;
25907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_H263LEVELTYPE codecLevel;
26007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (profiles.map(profile, &codecProfile)) {
26107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("profile", codecProfile);
26207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (levels.map(level, &codecLevel)) {
26307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", codecLevel);
26407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
26507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
26607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
26707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
26807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
26907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (size < 13 || ptr[0] != 1) {  // configurationVersion == 1
27007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        return;
27107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
27207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
27307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t profile = ptr[1] & 0x1F;
27407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t tier = (ptr[1] & 0x20) >> 5;
27507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t level = ptr[12];
27607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
27707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
27807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 30  }, OMX_VIDEO_HEVCMainTierLevel1  },
27907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 60  }, OMX_VIDEO_HEVCMainTierLevel2  },
28007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 63  }, OMX_VIDEO_HEVCMainTierLevel21 },
28107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 90  }, OMX_VIDEO_HEVCMainTierLevel3  },
28207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 93  }, OMX_VIDEO_HEVCMainTierLevel31 },
28307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4  },
28407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
28507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5  },
28607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
28707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
28807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6  },
28907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
29007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
29107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 30  }, OMX_VIDEO_HEVCHighTierLevel1  },
29207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 60  }, OMX_VIDEO_HEVCHighTierLevel2  },
29307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 63  }, OMX_VIDEO_HEVCHighTierLevel21 },
29407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 90  }, OMX_VIDEO_HEVCHighTierLevel3  },
29507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 93  }, OMX_VIDEO_HEVCHighTierLevel31 },
29607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4  },
29707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
29807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5  },
29907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
30007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
30107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6  },
30207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
30307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
30407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
30507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
30607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
30707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 1, OMX_VIDEO_HEVCProfileMain   },
30807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        { 2, OMX_VIDEO_HEVCProfileMain10 },
30907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    };
31007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
31107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // set profile & level if they are recognized
31207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_HEVCPROFILETYPE codecProfile;
31307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    OMX_VIDEO_HEVCLEVELTYPE codecLevel;
31407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (!profiles.map(profile, &codecProfile)) {
31507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
31607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            codecProfile = OMX_VIDEO_HEVCProfileMain;
31707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
31807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            codecProfile = OMX_VIDEO_HEVCProfileMain10;
31907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else {
32007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            return;
32107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
32207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
32307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    format->setInt32("profile", codecProfile);
32407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (levels.map(std::make_pair(tier, level), &codecLevel)) {
32507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        format->setInt32("level", codecLevel);
32607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
32707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
32807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
32907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg2ProfileLevelFromHeader(
33007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t *data, size_t size, sp<AMessage> &format) {
33107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // find sequence extension
33207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
33307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (seq != NULL && seq + 5 < data + size) {
33407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t start_code = seq[4] >> 4;
33507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (start_code != 1 /* sequence extension ID */) {
33607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            return;
33707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
33807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);
33907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
34007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
34107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x50, OMX_VIDEO_MPEG2ProfileSimple  },
34207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x40, OMX_VIDEO_MPEG2ProfileMain    },
34307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x30, OMX_VIDEO_MPEG2ProfileSNR     },
34407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
34507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x10, OMX_VIDEO_MPEG2ProfileHigh    },
34607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
34707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
34807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
34907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x0A, OMX_VIDEO_MPEG2LevelLL  },
35007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x08, OMX_VIDEO_MPEG2LevelML  },
35107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x06, OMX_VIDEO_MPEG2LevelH14 },
35207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x04, OMX_VIDEO_MPEG2LevelHL  },
35307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x02, OMX_VIDEO_MPEG2LevelHP  },
35407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
35507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
35607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t,
35707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
35807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
35907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL  } },
36007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML  } },
36107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
36207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL  } }, */
36307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML  } },
36407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL  } },
36507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
36607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
36707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2PROFILETYPE profile;
36807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2LEVELTYPE level;
36907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
37007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (escapes.map(indication, &profileLevel)) {
37107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profileLevel.first);
37207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", profileLevel.second);
37307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (profiles.map(indication & 0x70, &profile)) {
37407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profile);
37507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (levels.map(indication & 0xF, &level)) {
37607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                format->setInt32("level", level);
37707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
37807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
37907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
38007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
38107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
38207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
38307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // esds seems to only contain the profile for MPEG-2
38407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    uint8_t objType;
38507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (esds.getObjectTypeIndication(&objType) == OK) {
38607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
38707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x60, OMX_VIDEO_MPEG2ProfileSimple  },
38807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x61, OMX_VIDEO_MPEG2ProfileMain    },
38907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x62, OMX_VIDEO_MPEG2ProfileSNR     },
39007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
39107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x64, OMX_VIDEO_MPEG2ProfileHigh    },
39207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0x65, OMX_VIDEO_MPEG2Profile422     },
39307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
39407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
39507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        OMX_VIDEO_MPEG2PROFILETYPE profile;
39607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (profiles.map(objType, &profile)) {
39707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profile);
39807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
39907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
40007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
40107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
40207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
40307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *data = csd->data();
40407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    // find visual object sequence
40507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
40607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    if (seq != NULL && seq + 4 < data + csd->size()) {
40707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t indication = seq[4];
40807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
40907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const static ALookup<uint8_t,
41007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
41107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level1  } },
41207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level2  } },
41307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level3  } },
41407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level4a } },
41507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level5  } },
41607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level6  } },
41707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0  } },
41807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0b } },
41907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level0  } },
42007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level1  } },
42107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level2  } },
42207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
42307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level0  } },
42407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level1  } },
42507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level2  } }, */
42607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level1  } },
42707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level2  } },
42807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level2  } },
42907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level3  } },
43007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level4  } },
43107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* deprecated
43207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit,              OMX_VIDEO_MPEG4Level2  } }, */
43307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture,   OMX_VIDEO_MPEG4Level1  } },
43407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level1  } },
43507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level2  } },
43607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level1  } },
43707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level2  } },
43807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level1  } },
43907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level2  } },
44007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level1  } },
44107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level2  } },
44207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level1  } },
44307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level2  } },
44407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level3  } },
44507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level4  } },
44607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level1  } },
44707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level2  } },
44807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level3  } },
44907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level1  } },
45007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level2  } },
45107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level3  } },
45207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level4  } },
45307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level1  } },
45407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level2  } },
45507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level1  } },
45607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level2  } },
45707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level3  } },
45807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* unsupported
45907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100001, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level1  } },
46007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100010, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level2  } },
46107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level3  } },
46207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level4  } },
46307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100101, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level1  } },
46407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100110, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level2  } },
46507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11100111, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level3  } },
46607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101000, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level4  } },
46707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level5  } },
46807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11101100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level6  } }, */
46907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level0  } },
47007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level1  } },
47107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level2  } },
47207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3  } },
47307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level4  } },
47407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level5  } },
47507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3b } },
47607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            /* deprecated
47707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0  } },
47807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1  } },
47907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2  } },
48007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3  } },
48107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4  } },
48207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5  } }, */
48307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        };
48407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
48507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
48607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (table.map(indication, &profileLevel)) {
48707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("profile", profileLevel.first);
48807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            format->setInt32("level", profileLevel.second);
48907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
49007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
49107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
49207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
49307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnarstatic void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
49407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    const uint8_t *data = csd->data();
49507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    size_t remaining = csd->size();
49607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
49707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    while (remaining >= 2) {
49807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t id = data[0];
49907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t length = data[1];
50007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        remaining -= 2;
50107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        data += 2;
50207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (length > remaining) {
50307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            break;
50407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
50507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        switch (id) {
50607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            case 1 /* profileId */:
50707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (length >= 1) {
50807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
50907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 0, OMX_VIDEO_VP9Profile0 },
51007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 1, OMX_VIDEO_VP9Profile1 },
51107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 2, OMX_VIDEO_VP9Profile2 },
51207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 3, OMX_VIDEO_VP9Profile3 },
51307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    };
51407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
51507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    OMX_VIDEO_VP9PROFILETYPE profile;
51607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    if (profiles.map(data[0], &profile)) {
51707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        format->setInt32("profile", profile);
51807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    }
51907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                }
52007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
52107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            case 2 /* levelId */:
52207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                if (length >= 1) {
52307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
52407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 10, OMX_VIDEO_VP9Level1  },
52507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 11, OMX_VIDEO_VP9Level11 },
52607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 20, OMX_VIDEO_VP9Level2  },
52707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 21, OMX_VIDEO_VP9Level21 },
52807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 30, OMX_VIDEO_VP9Level3  },
52907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 31, OMX_VIDEO_VP9Level31 },
53007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 40, OMX_VIDEO_VP9Level4  },
53107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 41, OMX_VIDEO_VP9Level41 },
53207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 50, OMX_VIDEO_VP9Level5  },
53307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 51, OMX_VIDEO_VP9Level51 },
53407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 52, OMX_VIDEO_VP9Level52 },
53507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 60, OMX_VIDEO_VP9Level6  },
53607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 61, OMX_VIDEO_VP9Level61 },
53707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        { 62, OMX_VIDEO_VP9Level62 },
53807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    };
53907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
54007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    OMX_VIDEO_VP9LEVELTYPE level;
54107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    if (levels.map(data[0], &level)) {
54207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                        format->setInt32("level", level);
54307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                    }
54407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                }
54507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
54607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            default:
54707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                break;
54807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
54907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        remaining -= length;
55007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        data += length;
55107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    }
55207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar}
55307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
5549806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage(
5559806555d3930be43e11106281dee354820ac1c88Andreas Huber        const sp<MetaData> &meta, sp<AMessage> *format) {
55659e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
5579806555d3930be43e11106281dee354820ac1c88Andreas Huber    format->clear();
5589806555d3930be43e11106281dee354820ac1c88Andreas Huber
55959e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    if (meta == NULL) {
56059e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        ALOGE("convertMetaDataToMessage: NULL input");
56159e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        return BAD_VALUE;
56259e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    }
56359e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
5649806555d3930be43e11106281dee354820ac1c88Andreas Huber    const char *mime;
565f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    if (!meta->findCString(kKeyMIMEType, &mime)) {
566f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        return BAD_VALUE;
567f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    }
5689806555d3930be43e11106281dee354820ac1c88Andreas Huber
5699806555d3930be43e11106281dee354820ac1c88Andreas Huber    sp<AMessage> msg = new AMessage;
5709806555d3930be43e11106281dee354820ac1c88Andreas Huber    msg->setString("mime", mime);
5719806555d3930be43e11106281dee354820ac1c88Andreas Huber
5729806555d3930be43e11106281dee354820ac1c88Andreas Huber    int64_t durationUs;
5739806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt64(kKeyDuration, &durationUs)) {
5749806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt64("durationUs", durationUs);
5759806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
5769806555d3930be43e11106281dee354820ac1c88Andreas Huber
577ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t avgBitRate = 0;
578ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
57946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        msg->setInt32("bitrate", avgBitRate);
58046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    }
58146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
58246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    int32_t maxBitRate;
583ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
584ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            && maxBitRate > 0 && maxBitRate >= avgBitRate) {
58546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        msg->setInt32("max-bitrate", maxBitRate);
586bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
587bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
5888c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
5898c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
5908c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        msg->setInt32("is-sync-frame", 1);
5918c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
5928c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
593faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    // this only needs to be translated from meta to message as it is an extractor key
594faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    int32_t trackID;
595faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (meta->findInt32(kKeyTrackID, &trackID)) {
596faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        msg->setInt32("track-id", trackID);
597faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
598faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar
5999806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (!strncasecmp("video/", mime, 6)) {
6009806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t width, height;
601f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyWidth, &width)
602f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeyHeight, &height)) {
603f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
604f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
6059806555d3930be43e11106281dee354820ac1c88Andreas Huber
6069806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("width", width);
6079806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("height", height);
608516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
609516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
610516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (meta->findInt32(kKeySARWidth, &sarWidth)
611516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && meta->findInt32(kKeySARHeight, &sarHeight)) {
612516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-width", sarWidth);
613516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-height", sarHeight);
614516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
615475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
616475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
617475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
618475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("color-format", colorFormat);
619475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
620475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
621475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
622475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findRect(kKeyCropRect,
623475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropLeft,
624475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropTop,
625475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropRight,
626475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropBottom)) {
627475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
628475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
629475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
630475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
631475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
632475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("rotation-degrees", rotationDegrees);
633475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
634caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
635caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance");
636caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance");
637caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageColorAspects(meta, msg);
6389806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (!strncasecmp("audio/", mime, 6)) {
6399806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t numChannels, sampleRate;
640f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyChannelCount, &numChannels)
641f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeySampleRate, &sampleRate)) {
642f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
643f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
6449806555d3930be43e11106281dee354820ac1c88Andreas Huber
6459806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("channel-count", numChannels);
6469806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("sample-rate", sampleRate);
6479806555d3930be43e11106281dee354820ac1c88Andreas Huber
6489806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t channelMask;
6499806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
6509806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("channel-mask", channelMask);
6519806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
6529806555d3930be43e11106281dee354820ac1c88Andreas Huber
6539806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t delay = 0;
6549806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
6559806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-delay", delay);
6569806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
6579806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t padding = 0;
6589806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
6599806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-padding", padding);
6609806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
6619806555d3930be43e11106281dee354820ac1c88Andreas Huber
6629806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t isADTS;
6639806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
6642954bca7bdec618da2b94a7e8ac62595b56598a3Pawin Vongmasa            msg->setInt32("is-adts", isADTS);
6659806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
666ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad
667ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        int32_t aacProfile = -1;
668ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
669ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad            msg->setInt32("aac-profile", aacProfile);
670ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        }
67178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
67278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
67378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
67478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            msg->setInt32("pcm-encoding", pcmEncoding);
67578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
6769806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
6779806555d3930be43e11106281dee354820ac1c88Andreas Huber
6789806555d3930be43e11106281dee354820ac1c88Andreas Huber    int32_t maxInputSize;
6799806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
6809806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("max-input-size", maxInputSize);
6819806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
6829806555d3930be43e11106281dee354820ac1c88Andreas Huber
683a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
684a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
685a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-width", maxWidth);
686a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
687a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
688a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
689a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
690a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-height", maxHeight);
691a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
692a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
693e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    int32_t rotationDegrees;
694e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
695e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        msg->setInt32("rotation-degrees", rotationDegrees);
696e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
697e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
6988f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
6992a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
7008f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        msg->setInt32("frame-rate", fps);
7018f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
7028f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
7039806555d3930be43e11106281dee354820ac1c88Andreas Huber    uint32_t type;
7049806555d3930be43e11106281dee354820ac1c88Andreas Huber    const void *data;
7059806555d3930be43e11106281dee354820ac1c88Andreas Huber    size_t size;
7069806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
7079806555d3930be43e11106281dee354820ac1c88Andreas Huber        // Parse the AVCDecoderConfigurationRecord
7089806555d3930be43e11106281dee354820ac1c88Andreas Huber
7099806555d3930be43e11106281dee354820ac1c88Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
7109806555d3930be43e11106281dee354820ac1c88Andreas Huber
7117bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
7127bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
7137bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
7147bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
71507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
71607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseAvcProfileLevelFromAvcc(ptr, size, msg);
7179806555d3930be43e11106281dee354820ac1c88Andreas Huber
7189806555d3930be43e11106281dee354820ac1c88Andreas Huber        // There is decodable content out there that fails the following
7199806555d3930be43e11106281dee354820ac1c88Andreas Huber        // assertion, let's be lenient for now...
7209806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
7219806555d3930be43e11106281dee354820ac1c88Andreas Huber
722b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t lengthSize __unused = 1 + (ptr[4] & 3);
7239806555d3930be43e11106281dee354820ac1c88Andreas Huber
7249806555d3930be43e11106281dee354820ac1c88Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
7259806555d3930be43e11106281dee354820ac1c88Andreas Huber        // violates it...
7269806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
7279806555d3930be43e11106281dee354820ac1c88Andreas Huber
7289806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
7299806555d3930be43e11106281dee354820ac1c88Andreas Huber
7309806555d3930be43e11106281dee354820ac1c88Andreas Huber        ptr += 6;
7319806555d3930be43e11106281dee354820ac1c88Andreas Huber        size -= 6;
7329806555d3930be43e11106281dee354820ac1c88Andreas Huber
7339c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
7349c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
7359c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
7369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
7379806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
7389806555d3930be43e11106281dee354820ac1c88Andreas Huber
7399806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
7407bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
7417bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
7427bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
7437bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
7449806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
7459806555d3930be43e11106281dee354820ac1c88Andreas Huber
7469806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
7479806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
7489806555d3930be43e11106281dee354820ac1c88Andreas Huber
7499c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
7509c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
7519c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
7529c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
7539c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
7549c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
7559c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
7569806555d3930be43e11106281dee354820ac1c88Andreas Huber
7579806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
7589806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
7599806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
7609806555d3930be43e11106281dee354820ac1c88Andreas Huber
7619806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
7629806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
7639806555d3930be43e11106281dee354820ac1c88Andreas Huber
7649806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
7659806555d3930be43e11106281dee354820ac1c88Andreas Huber
7669c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(1024);
7679c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
7689c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
7699c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
7709806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
7719806555d3930be43e11106281dee354820ac1c88Andreas Huber
7727bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 1) {
7737bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
7747bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
7757bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
7769806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numPictureParameterSets = *ptr;
7779806555d3930be43e11106281dee354820ac1c88Andreas Huber        ++ptr;
7789806555d3930be43e11106281dee354820ac1c88Andreas Huber        --size;
7799806555d3930be43e11106281dee354820ac1c88Andreas Huber
7809806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
7817bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
7827bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
7837bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
7847bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
7859806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
7869806555d3930be43e11106281dee354820ac1c88Andreas Huber
7879806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
7889806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
7899806555d3930be43e11106281dee354820ac1c88Andreas Huber
7909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
7919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
7929c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
7939c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
7949c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
7959c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
7969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
7979806555d3930be43e11106281dee354820ac1c88Andreas Huber
7989806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
7999806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
8009806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
8019806555d3930be43e11106281dee354820ac1c88Andreas Huber
8029806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
8039806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
8049806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
8053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
8063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
8073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8087bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
8097bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
8107bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
8117bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
81207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
81307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseHevcProfileLevelFromHvcc(ptr, size, msg);
8143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 22;
8153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 22;
8163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t numofArrays = (char)ptr[0];
8183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 1;
8193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 1;
8203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t j = 0, i = 0;
8213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8229c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
8239c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
8249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
8259c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
8263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->setRange(0, 0);
8273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        for (i = 0; i < numofArrays; i++) {
8297bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 3) {
8307bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
8317bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
8327bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
8333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 1;
8343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 1;
8353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            //Num of nals
8373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size_t numofNals = U16_AT(ptr);
8383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 2;
8403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 2;
8413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            for (j = 0; j < numofNals; j++) {
8437bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                if (size < 2) {
8447bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    ALOGE("b/23680780");
8457bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    return BAD_VALUE;
8467bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                }
8473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size_t length = U16_AT(ptr);
8483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += 2;
8503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= 2;
8513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8529c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (size < length) {
8539c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return BAD_VALUE;
8549c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
8559c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                status_t err = copyNALUToABuffer(&buffer, ptr, length);
8569c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (err != OK) {
8579c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return err;
8589c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
8593b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8603b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += length;
8613b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= length;
8623b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
8633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
8643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt32("csd", true);
8653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt64("timeUs", 0);
8663b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        msg->setBuffer("csd-0", buffer);
8673b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
8689806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
8699806555d3930be43e11106281dee354820ac1c88Andreas Huber        ESDS esds((const char *)data, size);
870f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (esds.InitCheck() != (status_t)OK) {
871f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
872f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
8739806555d3930be43e11106281dee354820ac1c88Andreas Huber
8749806555d3930be43e11106281dee354820ac1c88Andreas Huber        const void *codec_specific_data;
8759806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t codec_specific_data_size;
8769806555d3930be43e11106281dee354820ac1c88Andreas Huber        esds.getCodecSpecificInfo(
8779806555d3930be43e11106281dee354820ac1c88Andreas Huber                &codec_specific_data, &codec_specific_data_size);
8789806555d3930be43e11106281dee354820ac1c88Andreas Huber
8799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
8809c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
8819c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
8829c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
8839806555d3930be43e11106281dee354820ac1c88Andreas Huber
8849806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), codec_specific_data,
8859806555d3930be43e11106281dee354820ac1c88Andreas Huber               codec_specific_data_size);
8869806555d3930be43e11106281dee354820ac1c88Andreas Huber
8879806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
8889806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
8899806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
89046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar
89107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
89207b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseMpeg4ProfileLevelFromCsd(buffer, msg);
89307b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
89407b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseMpeg2ProfileLevelFromEsds(esds, msg);
89507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
89607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar                parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
89707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            }
89807b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
89907b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar            parseAacProfileFromCsd(buffer, msg);
90007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        }
90107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
90246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        uint32_t maxBitrate, avgBitrate;
90346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
90446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            if (!meta->hasData(kKeyBitRate)
90546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                    && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
90646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar                msg->setInt32("bitrate", (int32_t)avgBitrate);
907ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            } else {
908ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
909ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            }
910ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar            if (!meta->hasData(kKeyMaxBitRate)
911ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                    && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
912ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
91346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar            }
91446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar        }
91507b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar    } else if (meta->findData(kTypeD263, &type, &data, &size)) {
91607b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        const uint8_t *ptr = (const uint8_t *)data;
91707b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseH263ProfileLevelFromD263(ptr, size, msg);
9189806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
9199c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
9209c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9219c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9229c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9239806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
9249806555d3930be43e11106281dee354820ac1c88Andreas Huber
9259806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
9269806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
9279806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
9289806555d3930be43e11106281dee354820ac1c88Andreas Huber
9299806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
9309806555d3930be43e11106281dee354820ac1c88Andreas Huber            return -EINVAL;
9319806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
9329806555d3930be43e11106281dee354820ac1c88Andreas Huber
9339c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
9349c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9359c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9379806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
9389806555d3930be43e11106281dee354820ac1c88Andreas Huber
9399806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
9409806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
9419806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
942bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
9439c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
9449c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9459c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9469c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
947bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
948bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian
949bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
950bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
951bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
9529b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9539b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
9549b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
9559b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
9569b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9579c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
9589c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9599c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9609c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9619b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
9629b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9639b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
9649b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
9659b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-1", buffer);
9669b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9679b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
9689b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
9699b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
9709b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
9729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
9739c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
9749c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
9759b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
9769b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
9779b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
9789b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
9799b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-2", buffer);
980d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian    } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
981d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
982d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        if (buffer.get() == NULL || buffer->base() == NULL) {
983d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian            return NO_MEMORY;
984d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        }
985d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
986d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian
987d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
988d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
989d0d32c0d39b56d7e85fcaa61f3245ac7bbb1f9ebVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
99007b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar
99107b2fbfb40770f3be0f674596f2e51d257c6d2bdLajos Molnar        parseVp9ProfileLevelFromCsd(buffer, msg);
9929806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
9939806555d3930be43e11106281dee354820ac1c88Andreas Huber
994793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // TODO expose "crypto-key"/kKeyCryptoKey through public api
995793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
996793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
997793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        msg->setBuffer("crypto-key", buffer);
998793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(buffer->data(), data, size);
999793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
1000793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
10019806555d3930be43e11106281dee354820ac1c88Andreas Huber    *format = msg;
10029806555d3930be43e11106281dee354820ac1c88Andreas Huber
10039806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
10049806555d3930be43e11106281dee354820ac1c88Andreas Huber}
10059806555d3930be43e11106281dee354820ac1c88Andreas Huber
100647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnarconst uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
100747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    uint8_t *res = NULL;
100847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    if (length > 4) {
100947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        // minus 1 as to not match NAL start code at end
101047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
101147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    }
101247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar    return res != NULL && res < data + length - 4 ? res : &data[length];
101347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar}
101447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar
101556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
101656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[0] = 1;        // version
101746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[1] = 0x64;     // profile (default to high)
101846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[2] = 0;        // constraints (default to none)
101946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    avcc[3] = 0xd;      // level (default to 1.3)
102056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[4] = 0xff;     // reserved+size
102156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
102256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    size_t i = 0;
102356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numparams = 0;
102456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int lastparamoffset = 0;
102556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int avccidx = 6;
102656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
102747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
102847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        ALOGV("block at %zu, last was %d", i, lastparamoffset);
102947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        if (lastparamoffset > 0) {
103047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            const uint8_t *lastparam = csd0->data() + lastparamoffset;
103147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            int size = i - lastparamoffset;
103247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            if (size > 3) {
103347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
103447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
103547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                            avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
103647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                } else if (!numparams) {
103747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    // fill in profile, constraints and level
103847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                    memcpy(avcc + 1, lastparam + 1, 3);
103947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar                }
104056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
104147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size >> 8;
104247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size & 0xff;
104347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            memcpy(avcc+avccidx, lastparam, size);
104447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avccidx += size;
104547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            numparams++;
104647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        }
104747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i += 4;
104847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        lastparamoffset = i;
104956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd0->size());
105056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGV("csd0 contains %d params", numparams);
105156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
105256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[5] = 0xe0 | numparams;
105356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    //and now csd-1
105456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    i = 0;
105556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    numparams = 0;
105656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    lastparamoffset = 0;
105756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numpicparamsoffset = avccidx;
105856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avccidx++;
105956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
106047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
106147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        ALOGV("block at %zu, last was %d", i, lastparamoffset);
106247d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        if (lastparamoffset > 0) {
106347d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            int size = i - lastparamoffset;
106447d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size >> 8;
106547d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avcc[avccidx++] = size & 0xff;
106647d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
106747d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            avccidx += size;
106847d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar            numparams++;
106947d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        }
107047d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        i += 4;
107147d8891199f40a3a89c2910e4407f82a125df43bLajos Molnar        lastparamoffset = i;
107256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd1->size());
107356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[numpicparamsoffset] = numparams;
107456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    return avccidx;
107556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
107656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
107756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
107856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int csd0size = csd0->size();
107956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[0] = 3; // kTag_ESDescriptor;
108056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int esdescriptorsize = 26 + csd0size;
108156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
108256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[1] = 0x80 | (esdescriptorsize >> 21);
108356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
108456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
108556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[4] = (esdescriptorsize & 0x7f);
108656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[5] = esds[6] = 0; // es id
108756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[7] = 0; // flags
108856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[8] = 4; // kTag_DecoderConfigDescriptor
108956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int configdescriptorsize = 18 + csd0size;
109056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[9] = 0x80 | (configdescriptorsize >> 21);
109156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
109256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
109356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[12] = (configdescriptorsize & 0x7f);
109456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[13] = 0x40; // objectTypeIndication
109546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
109646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[14] = 0x15; // streamType(5), upStream(0),
109746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
109856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[16] = 0x18;
109956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[17] = 0x00;
110046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
110156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[19] = 0x00;
110256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[20] = 0xfa;
110356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[21] = 0x00;
110446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
110556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[23] = 0x00;
110656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[24] = 0xfa;
110756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[25] = 0x00;
110856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[26] = 5; // kTag_DecoderSpecificInfo;
110956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[27] = 0x80 | (csd0size >> 21);
111056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
111156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
111256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[30] = (csd0size & 0x7f);
111356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    memcpy((void*)&esds[31], csd0->data(), csd0size);
111456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // data following this is ignored, so don't bother appending it
111556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
111656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
11179aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
11189aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    HevcParameterSets paramSets;
11199aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    uint8_t* data = csd0->data();
11209aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (csd0->size() < 4) {
11219aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 too small");
11229aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11239aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11249aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
11259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 doesn't start with a start code");
11269aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11289aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t prevNalOffset = 4;
11299aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    status_t err = OK;
11309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    for (size_t i = 1; i < csd0->size() - 4; ++i) {
11319aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
11329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            continue;
11339aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
11349aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
11359aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (err != OK) {
11369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            return 0;
11379aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
11389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        prevNalOffset = i + 4;
11399aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11409aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
11419aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
11429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11439aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t size = hvccSize;
11459aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
11469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
11479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
11489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
11499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    return size;
11509aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}
11519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim
1152caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataInt32(
1153caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
1154caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
1155caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (msg->findInt32(name, &value)) {
1156caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(key, value);
1157caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1158caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
1159caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1160caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
1161caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
1162caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0, standard = 0, transfer = 0;
1163caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-range", &range);
1164caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-standard", &standard);
1165caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-transfer", &transfer);
1166caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1167caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
1168caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
1169caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
1170caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            range, standard, transfer, colorAspects) != OK) {
1171caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
1172caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1173caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1174caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to meta
1175caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mRange != 0) {
1176caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorRange, colorAspects.mRange);
1177caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1178caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mPrimaries != 0) {
1179caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
1180caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1181caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mTransfer != 0) {
1182caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
1183caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1184caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mMatrixCoeffs != 0) {
1185caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
1186caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
1187caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
1188caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
118956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
119056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    AString mime;
119156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findString("mime", &mime)) {
119256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setCString(kKeyMIMEType, mime.c_str());
119356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else {
119456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        ALOGW("did not find mime type");
119556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
119656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
119756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int64_t durationUs;
119856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt64("durationUs", &durationUs)) {
119956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt64(kKeyDuration, durationUs);
120056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
120156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
12028c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
12038c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
12048c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        meta->setInt32(kKeyIsSyncFrame, 1);
12058c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
12068c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
1207ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t avgBitrate = 0;
1208ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    int32_t maxBitrate;
1209ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
1210ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar        meta->setInt32(kKeyBitRate, avgBitrate);
1211ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    }
1212ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
1213ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar        meta->setInt32(kKeyMaxBitRate, maxBitrate);
1214ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar    }
1215ad91cd24427222dccd90487fba5fef7e9400b5c4Lajos Molnar
121656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (mime.startsWith("video/")) {
121756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t width;
121856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t height;
121956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
122056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyWidth, width);
122156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyHeight, height);
122256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
122356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            ALOGW("did not find width and/or height");
122456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
1225516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
1226516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
1227516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (msg->findInt32("sar-width", &sarWidth)
1228516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && msg->findInt32("sar-height", &sarHeight)) {
1229516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARWidth, sarWidth);
1230516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARHeight, sarHeight);
1231516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
1232475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1233475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
1234475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("color-format", &colorFormat)) {
1235475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyColorFormat, colorFormat);
1236475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1237475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1238475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
1239475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findRect("crop",
1240475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropLeft,
1241475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropTop,
1242475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropRight,
1243475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropBottom)) {
1244475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
1245475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1246475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1247475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
1248475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1249475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyRotation, rotationDegrees);
1250475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
1251caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1252caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
1253caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
1254caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataColorAspects(msg, meta);
125556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else if (mime.startsWith("audio/")) {
125656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t numChannels;
125756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-count", &numChannels)) {
125856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelCount, numChannels);
125956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
126056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t sampleRate;
126156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("sample-rate", &sampleRate)) {
126256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeySampleRate, sampleRate);
126356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
126456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t channelMask;
126556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-mask", &channelMask)) {
126656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelMask, channelMask);
126756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
126856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t delay = 0;
126956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-delay", &delay)) {
127056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderDelay, delay);
127156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
127256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t padding = 0;
127356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-padding", &padding)) {
127456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderPadding, padding);
127556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
127656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
127756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t isADTS;
127856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("is-adts", &isADTS)) {
127956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyIsADTS, isADTS);
128056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
128178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
128278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
128378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
128478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            meta->setInt32(kKeyPcmEncoding, pcmEncoding);
128578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
128656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
128756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
128856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int32_t maxInputSize;
128956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt32("max-input-size", &maxInputSize)) {
129056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt32(kKeyMaxInputSize, maxInputSize);
129156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
129256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1293a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
1294a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-width", &maxWidth)) {
1295a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxWidth, maxWidth);
1296a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
1297a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
1298a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
1299a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-height", &maxHeight)) {
1300a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxHeight, maxHeight);
1301a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
1302a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
13038f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
130494e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    float fpsFloat;
13052a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
13068f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        meta->setInt32(kKeyFrameRate, fps);
130794e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    } else if (msg->findFloat("frame-rate", &fpsFloat)
130894e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
130994e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        // truncate values to distinguish between e.g. 24 vs 23.976 fps
131094e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
13118f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
13128f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
131356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // reassemble the csd data into its original form
131456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    sp<ABuffer> csd0;
131556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findBuffer("csd-0", &csd0)) {
131677f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
131756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            sp<ABuffer> csd1;
131856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (msg->findBuffer("csd-1", &csd1)) {
131956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                char avcc[1024]; // that oughta be enough, right?
132056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
132156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
132256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
132377f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
132456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            int csd0size = csd0->size();
132556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            char esds[csd0size + 31];
132677f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // The written ESDS is actually for an audio stream, but it's enough
132777f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // for transporting the CSD to muxers.
132856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            reassembleESDS(csd0, esds);
132956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
13309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
13319aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            uint8_t hvcc[1024]; // that oughta be enough, right?
13329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
13339aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
133456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
133556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
133656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
13372c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    int32_t timeScale;
13382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (msg->findInt32("time-scale", &timeScale)) {
13392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        meta->setInt32(kKeyTimeScale, timeScale);
13402c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
13412c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
134256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // XXX TODO add whatever other keys there are
134356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
134456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0
134556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGI("converted %s to:", msg->debugString(0).c_str());
134656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    meta->dumpToLog();
134756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif
134856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
134956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1350cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() {
1351cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    AString ua;
1352cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
1353cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1354cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8)
1355cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
1356cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif
1357cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1358cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    char value[PROPERTY_VALUE_MAX];
1359cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    property_get("ro.build.version.release", value, "Unknown");
1360cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(value);
1361cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(")");
1362cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
1363cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    return ua;
1364cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber}
136556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
1366ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
1367ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                           const sp<MetaData>& meta)
1368ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
136994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t sampleRate = 0;
137094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t bitRate = 0;
137194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t channelMask = 0;
137294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t delaySamples = 0;
137394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t paddingSamples = 0;
137494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
137594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    AudioParameter param = AudioParameter();
137694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
137794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
137894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
137994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
138094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
138194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
138294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
138394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyBitRate, &bitRate)) {
138494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
138594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
138694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
138794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
138894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
138994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
139094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
139194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
139294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
139394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
139494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          "delaySample %d, paddingSample %d", bitRate, sampleRate,
139594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          channelMask, delaySamples, paddingSamples);
139694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
139794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    sink->setParameters(param.toString());
1398ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return OK;
1399ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1400ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
140194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t {
140294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char* mime;
140394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t format;
140494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
140594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
140694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = {
140794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
140894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
140994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
141094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
141194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
141294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
1413bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
141494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { 0, AUDIO_FORMAT_INVALID }
141594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
141694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
141794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
1418ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
141994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0];
142094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    while (p->mime != NULL) {
142194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (0 == strcasecmp(mime, p->mime)) {
142294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            format = p->format;
142394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return OK;
142494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
142594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ++p;
142694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
142794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
1428ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return BAD_VALUE;
1429ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1430ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
14312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t {
14322829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
14332829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    audio_format_t format;
14342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
14352829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
14362829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = {
14372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
14382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
14392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
14402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
14412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
14422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
14432829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
14442829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
14452829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
14462829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
14472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
14482829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
14492829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
14502829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
14512829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{
14522829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0];
14532829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
14542829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if (eAacProfile == p->eAacProfileType) {
14552829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            format = p->format;
14562829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            return;
14572829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
14582829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        ++p;
14592829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    }
14602829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    format = AUDIO_FORMAT_AAC;
14612829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    return;
14622829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}
14632829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
146422612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
146522612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent                      bool isStreaming, audio_stream_type_t streamType)
1466ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
146794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char *mime;
1468cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    if (meta == NULL) {
1469cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia        return false;
1470cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    }
147194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(meta->findCString(kKeyMIMEType, &mime));
147294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
147394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
147494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
147594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.format = AUDIO_FORMAT_INVALID;
147694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mapMimeToAudioFormat(info.format, mime) != OK) {
147794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
147894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
147994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
148094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
148194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
148294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
148394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (AUDIO_FORMAT_INVALID == info.format) {
148494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // can't offload if we don't know what the source format is
148594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE("mime type \"%s\" not a known audio format", mime);
148694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
148794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
148894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
14892829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Redefine aac format according to its profile
14902829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Offloading depends on audio DSP capabilities.
1491db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    int32_t aacaot = -1;
1492db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
14932829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1494db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    }
1495db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
149694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t srate = -1;
149794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeySampleRate, &srate)) {
149894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish sample rate", mime);
149994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
150094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.sample_rate = srate;
150194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
150294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t cmask = 0;
150394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
150494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish channel mask", mime);
150594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
150694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // Try a channel count instead
150794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        int32_t channelCount;
150894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
150994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("track of type '%s' does not publish channel count", mime);
151094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
151194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            cmask = audio_channel_out_mask_from_count(channelCount);
151294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
151394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
151494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.channel_mask = cmask;
151594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
151694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int64_t duration = 0;
151794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt64(kKeyDuration, &duration)) {
151894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish duration", mime);
151994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
152094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.duration_us = duration;
152194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
152294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t brate = -1;
152394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyBitRate, &brate)) {
152494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish bitrate", mime);
152546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar    }
152694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.bit_rate = brate;
152794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
152894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
152922612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent    info.stream_type = streamType;
153094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.has_video = hasVideo;
153194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.is_streaming = isStreaming;
153294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
153394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // Check if offload is possible for given format, stream type, sample rate,
153494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // bit rate, duration, video and streaming
153594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return AudioSystem::isOffloadSupported(info);
1536ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1537ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
1538a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) {
1539a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (incognito) {
1540a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return AString("<URI suppressed>");
1541a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1542a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1543a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    char prop[PROPERTY_VALUE_MAX];
1544a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (property_get("media.stagefright.log-uri", prop, "false") &&
1545a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
1546a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return uri;
1547a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1548a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1549a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    // find scheme
1550a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    AString scheme;
1551a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    const char *chars = uri.c_str();
1552a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    for (size_t i = 0; i < uri.size(); i++) {
1553a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        const char c = chars[i];
1554a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        if (!isascii(c)) {
1555a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1556a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isalpha(c)) {
1557a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1558a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (i == 0) {
1559a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            // first character must be a letter
1560a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1561a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
1562a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1563a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (c != ':') {
1564a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1565a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        }
1566a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme = AString(uri, 0, i);
1567a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme.append("://<suppressed>");
1568a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return scheme;
1569a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1570a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    return AString("<no-scheme URI suppressed>");
1571a1df816c0677185534babba6ffc29970b048e52eLajos Molnar}
1572a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1573d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) :
1574d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mSeq(-1),
1575d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mTimeUs(-1ll),
1576d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mMeta(meta) {
1577d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (meta != NULL) {
1578d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
1579d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt64("timeUs", &mTimeUs));
1580d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1581d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1582d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1583978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const {
1584d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t segmentStartTimeUs = -1ll;
1585d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (mMeta != NULL) {
1586d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
1587978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1588978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t segmentFirstTimeUs;
1589978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
1590978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
1591978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        }
1592978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1593978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        // adjust segment time by playlist age (for live streaming)
1594978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t playlistTimeUs;
1595978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
1596978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
1597978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1598d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t durationUs;
1599d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
1600978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1601978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            // round to nearest whole segment
1602978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            playlistAgeUs = (playlistAgeUs + durationUs / 2)
1603978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                    / durationUs * durationUs;
1604978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1605978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs -= playlistAgeUs;
1606978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            if (segmentStartTimeUs < 0) {
1607978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                segmentStartTimeUs = 0;
1608978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            }
1609d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1610d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1611d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return segmentStartTimeUs;
1612d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1613d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1614d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) {
1615d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // we can only compare discontinuity sequence and timestamp.
1616d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // (mSegmentTimeUs is not reliable in live streaming case, it's the
1617d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // time starting from beginning of playlist but playlist could change.)
1618d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return t0.mSeq < t1.mSeq
1619d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
1620d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1621d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
16223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
16233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("speed", rate.mSpeed);
16243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("pitch", rate.mPitch);
16253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
16263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
16273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
16283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
16293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
16303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
16313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("speed", &rate->mSpeed));
16323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("pitch", &rate->mPitch));
16333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
16343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
16353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
16363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
16373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
16383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("sync-source", sync.mSource);
16393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
16403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("tolerance", sync.mTolerance);
16413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("video-fps", videoFpsHint);
16423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
16433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
16443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(
16453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        const sp<AMessage> &msg,
16463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings *sync /* nonnull */,
16473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        float *videoFps /* nonnull */) {
16483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    AVSyncSettings settings;
16493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
16503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
16513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
16523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("video-fps", videoFps));
16533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *sync = settings;
16543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
16553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
165683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) {
165783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    const size_t SIZE = 256;
165883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    char buffer[SIZE];
165983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    AString result;
166083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
166183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    struct stat s;
166283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    if (lstat(buffer, &s) == 0) {
166383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        if ((s.st_mode & S_IFMT) == S_IFLNK) {
166483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            char linkto[256];
166583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            int len = readlink(buffer, linkto, sizeof(linkto));
166683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            if(len > 0) {
166783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                if(len > 255) {
166883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[252] = '.';
166983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[253] = '.';
167083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[254] = '.';
167183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[255] = 0;
167283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                } else {
167383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[len] = 0;
167483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                }
167583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                result.append(linkto);
167683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            }
167783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        } else {
167883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append("unexpected type for ");
167983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append(buffer);
168083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        }
168183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    } else {
168283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append("couldn't open ");
168383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append(buffer);
168483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    }
168583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    return result;
168683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen}
168783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
168820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
168920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1690