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