Utils.cpp revision 94e5455150064f40041dddf7a1a83b8414f01b91
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
249806555d3930be43e11106281dee354820ac1c88Andreas Huber#include "include/ESDS.h"
259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include "include/HevcUtils.h"
269806555d3930be43e11106281dee354820ac1c88Andreas Huber
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
28cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#include <cutils/properties.h>
292829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad#include <media/openmax/OMX_Audio.h>
30caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu#include <media/stagefright/CodecBase.h>
319806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
329806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h>
339806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h>
349806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h>
3594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/MediaDefs.h>
3694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioSystem.h>
3794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/MediaPlayerInterface.h>
3894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <hardware/audio.h>
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
4094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioParameter.h>
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) {
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ptr[0] << 8 | ptr[1];
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) {
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) {
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) {
57ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ptr[0] | (ptr[1] << 8);
58ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
59ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
60ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) {
61ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
62ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
63ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
64ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) {
65ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber    return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
66ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber}
67ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host.
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) {
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) {
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
779c170c076382096b9e767da0e3f9f37dafa76546Wei Jiastatic status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
789c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
809c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
819c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
829c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        tmpBuffer->setRange(0, (*buffer)->size());
859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        (*buffer) = tmpBuffer;
869c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    }
879c170c076382096b9e767da0e3f9f37dafa76546Wei Jia
889c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
899c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia    return OK;
929c170c076382096b9e767da0e3f9f37dafa76546Wei Jia}
939c170c076382096b9e767da0e3f9f37dafa76546Wei Jia
94caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageInt32(
95caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
96caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
97caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (meta->findInt32(key, &value)) {
98caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32(name, value);
99caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
100caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
101caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
102caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
103caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
104caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0;
105caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t primaries = 0;
106caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t transferFunction = 0;
107caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t colorMatrix = 0;
108caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorRange, &range);
109caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorPrimaries, &primaries);
110caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyTransferFunction, &transferFunction);
111caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    meta->findInt32(kKeyColorMatrix, &colorMatrix);
112caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
113caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
114caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mRange = (ColorAspects::Range)range;
115caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
116caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
117caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
118caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
119caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t rangeMsg, standardMsg, transferMsg;
120caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertCodecColorAspectsToPlatformAspects(
121caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
122caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
123caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
124caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
125caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to msg
126caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (rangeMsg != 0) {
127caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-range", rangeMsg);
128caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
129caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (standardMsg != 0) {
130caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-standard", standardMsg);
131caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
132caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (transferMsg != 0) {
133caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        msg->setInt32("color-transfer", transferMsg);
134caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
135caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
136caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
1379806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage(
1389806555d3930be43e11106281dee354820ac1c88Andreas Huber        const sp<MetaData> &meta, sp<AMessage> *format) {
13959e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
1409806555d3930be43e11106281dee354820ac1c88Andreas Huber    format->clear();
1419806555d3930be43e11106281dee354820ac1c88Andreas Huber
14259e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    if (meta == NULL) {
14359e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        ALOGE("convertMetaDataToMessage: NULL input");
14459e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen        return BAD_VALUE;
14559e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen    }
14659e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen
1479806555d3930be43e11106281dee354820ac1c88Andreas Huber    const char *mime;
148f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    if (!meta->findCString(kKeyMIMEType, &mime)) {
149f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        return BAD_VALUE;
150f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih    }
1519806555d3930be43e11106281dee354820ac1c88Andreas Huber
1529806555d3930be43e11106281dee354820ac1c88Andreas Huber    sp<AMessage> msg = new AMessage;
1539806555d3930be43e11106281dee354820ac1c88Andreas Huber    msg->setString("mime", mime);
1549806555d3930be43e11106281dee354820ac1c88Andreas Huber
1559806555d3930be43e11106281dee354820ac1c88Andreas Huber    int64_t durationUs;
1569806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt64(kKeyDuration, &durationUs)) {
1579806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt64("durationUs", durationUs);
1589806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
1599806555d3930be43e11106281dee354820ac1c88Andreas Huber
160bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    int avgBitRate;
161bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
162bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        msg->setInt32("bit-rate", avgBitRate);
163bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
164bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
1658c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
1668c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
1678c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        msg->setInt32("is-sync-frame", 1);
1688c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
1698c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
170faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    // this only needs to be translated from meta to message as it is an extractor key
171faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    int32_t trackID;
172faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    if (meta->findInt32(kKeyTrackID, &trackID)) {
173faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar        msg->setInt32("track-id", trackID);
174faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar    }
175faf35c0c279114b11a36615dc6630c126e767da0Lajos Molnar
1769806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (!strncasecmp("video/", mime, 6)) {
1779806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t width, height;
178f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyWidth, &width)
179f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeyHeight, &height)) {
180f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
181f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
1829806555d3930be43e11106281dee354820ac1c88Andreas Huber
1839806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("width", width);
1849806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("height", height);
185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
186516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
187516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (meta->findInt32(kKeySARWidth, &sarWidth)
188516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && meta->findInt32(kKeySARHeight, &sarHeight)) {
189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-width", sarWidth);
190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-height", sarHeight);
191516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
192475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
193475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
194475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
195475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("color-format", colorFormat);
196475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
197475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
198475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
199475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findRect(kKeyCropRect,
200475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropLeft,
201475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropTop,
202475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropRight,
203475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropBottom)) {
204475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
205475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
206475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
207475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
208475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
209475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("rotation-degrees", rotationDegrees);
210475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
211caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
212caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance");
213caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance");
214caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageColorAspects(meta, msg);
2159806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (!strncasecmp("audio/", mime, 6)) {
2169806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t numChannels, sampleRate;
217f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyChannelCount, &numChannels)
218f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeySampleRate, &sampleRate)) {
219f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
220f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
2219806555d3930be43e11106281dee354820ac1c88Andreas Huber
2229806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("channel-count", numChannels);
2239806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("sample-rate", sampleRate);
2249806555d3930be43e11106281dee354820ac1c88Andreas Huber
2259806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t channelMask;
2269806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
2279806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("channel-mask", channelMask);
2289806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2299806555d3930be43e11106281dee354820ac1c88Andreas Huber
2309806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t delay = 0;
2319806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
2329806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-delay", delay);
2339806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2349806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t padding = 0;
2359806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
2369806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-padding", padding);
2379806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2389806555d3930be43e11106281dee354820ac1c88Andreas Huber
2399806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t isADTS;
2409806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
2412954bca7bdec618da2b94a7e8ac62595b56598a3Pawin Vongmasa            msg->setInt32("is-adts", isADTS);
2429806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
243ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad
244ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        int32_t aacProfile = -1;
245ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
246ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad            msg->setInt32("aac-profile", aacProfile);
247ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        }
24878bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
24978bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
25078bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
25178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            msg->setInt32("pcm-encoding", pcmEncoding);
25278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
2539806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2549806555d3930be43e11106281dee354820ac1c88Andreas Huber
2559806555d3930be43e11106281dee354820ac1c88Andreas Huber    int32_t maxInputSize;
2569806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
2579806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("max-input-size", maxInputSize);
2589806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2599806555d3930be43e11106281dee354820ac1c88Andreas Huber
260a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
261a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
262a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-width", maxWidth);
263a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
264a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
265a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
266a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
267a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-height", maxHeight);
268a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
269a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
270e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    int32_t rotationDegrees;
271e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
272e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        msg->setInt32("rotation-degrees", rotationDegrees);
273e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
274e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
2758f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
2762a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
2778f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        msg->setInt32("frame-rate", fps);
2788f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
2798f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
2809806555d3930be43e11106281dee354820ac1c88Andreas Huber    uint32_t type;
2819806555d3930be43e11106281dee354820ac1c88Andreas Huber    const void *data;
2829806555d3930be43e11106281dee354820ac1c88Andreas Huber    size_t size;
2839806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
2849806555d3930be43e11106281dee354820ac1c88Andreas Huber        // Parse the AVCDecoderConfigurationRecord
2859806555d3930be43e11106281dee354820ac1c88Andreas Huber
2869806555d3930be43e11106281dee354820ac1c88Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
2879806555d3930be43e11106281dee354820ac1c88Andreas Huber
2887bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
2897bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
2907bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
2917bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
292b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1];
293b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[3];
2949806555d3930be43e11106281dee354820ac1c88Andreas Huber
2959806555d3930be43e11106281dee354820ac1c88Andreas Huber        // There is decodable content out there that fails the following
2969806555d3930be43e11106281dee354820ac1c88Andreas Huber        // assertion, let's be lenient for now...
2979806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
2989806555d3930be43e11106281dee354820ac1c88Andreas Huber
299b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t lengthSize __unused = 1 + (ptr[4] & 3);
3009806555d3930be43e11106281dee354820ac1c88Andreas Huber
3019806555d3930be43e11106281dee354820ac1c88Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
3029806555d3930be43e11106281dee354820ac1c88Andreas Huber        // violates it...
3039806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
3049806555d3930be43e11106281dee354820ac1c88Andreas Huber
3059806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
3069806555d3930be43e11106281dee354820ac1c88Andreas Huber
3079806555d3930be43e11106281dee354820ac1c88Andreas Huber        ptr += 6;
3089806555d3930be43e11106281dee354820ac1c88Andreas Huber        size -= 6;
3099806555d3930be43e11106281dee354820ac1c88Andreas Huber
3109c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
3119c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3129c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3139c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3149806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3159806555d3930be43e11106281dee354820ac1c88Andreas Huber
3169806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
3177bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3187bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3197bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3207bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3219806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3229806555d3930be43e11106281dee354820ac1c88Andreas Huber
3239806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3249806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3259806555d3930be43e11106281dee354820ac1c88Andreas Huber
3269c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3279c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3289c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3299c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3309c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3319c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3329c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3339806555d3930be43e11106281dee354820ac1c88Andreas Huber
3349806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3359806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3369806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3379806555d3930be43e11106281dee354820ac1c88Andreas Huber
3389806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3399806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3409806555d3930be43e11106281dee354820ac1c88Andreas Huber
3419806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber
3439c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(1024);
3449c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3459c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3469c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3479806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3489806555d3930be43e11106281dee354820ac1c88Andreas Huber
3497bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 1) {
3507bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3517bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3527bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
3539806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numPictureParameterSets = *ptr;
3549806555d3930be43e11106281dee354820ac1c88Andreas Huber        ++ptr;
3559806555d3930be43e11106281dee354820ac1c88Andreas Huber        --size;
3569806555d3930be43e11106281dee354820ac1c88Andreas Huber
3579806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
3587bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3597bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3607bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3617bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3629806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3639806555d3930be43e11106281dee354820ac1c88Andreas Huber
3649806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber
3679c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3689c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3699c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3709c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3739c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3749806555d3930be43e11106281dee354820ac1c88Andreas Huber
3759806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3769806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3779806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3789806555d3930be43e11106281dee354820ac1c88Andreas Huber
3799806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3809806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3819806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
3823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
3833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
3843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3857bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
3867bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3877bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3887bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
389b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1] & 31;
390b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[12];
3913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 22;
3923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 22;
3933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t numofArrays = (char)ptr[0];
3963b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 1;
3973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 1;
3983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t j = 0, i = 0;
3993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
4019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4029c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4039c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4043b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->setRange(0, 0);
4053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        for (i = 0; i < numofArrays; i++) {
4077bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 3) {
4087bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
4097bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
4107bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
4113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 1;
4123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 1;
4133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            //Num of nals
4153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size_t numofNals = U16_AT(ptr);
4163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 2;
4183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 2;
4193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            for (j = 0; j < numofNals; j++) {
4217bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                if (size < 2) {
4227bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    ALOGE("b/23680780");
4237bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    return BAD_VALUE;
4247bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                }
4253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size_t length = U16_AT(ptr);
4263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += 2;
4283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= 2;
4293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4309c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (size < length) {
4319c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return BAD_VALUE;
4329c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4339c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                status_t err = copyNALUToABuffer(&buffer, ptr, length);
4349c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (err != OK) {
4359c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return err;
4369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += length;
4393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= length;
4403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
4413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
4423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt32("csd", true);
4433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt64("timeUs", 0);
4443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        msg->setBuffer("csd-0", buffer);
4453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4469806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
4479806555d3930be43e11106281dee354820ac1c88Andreas Huber        ESDS esds((const char *)data, size);
448f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (esds.InitCheck() != (status_t)OK) {
449f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
450f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
4519806555d3930be43e11106281dee354820ac1c88Andreas Huber
4529806555d3930be43e11106281dee354820ac1c88Andreas Huber        const void *codec_specific_data;
4539806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t codec_specific_data_size;
4549806555d3930be43e11106281dee354820ac1c88Andreas Huber        esds.getCodecSpecificInfo(
4559806555d3930be43e11106281dee354820ac1c88Andreas Huber                &codec_specific_data, &codec_specific_data_size);
4569806555d3930be43e11106281dee354820ac1c88Andreas Huber
4579c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
4589c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4599c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4609c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4619806555d3930be43e11106281dee354820ac1c88Andreas Huber
4629806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), codec_specific_data,
4639806555d3930be43e11106281dee354820ac1c88Andreas Huber               codec_specific_data_size);
4649806555d3930be43e11106281dee354820ac1c88Andreas Huber
4659806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4669806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4679806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4689806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
4699c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4709c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4739806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4749806555d3930be43e11106281dee354820ac1c88Andreas Huber
4759806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4769806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4779806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4789806555d3930be43e11106281dee354820ac1c88Andreas Huber
4799806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
4809806555d3930be43e11106281dee354820ac1c88Andreas Huber            return -EINVAL;
4819806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
4829806555d3930be43e11106281dee354820ac1c88Andreas Huber
4839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
4849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4869c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4879806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4889806555d3930be43e11106281dee354820ac1c88Andreas Huber
4899806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4909806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4919806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
492bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
4939c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4949c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4959c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
497bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
498bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian
499bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
500bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
501bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
5029b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5039b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
5049b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
5059b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
5069b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5079c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
5089c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
5099c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
5109c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5119b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5129b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5139b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5149b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5159b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-1", buffer);
5169b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5179b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
5189b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
5199b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
5209b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5219c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
5229c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
5239c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
5249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5259b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5269b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5279b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5289b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5299b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-2", buffer);
5309806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
5319806555d3930be43e11106281dee354820ac1c88Andreas Huber
532793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // TODO expose "crypto-key"/kKeyCryptoKey through public api
533793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
534793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
535793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        msg->setBuffer("crypto-key", buffer);
536793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(buffer->data(), data, size);
537793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
538793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
5399806555d3930be43e11106281dee354820ac1c88Andreas Huber    *format = msg;
5409806555d3930be43e11106281dee354820ac1c88Andreas Huber
5419806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
5429806555d3930be43e11106281dee354820ac1c88Andreas Huber}
5439806555d3930be43e11106281dee354820ac1c88Andreas Huber
54456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
54556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
54656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[0] = 1;        // version
54756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[1] = 0x64;     // profile
54856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[2] = 0;        // unused (?)
54956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[3] = 0xd;      // level
55056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[4] = 0xff;     // reserved+size
55156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
55256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    size_t i = 0;
55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numparams = 0;
55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int lastparamoffset = 0;
55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int avccidx = 6;
55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
55756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd0->size() - 4 ||
55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd0->size() - 4) {
56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd0->size();
56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
563a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
57456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
57556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
57656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
57756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd0->size());
57856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGV("csd0 contains %d params", numparams);
57956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
58056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[5] = 0xe0 | numparams;
58156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    //and now csd-1
58256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    i = 0;
58356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    numparams = 0;
58456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    lastparamoffset = 0;
58556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numpicparamsoffset = avccidx;
58656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avccidx++;
58756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
58856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd1->size() - 4 ||
58956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
59056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd1->size() - 4) {
59156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
59256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd1->size();
59356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
594a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
59656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
59756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
59856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
59956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
60056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
60156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
60256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
60356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
60456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
60656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
60756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
60856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd1->size());
60956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[numpicparamsoffset] = numparams;
61056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    return avccidx;
61156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
61256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
61356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
61456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int csd0size = csd0->size();
61556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[0] = 3; // kTag_ESDescriptor;
61656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int esdescriptorsize = 26 + csd0size;
61756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
61856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[1] = 0x80 | (esdescriptorsize >> 21);
61956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
62056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
62156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[4] = (esdescriptorsize & 0x7f);
62256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[5] = esds[6] = 0; // es id
62356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[7] = 0; // flags
62456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[8] = 4; // kTag_DecoderConfigDescriptor
62556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int configdescriptorsize = 18 + csd0size;
62656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[9] = 0x80 | (configdescriptorsize >> 21);
62756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
62856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
62956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[12] = (configdescriptorsize & 0x7f);
63056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[13] = 0x40; // objectTypeIndication
63156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
63256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[15] = 0x00; // but the actual values here were taken from a real file.
63356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[16] = 0x18;
63456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[17] = 0x00;
63556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[18] = 0x00;
63656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[19] = 0x00;
63756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[20] = 0xfa;
63856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[21] = 0x00;
63956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[22] = 0x00;
64056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[23] = 0x00;
64156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[24] = 0xfa;
64256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[25] = 0x00;
64356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[26] = 5; // kTag_DecoderSpecificInfo;
64456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[27] = 0x80 | (csd0size >> 21);
64556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
64656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
64756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[30] = (csd0size & 0x7f);
64856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    memcpy((void*)&esds[31], csd0->data(), csd0size);
64956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // data following this is ignored, so don't bother appending it
65056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
65156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
65256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
6539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
6549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    HevcParameterSets paramSets;
6559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    uint8_t* data = csd0->data();
6569aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (csd0->size() < 4) {
6579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 too small");
6589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
6619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 doesn't start with a start code");
6629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t prevNalOffset = 4;
6659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    status_t err = OK;
6669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    for (size_t i = 1; i < csd0->size() - 4; ++i) {
6679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
6689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            continue;
6699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
6719aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (err != OK) {
6729aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            return 0;
6739aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        prevNalOffset = i + 4;
6759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
6779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t size = hvccSize;
6819aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
6829aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6839aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6849aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6859aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    return size;
6869aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}
6879aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim
688caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataInt32(
689caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
690caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
691caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (msg->findInt32(name, &value)) {
692caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(key, value);
693caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
694caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
695caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
696caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
697caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
698caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0, standard = 0, transfer = 0;
699caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-range", &range);
700caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-standard", &standard);
701caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-transfer", &transfer);
702caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
703caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
704caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
705caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
706caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            range, standard, transfer, colorAspects) != OK) {
707caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
708caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
709caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
710caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to meta
711caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mRange != 0) {
712caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorRange, colorAspects.mRange);
713caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
714caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mPrimaries != 0) {
715caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
716caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
717caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mTransfer != 0) {
718caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
719caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
720caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mMatrixCoeffs != 0) {
721caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
722caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
723caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
724caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
72556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
72656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    AString mime;
72756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findString("mime", &mime)) {
72856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setCString(kKeyMIMEType, mime.c_str());
72956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else {
73056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        ALOGW("did not find mime type");
73156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
73256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
73356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int64_t durationUs;
73456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt64("durationUs", &durationUs)) {
73556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt64(kKeyDuration, durationUs);
73656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
73756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
7388c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
7398c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
7408c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        meta->setInt32(kKeyIsSyncFrame, 1);
7418c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
7428c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
74356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (mime.startsWith("video/")) {
74456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t width;
74556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t height;
74656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
74756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyWidth, width);
74856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyHeight, height);
74956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
75056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            ALOGW("did not find width and/or height");
75156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
752516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
753516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
754516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (msg->findInt32("sar-width", &sarWidth)
755516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && msg->findInt32("sar-height", &sarHeight)) {
756516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARWidth, sarWidth);
757516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARHeight, sarHeight);
758516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
759475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
760475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
761475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("color-format", &colorFormat)) {
762475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyColorFormat, colorFormat);
763475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
764475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
765475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
766475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findRect("crop",
767475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropLeft,
768475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropTop,
769475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropRight,
770475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropBottom)) {
771475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
772475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
773475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
774475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
775475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
776475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyRotation, rotationDegrees);
777475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
778caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
779caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
780caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
781caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataColorAspects(msg, meta);
78256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else if (mime.startsWith("audio/")) {
78356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t numChannels;
78456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-count", &numChannels)) {
78556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelCount, numChannels);
78656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t sampleRate;
78856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("sample-rate", &sampleRate)) {
78956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeySampleRate, sampleRate);
79056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t channelMask;
79256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-mask", &channelMask)) {
79356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelMask, channelMask);
79456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t delay = 0;
79656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-delay", &delay)) {
79756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderDelay, delay);
79856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t padding = 0;
80056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-padding", &padding)) {
80156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderPadding, padding);
80256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
80356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
80456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t isADTS;
80556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("is-adts", &isADTS)) {
80656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyIsADTS, isADTS);
80756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
80878bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
80978bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
81078bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
81178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            meta->setInt32(kKeyPcmEncoding, pcmEncoding);
81278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
81356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
81456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
81556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int32_t maxInputSize;
81656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt32("max-input-size", &maxInputSize)) {
81756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt32(kKeyMaxInputSize, maxInputSize);
81856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
81956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
820a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
821a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-width", &maxWidth)) {
822a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxWidth, maxWidth);
823a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
824a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
825a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
826a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-height", &maxHeight)) {
827a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxHeight, maxHeight);
828a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
829a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
8308f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
83194e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    float fpsFloat;
8322a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
8338f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        meta->setInt32(kKeyFrameRate, fps);
83494e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar    } else if (msg->findFloat("frame-rate", &fpsFloat)
83594e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
83694e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        // truncate values to distinguish between e.g. 24 vs 23.976 fps
83794e5455150064f40041dddf7a1a83b8414f01b91Lajos Molnar        meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
8388f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
8398f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
84056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // reassemble the csd data into its original form
84156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    sp<ABuffer> csd0;
84256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findBuffer("csd-0", &csd0)) {
84377f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
84456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            sp<ABuffer> csd1;
84556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (msg->findBuffer("csd-1", &csd1)) {
84656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                char avcc[1024]; // that oughta be enough, right?
84756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
84856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
84956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
85077f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
85156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            int csd0size = csd0->size();
85256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            char esds[csd0size + 31];
85377f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // The written ESDS is actually for an audio stream, but it's enough
85477f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // for transporting the CSD to muxers.
85556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            reassembleESDS(csd0, esds);
85656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
8579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
8589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            uint8_t hvcc[1024]; // that oughta be enough, right?
8599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
8609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
86156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
86256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
86356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
8642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    int32_t timeScale;
8652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (msg->findInt32("time-scale", &timeScale)) {
8662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        meta->setInt32(kKeyTimeScale, timeScale);
8672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
8682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
86956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // XXX TODO add whatever other keys there are
87056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
87156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0
87256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGI("converted %s to:", msg->debugString(0).c_str());
87356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    meta->dumpToLog();
87456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif
87556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
87656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
877cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() {
878cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    AString ua;
879cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
880cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
881cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8)
882cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
883cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif
884cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
885cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    char value[PROPERTY_VALUE_MAX];
886cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    property_get("ro.build.version.release", value, "Unknown");
887cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(value);
888cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(")");
889cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
890cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    return ua;
891cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber}
89256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
893ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
894ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                           const sp<MetaData>& meta)
895ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
89694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t sampleRate = 0;
89794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t bitRate = 0;
89894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t channelMask = 0;
89994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t delaySamples = 0;
90094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t paddingSamples = 0;
90194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
90294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    AudioParameter param = AudioParameter();
90394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
90494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
90594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
90694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
90794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
90894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
90994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
91094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyBitRate, &bitRate)) {
91194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
91294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
91394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
91494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
91594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
91694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
91794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
91894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
91994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
92094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
92194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          "delaySample %d, paddingSample %d", bitRate, sampleRate,
92294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          channelMask, delaySamples, paddingSamples);
92394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
92494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    sink->setParameters(param.toString());
925ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return OK;
926ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
927ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
92894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t {
92994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char* mime;
93094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t format;
93194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
93294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
93394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = {
93494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
93594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
93694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
93794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
93894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
93994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
940bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
94194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { 0, AUDIO_FORMAT_INVALID }
94294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
94394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
94494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
945ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
94694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0];
94794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    while (p->mime != NULL) {
94894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (0 == strcasecmp(mime, p->mime)) {
94994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            format = p->format;
95094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return OK;
95194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
95294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ++p;
95394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
95494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
955ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return BAD_VALUE;
956ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
957ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
9582829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t {
9592829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
9602829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    audio_format_t format;
9612829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9622829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9632829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = {
9642829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
9652829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
9662829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
9672829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
9682829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
9692829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
9702829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
9712829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
9722829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
9732829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
9742829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
9752829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9762829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9772829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
9782829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{
9792829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0];
9802829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
9812829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if (eAacProfile == p->eAacProfileType) {
9822829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            format = p->format;
9832829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            return;
9842829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
9852829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        ++p;
9862829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    }
9872829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    format = AUDIO_FORMAT_AAC;
9882829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    return;
9892829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}
9902829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
99122612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
99222612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent                      bool isStreaming, audio_stream_type_t streamType)
993ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
99494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char *mime;
995cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    if (meta == NULL) {
996cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia        return false;
997cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    }
99894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(meta->findCString(kKeyMIMEType, &mime));
99994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
100094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
100194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
100294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.format = AUDIO_FORMAT_INVALID;
100394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mapMimeToAudioFormat(info.format, mime) != OK) {
100494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
100594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
100694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
100794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
100894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
100994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
101094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (AUDIO_FORMAT_INVALID == info.format) {
101194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // can't offload if we don't know what the source format is
101294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE("mime type \"%s\" not a known audio format", mime);
101394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
101494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
101594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
10162829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Redefine aac format according to its profile
10172829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Offloading depends on audio DSP capabilities.
1018db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    int32_t aacaot = -1;
1019db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
10202829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1021db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    }
1022db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
102394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t srate = -1;
102494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeySampleRate, &srate)) {
102594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish sample rate", mime);
102694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
102794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.sample_rate = srate;
102894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
102994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t cmask = 0;
103094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
103194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish channel mask", mime);
103294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // Try a channel count instead
103494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        int32_t channelCount;
103594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
103694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("track of type '%s' does not publish channel count", mime);
103794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
103894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            cmask = audio_channel_out_mask_from_count(channelCount);
103994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
104094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
104194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.channel_mask = cmask;
104294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
104394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int64_t duration = 0;
104494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt64(kKeyDuration, &duration)) {
104594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish duration", mime);
104694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
104794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.duration_us = duration;
104894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
104994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t brate = -1;
105094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyBitRate, &brate)) {
105194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish bitrate", mime);
105294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald     }
105394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.bit_rate = brate;
105494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
105594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
105622612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent    info.stream_type = streamType;
105794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.has_video = hasVideo;
105894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.is_streaming = isStreaming;
105994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
106094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // Check if offload is possible for given format, stream type, sample rate,
106194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // bit rate, duration, video and streaming
106294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return AudioSystem::isOffloadSupported(info);
1063ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1064ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
1065a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) {
1066a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (incognito) {
1067a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return AString("<URI suppressed>");
1068a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1069a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1070a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    char prop[PROPERTY_VALUE_MAX];
1071a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (property_get("media.stagefright.log-uri", prop, "false") &&
1072a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
1073a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return uri;
1074a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1075a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1076a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    // find scheme
1077a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    AString scheme;
1078a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    const char *chars = uri.c_str();
1079a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    for (size_t i = 0; i < uri.size(); i++) {
1080a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        const char c = chars[i];
1081a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        if (!isascii(c)) {
1082a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1083a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isalpha(c)) {
1084a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1085a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (i == 0) {
1086a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            // first character must be a letter
1087a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1088a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
1089a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1090a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (c != ':') {
1091a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1092a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        }
1093a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme = AString(uri, 0, i);
1094a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme.append("://<suppressed>");
1095a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return scheme;
1096a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1097a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    return AString("<no-scheme URI suppressed>");
1098a1df816c0677185534babba6ffc29970b048e52eLajos Molnar}
1099a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1100d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) :
1101d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mSeq(-1),
1102d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mTimeUs(-1ll),
1103d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mMeta(meta) {
1104d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (meta != NULL) {
1105d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
1106d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt64("timeUs", &mTimeUs));
1107d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1108d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1109d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1110978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const {
1111d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t segmentStartTimeUs = -1ll;
1112d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (mMeta != NULL) {
1113d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
1114978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1115978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t segmentFirstTimeUs;
1116978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
1117978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
1118978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        }
1119978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1120978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        // adjust segment time by playlist age (for live streaming)
1121978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t playlistTimeUs;
1122978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
1123978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
1124978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1125d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t durationUs;
1126d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
1127978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1128978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            // round to nearest whole segment
1129978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            playlistAgeUs = (playlistAgeUs + durationUs / 2)
1130978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                    / durationUs * durationUs;
1131978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1132978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs -= playlistAgeUs;
1133978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            if (segmentStartTimeUs < 0) {
1134978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                segmentStartTimeUs = 0;
1135978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            }
1136d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1137d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1138d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return segmentStartTimeUs;
1139d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1140d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1141d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) {
1142d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // we can only compare discontinuity sequence and timestamp.
1143d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // (mSegmentTimeUs is not reliable in live streaming case, it's the
1144d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // time starting from beginning of playlist but playlist could change.)
1145d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return t0.mSeq < t1.mSeq
1146d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
1147d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1148d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
11493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
11503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("speed", rate.mSpeed);
11513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("pitch", rate.mPitch);
11523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
11533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
11543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
11573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
11583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("speed", &rate->mSpeed));
11593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("pitch", &rate->mPitch));
11603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
11613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
11623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
11653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("sync-source", sync.mSource);
11663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
11673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("tolerance", sync.mTolerance);
11683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("video-fps", videoFpsHint);
11693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(
11723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        const sp<AMessage> &msg,
11733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings *sync /* nonnull */,
11743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        float *videoFps /* nonnull */) {
11753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    AVSyncSettings settings;
11763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
11773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
11783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
11793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("video-fps", videoFps));
11803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *sync = settings;
11813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
118383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) {
118483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    const size_t SIZE = 256;
118583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    char buffer[SIZE];
118683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    AString result;
118783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
118883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    struct stat s;
118983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    if (lstat(buffer, &s) == 0) {
119083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        if ((s.st_mode & S_IFMT) == S_IFLNK) {
119183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            char linkto[256];
119283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            int len = readlink(buffer, linkto, sizeof(linkto));
119383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            if(len > 0) {
119483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                if(len > 255) {
119583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[252] = '.';
119683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[253] = '.';
119783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[254] = '.';
119883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[255] = 0;
119983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                } else {
120083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[len] = 0;
120183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                }
120283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                result.append(linkto);
120383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            }
120483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        } else {
120583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append("unexpected type for ");
120683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append(buffer);
120783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        }
120883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    } else {
120983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append("couldn't open ");
121083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append(buffer);
121183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    }
121283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    return result;
121383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen}
121483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
121520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
121620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1217