Utils.cpp revision 2954bca7bdec618da2b94a7e8ac62595b56598a3
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
1709806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (!strncasecmp("video/", mime, 6)) {
1719806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t width, height;
172f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyWidth, &width)
173f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeyHeight, &height)) {
174f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
175f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
1769806555d3930be43e11106281dee354820ac1c88Andreas Huber
1779806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("width", width);
1789806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("height", height);
179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
180516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
181516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (meta->findInt32(kKeySARWidth, &sarWidth)
182516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && meta->findInt32(kKeySARHeight, &sarHeight)) {
183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-width", sarWidth);
184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            msg->setInt32("sar-height", sarHeight);
185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
186475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
187475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
188475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
189475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("color-format", colorFormat);
190475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
191475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
192475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
193475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findRect(kKeyCropRect,
194475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropLeft,
195475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropTop,
196475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropRight,
197475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                           &cropBottom)) {
198475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
199475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
200475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
201475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
202475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
203475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            msg->setInt32("rotation-degrees", rotationDegrees);
204475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
205caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
206caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance");
207caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance");
208caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMetaDataToMessageColorAspects(meta, msg);
2099806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (!strncasecmp("audio/", mime, 6)) {
2109806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t numChannels, sampleRate;
211f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (!meta->findInt32(kKeyChannelCount, &numChannels)
212f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih                || !meta->findInt32(kKeySampleRate, &sampleRate)) {
213f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
214f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
2159806555d3930be43e11106281dee354820ac1c88Andreas Huber
2169806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("channel-count", numChannels);
2179806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("sample-rate", sampleRate);
2189806555d3930be43e11106281dee354820ac1c88Andreas Huber
2199806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t channelMask;
2209806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
2219806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("channel-mask", channelMask);
2229806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2239806555d3930be43e11106281dee354820ac1c88Andreas Huber
2249806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t delay = 0;
2259806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
2269806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-delay", delay);
2279806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2289806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t padding = 0;
2299806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
2309806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("encoder-padding", padding);
2319806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
2329806555d3930be43e11106281dee354820ac1c88Andreas Huber
2339806555d3930be43e11106281dee354820ac1c88Andreas Huber        int32_t isADTS;
2349806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
2352954bca7bdec618da2b94a7e8ac62595b56598a3Pawin Vongmasa            msg->setInt32("is-adts", isADTS);
2369806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
237ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad
238ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        int32_t aacProfile = -1;
239ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
240ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad            msg->setInt32("aac-profile", aacProfile);
241ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad        }
24278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
24378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
24478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
24578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            msg->setInt32("pcm-encoding", pcmEncoding);
24678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
2479806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2489806555d3930be43e11106281dee354820ac1c88Andreas Huber
2499806555d3930be43e11106281dee354820ac1c88Andreas Huber    int32_t maxInputSize;
2509806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
2519806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("max-input-size", maxInputSize);
2529806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2539806555d3930be43e11106281dee354820ac1c88Andreas Huber
254a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
255a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
256a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-width", maxWidth);
257a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
258a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
259a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
260a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
261a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-height", maxHeight);
262a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
263a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
264e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    int32_t rotationDegrees;
265e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
266e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        msg->setInt32("rotation-degrees", rotationDegrees);
267e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
268e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
2698f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
2702a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
2718f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        msg->setInt32("frame-rate", fps);
2728f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
2738f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
2749806555d3930be43e11106281dee354820ac1c88Andreas Huber    uint32_t type;
2759806555d3930be43e11106281dee354820ac1c88Andreas Huber    const void *data;
2769806555d3930be43e11106281dee354820ac1c88Andreas Huber    size_t size;
2779806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
2789806555d3930be43e11106281dee354820ac1c88Andreas Huber        // Parse the AVCDecoderConfigurationRecord
2799806555d3930be43e11106281dee354820ac1c88Andreas Huber
2809806555d3930be43e11106281dee354820ac1c88Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
2819806555d3930be43e11106281dee354820ac1c88Andreas Huber
2827bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
2837bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
2847bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
2857bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
286b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1];
287b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[3];
2889806555d3930be43e11106281dee354820ac1c88Andreas Huber
2899806555d3930be43e11106281dee354820ac1c88Andreas Huber        // There is decodable content out there that fails the following
2909806555d3930be43e11106281dee354820ac1c88Andreas Huber        // assertion, let's be lenient for now...
2919806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
2929806555d3930be43e11106281dee354820ac1c88Andreas Huber
293b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t lengthSize __unused = 1 + (ptr[4] & 3);
2949806555d3930be43e11106281dee354820ac1c88Andreas Huber
2959806555d3930be43e11106281dee354820ac1c88Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
2969806555d3930be43e11106281dee354820ac1c88Andreas Huber        // violates it...
2979806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
2989806555d3930be43e11106281dee354820ac1c88Andreas Huber
2999806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
3009806555d3930be43e11106281dee354820ac1c88Andreas Huber
3019806555d3930be43e11106281dee354820ac1c88Andreas Huber        ptr += 6;
3029806555d3930be43e11106281dee354820ac1c88Andreas Huber        size -= 6;
3039806555d3930be43e11106281dee354820ac1c88Andreas Huber
3049c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
3059c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3069c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3079c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3089806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3099806555d3930be43e11106281dee354820ac1c88Andreas Huber
3109806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
3117bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3127bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3137bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3147bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3159806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3169806555d3930be43e11106281dee354820ac1c88Andreas Huber
3179806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3189806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3199806555d3930be43e11106281dee354820ac1c88Andreas Huber
3209c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3219c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3229c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3239c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3259c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3269c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3279806555d3930be43e11106281dee354820ac1c88Andreas Huber
3289806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3299806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3309806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3319806555d3930be43e11106281dee354820ac1c88Andreas Huber
3329806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3339806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3349806555d3930be43e11106281dee354820ac1c88Andreas Huber
3359806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
3369806555d3930be43e11106281dee354820ac1c88Andreas Huber
3379c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(1024);
3389c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3399c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3409c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3419806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber
3437bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 1) {
3447bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3457bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3467bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
3479806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numPictureParameterSets = *ptr;
3489806555d3930be43e11106281dee354820ac1c88Andreas Huber        ++ptr;
3499806555d3930be43e11106281dee354820ac1c88Andreas Huber        --size;
3509806555d3930be43e11106281dee354820ac1c88Andreas Huber
3519806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
3527bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3537bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3547bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3557bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3569806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3579806555d3930be43e11106281dee354820ac1c88Andreas Huber
3589806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3599806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3609806555d3930be43e11106281dee354820ac1c88Andreas Huber
3619c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3629c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3639c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3649c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3659c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3669c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3679c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3719806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3729806555d3930be43e11106281dee354820ac1c88Andreas Huber
3739806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3749806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3759806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
3763b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
3773b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
3783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3797bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
3807bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3817bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3827bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
383b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1] & 31;
384b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[12];
3853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 22;
3863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 22;
3873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t numofArrays = (char)ptr[0];
3903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 1;
3913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 1;
3923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t j = 0, i = 0;
3933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3949c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
3959c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3979c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->setRange(0, 0);
3993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        for (i = 0; i < numofArrays; i++) {
4017bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 3) {
4027bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
4037bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
4047bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
4053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 1;
4063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 1;
4073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            //Num of nals
4093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size_t numofNals = U16_AT(ptr);
4103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 2;
4123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 2;
4133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            for (j = 0; j < numofNals; j++) {
4157bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                if (size < 2) {
4167bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    ALOGE("b/23680780");
4177bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    return BAD_VALUE;
4187bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                }
4193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size_t length = U16_AT(ptr);
4203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += 2;
4223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= 2;
4233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (size < length) {
4259c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return BAD_VALUE;
4269c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4279c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                status_t err = copyNALUToABuffer(&buffer, ptr, length);
4289c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (err != OK) {
4299c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return err;
4309c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += length;
4333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= length;
4343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
4353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
4363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt32("csd", true);
4373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt64("timeUs", 0);
4383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        msg->setBuffer("csd-0", buffer);
4393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4409806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
4419806555d3930be43e11106281dee354820ac1c88Andreas Huber        ESDS esds((const char *)data, size);
442f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (esds.InitCheck() != (status_t)OK) {
443f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
444f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
4459806555d3930be43e11106281dee354820ac1c88Andreas Huber
4469806555d3930be43e11106281dee354820ac1c88Andreas Huber        const void *codec_specific_data;
4479806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t codec_specific_data_size;
4489806555d3930be43e11106281dee354820ac1c88Andreas Huber        esds.getCodecSpecificInfo(
4499806555d3930be43e11106281dee354820ac1c88Andreas Huber                &codec_specific_data, &codec_specific_data_size);
4509806555d3930be43e11106281dee354820ac1c88Andreas Huber
4519c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
4529c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4539c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4549c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4559806555d3930be43e11106281dee354820ac1c88Andreas Huber
4569806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), codec_specific_data,
4579806555d3930be43e11106281dee354820ac1c88Andreas Huber               codec_specific_data_size);
4589806555d3930be43e11106281dee354820ac1c88Andreas Huber
4599806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4609806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4619806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4629806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
4639c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4649c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4659c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4669c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4679806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4689806555d3930be43e11106281dee354820ac1c88Andreas Huber
4699806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4709806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4719806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4729806555d3930be43e11106281dee354820ac1c88Andreas Huber
4739806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
4749806555d3930be43e11106281dee354820ac1c88Andreas Huber            return -EINVAL;
4759806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
4769806555d3930be43e11106281dee354820ac1c88Andreas Huber
4779c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
4789c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4809c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4819806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4829806555d3930be43e11106281dee354820ac1c88Andreas Huber
4839806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4849806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4859806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
486bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
4879c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4889c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4899c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
491bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
492bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian
493bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
494bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
495bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
4969b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
4979b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
4989b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
4999b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
5009b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
5029c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
5039c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
5049c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5059b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5069b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5079b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5089b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5099b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-1", buffer);
5109b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5119b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
5129b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
5139b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
5149b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5159c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
5169c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
5179c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
5189c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5199b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5209b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5219b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5229b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5239b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-2", buffer);
5249806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
5259806555d3930be43e11106281dee354820ac1c88Andreas Huber
526793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // TODO expose "crypto-key"/kKeyCryptoKey through public api
527793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
528793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
529793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        msg->setBuffer("crypto-key", buffer);
530793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(buffer->data(), data, size);
531793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
532793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
5339806555d3930be43e11106281dee354820ac1c88Andreas Huber    *format = msg;
5349806555d3930be43e11106281dee354820ac1c88Andreas Huber
5359806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
5369806555d3930be43e11106281dee354820ac1c88Andreas Huber}
5379806555d3930be43e11106281dee354820ac1c88Andreas Huber
53856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
53956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
54056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[0] = 1;        // version
54156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[1] = 0x64;     // profile
54256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[2] = 0;        // unused (?)
54356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[3] = 0xd;      // level
54456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[4] = 0xff;     // reserved+size
54556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
54656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    size_t i = 0;
54756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numparams = 0;
54856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int lastparamoffset = 0;
54956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int avccidx = 6;
55056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
55156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd0->size() - 4 ||
55256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd0->size() - 4) {
55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd0->size();
55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
557a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
56356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd0->size());
57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGV("csd0 contains %d params", numparams);
57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
57456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[5] = 0xe0 | numparams;
57556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    //and now csd-1
57656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    i = 0;
57756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    numparams = 0;
57856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    lastparamoffset = 0;
57956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numpicparamsoffset = avccidx;
58056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avccidx++;
58156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
58256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd1->size() - 4 ||
58356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
58456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd1->size() - 4) {
58556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
58656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd1->size();
58756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
588a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
58956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
59056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
59156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
59256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
59356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
59456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
59656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
59756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
59856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
59956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
60056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
60156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
60256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd1->size());
60356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[numpicparamsoffset] = numparams;
60456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    return avccidx;
60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
60656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
60756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
60856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int csd0size = csd0->size();
60956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[0] = 3; // kTag_ESDescriptor;
61056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int esdescriptorsize = 26 + csd0size;
61156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
61256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[1] = 0x80 | (esdescriptorsize >> 21);
61356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
61456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
61556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[4] = (esdescriptorsize & 0x7f);
61656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[5] = esds[6] = 0; // es id
61756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[7] = 0; // flags
61856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[8] = 4; // kTag_DecoderConfigDescriptor
61956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int configdescriptorsize = 18 + csd0size;
62056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[9] = 0x80 | (configdescriptorsize >> 21);
62156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
62256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
62356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[12] = (configdescriptorsize & 0x7f);
62456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[13] = 0x40; // objectTypeIndication
62556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
62656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[15] = 0x00; // but the actual values here were taken from a real file.
62756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[16] = 0x18;
62856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[17] = 0x00;
62956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[18] = 0x00;
63056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[19] = 0x00;
63156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[20] = 0xfa;
63256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[21] = 0x00;
63356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[22] = 0x00;
63456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[23] = 0x00;
63556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[24] = 0xfa;
63656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[25] = 0x00;
63756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[26] = 5; // kTag_DecoderSpecificInfo;
63856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[27] = 0x80 | (csd0size >> 21);
63956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
64056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
64156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[30] = (csd0size & 0x7f);
64256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    memcpy((void*)&esds[31], csd0->data(), csd0size);
64356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // data following this is ignored, so don't bother appending it
64456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
64556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
64656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
6479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
6489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    HevcParameterSets paramSets;
6499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    uint8_t* data = csd0->data();
6509aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (csd0->size() < 4) {
6519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 too small");
6529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
6559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 doesn't start with a start code");
6569aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t prevNalOffset = 4;
6599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    status_t err = OK;
6609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    for (size_t i = 1; i < csd0->size() - 4; ++i) {
6619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
6629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            continue;
6639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
6659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (err != OK) {
6669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            return 0;
6679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        prevNalOffset = i + 4;
6699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
6719aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6729aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6739aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t size = hvccSize;
6759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
6769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    return size;
6809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}
6819aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim
682caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataInt32(
683caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
684caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
685caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (msg->findInt32(name, &value)) {
686caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(key, value);
687caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
688caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
689caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
690caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
691caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
692caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0, standard = 0, transfer = 0;
693caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-range", &range);
694caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-standard", &standard);
695caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-transfer", &transfer);
696caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
697caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
698caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
699caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
700caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            range, standard, transfer, colorAspects) != OK) {
701caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
702caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
703caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
704caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to meta
705caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mRange != 0) {
706caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorRange, colorAspects.mRange);
707caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
708caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mPrimaries != 0) {
709caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
710caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
711caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mTransfer != 0) {
712caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
713caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
714caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mMatrixCoeffs != 0) {
715caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
716caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
717caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
718caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
71956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
72056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    AString mime;
72156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findString("mime", &mime)) {
72256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setCString(kKeyMIMEType, mime.c_str());
72356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else {
72456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        ALOGW("did not find mime type");
72556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
72656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
72756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int64_t durationUs;
72856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt64("durationUs", &durationUs)) {
72956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt64(kKeyDuration, durationUs);
73056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
73156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
7328c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
7338c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
7348c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        meta->setInt32(kKeyIsSyncFrame, 1);
7358c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
7368c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
73756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (mime.startsWith("video/")) {
73856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t width;
73956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t height;
74056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
74156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyWidth, width);
74256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyHeight, height);
74356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
74456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            ALOGW("did not find width and/or height");
74556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
746516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
747516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
748516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (msg->findInt32("sar-width", &sarWidth)
749516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && msg->findInt32("sar-height", &sarHeight)) {
750516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARWidth, sarWidth);
751516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARHeight, sarHeight);
752516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
753475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
754475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
755475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("color-format", &colorFormat)) {
756475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyColorFormat, colorFormat);
757475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
758475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
759475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
760475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findRect("crop",
761475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropLeft,
762475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropTop,
763475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropRight,
764475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropBottom)) {
765475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
766475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
767475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
768475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
769475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
770475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyRotation, rotationDegrees);
771475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
772caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
773caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
774caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
775caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataColorAspects(msg, meta);
77656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else if (mime.startsWith("audio/")) {
77756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t numChannels;
77856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-count", &numChannels)) {
77956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelCount, numChannels);
78056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t sampleRate;
78256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("sample-rate", &sampleRate)) {
78356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeySampleRate, sampleRate);
78456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t channelMask;
78656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-mask", &channelMask)) {
78756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelMask, channelMask);
78856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t delay = 0;
79056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-delay", &delay)) {
79156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderDelay, delay);
79256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t padding = 0;
79456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-padding", &padding)) {
79556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderPadding, padding);
79656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
79856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t isADTS;
79956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("is-adts", &isADTS)) {
80056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyIsADTS, isADTS);
80156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
80278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar
80378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        int32_t pcmEncoding;
80478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
80578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            meta->setInt32(kKeyPcmEncoding, pcmEncoding);
80678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
80756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
80856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
80956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int32_t maxInputSize;
81056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt32("max-input-size", &maxInputSize)) {
81156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt32(kKeyMaxInputSize, maxInputSize);
81256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
81356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
814a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
815a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-width", &maxWidth)) {
816a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxWidth, maxWidth);
817a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
818a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
819a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
820a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-height", &maxHeight)) {
821a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxHeight, maxHeight);
822a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
823a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
8248f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
8252a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
8268f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        meta->setInt32(kKeyFrameRate, fps);
8278f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
8288f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
82956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // reassemble the csd data into its original form
83056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    sp<ABuffer> csd0;
83156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findBuffer("csd-0", &csd0)) {
83277f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
83356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            sp<ABuffer> csd1;
83456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (msg->findBuffer("csd-1", &csd1)) {
83556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                char avcc[1024]; // that oughta be enough, right?
83656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
83756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
83856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
83977f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
84056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            int csd0size = csd0->size();
84156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            char esds[csd0size + 31];
84277f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // The written ESDS is actually for an audio stream, but it's enough
84377f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // for transporting the CSD to muxers.
84456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            reassembleESDS(csd0, esds);
84556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
8469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
8479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            uint8_t hvcc[1024]; // that oughta be enough, right?
8489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
8499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
85056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
85156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
85256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
8532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    int32_t timeScale;
8542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (msg->findInt32("time-scale", &timeScale)) {
8552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        meta->setInt32(kKeyTimeScale, timeScale);
8562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
8572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
85856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // XXX TODO add whatever other keys there are
85956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
86056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0
86156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGI("converted %s to:", msg->debugString(0).c_str());
86256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    meta->dumpToLog();
86356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif
86456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
86556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
866cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() {
867cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    AString ua;
868cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
869cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
870cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8)
871cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
872cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif
873cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
874cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    char value[PROPERTY_VALUE_MAX];
875cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    property_get("ro.build.version.release", value, "Unknown");
876cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(value);
877cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(")");
878cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
879cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    return ua;
880cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber}
88156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
882ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
883ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                           const sp<MetaData>& meta)
884ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
88594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t sampleRate = 0;
88694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t bitRate = 0;
88794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t channelMask = 0;
88894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t delaySamples = 0;
88994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t paddingSamples = 0;
89094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
89194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    AudioParameter param = AudioParameter();
89294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
89394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
89494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
89594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
89694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
89794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
89894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
89994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyBitRate, &bitRate)) {
90094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
90194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
90294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
90394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
90494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
90594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
90694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
90794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
90894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
90994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
91094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          "delaySample %d, paddingSample %d", bitRate, sampleRate,
91194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          channelMask, delaySamples, paddingSamples);
91294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
91394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    sink->setParameters(param.toString());
914ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return OK;
915ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
916ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
91794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t {
91894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char* mime;
91994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t format;
92094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
92194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
92294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = {
92394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
92494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
92594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
92694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
92794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
92894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
929bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
93094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { 0, AUDIO_FORMAT_INVALID }
93194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
93294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
93394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
934ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
93594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0];
93694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    while (p->mime != NULL) {
93794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (0 == strcasecmp(mime, p->mime)) {
93894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            format = p->format;
93994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return OK;
94094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
94194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ++p;
94294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
94394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
944ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return BAD_VALUE;
945ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
946ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
9472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t {
9482829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
9492829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    audio_format_t format;
9502829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9512829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9522829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = {
9532829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
9542829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
9552829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
9562829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
9572829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
9582829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
9592829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
9602829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
9612829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
9622829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
9632829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
9642829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9652829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9662829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
9672829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{
9682829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0];
9692829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
9702829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if (eAacProfile == p->eAacProfileType) {
9712829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            format = p->format;
9722829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            return;
9732829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
9742829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        ++p;
9752829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    }
9762829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    format = AUDIO_FORMAT_AAC;
9772829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    return;
9782829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}
9792829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
98022612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
98122612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent                      bool isStreaming, audio_stream_type_t streamType)
982ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
98394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char *mime;
984cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    if (meta == NULL) {
985cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia        return false;
986cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    }
98794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(meta->findCString(kKeyMIMEType, &mime));
98894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
98994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
99094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
99194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.format = AUDIO_FORMAT_INVALID;
99294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mapMimeToAudioFormat(info.format, mime) != OK) {
99394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
99494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
99594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
99694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
99794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
99894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
99994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (AUDIO_FORMAT_INVALID == info.format) {
100094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // can't offload if we don't know what the source format is
100194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE("mime type \"%s\" not a known audio format", mime);
100294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
100394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
100494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
10052829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Redefine aac format according to its profile
10062829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Offloading depends on audio DSP capabilities.
1007db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    int32_t aacaot = -1;
1008db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
10092829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1010db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    }
1011db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
101294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t srate = -1;
101394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeySampleRate, &srate)) {
101494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish sample rate", mime);
101594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
101694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.sample_rate = srate;
101794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
101894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t cmask = 0;
101994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
102094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish channel mask", mime);
102194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
102294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // Try a channel count instead
102394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        int32_t channelCount;
102494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
102594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("track of type '%s' does not publish channel count", mime);
102694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
102794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            cmask = audio_channel_out_mask_from_count(channelCount);
102894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
102994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
103094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.channel_mask = cmask;
103194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int64_t duration = 0;
103394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt64(kKeyDuration, &duration)) {
103494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish duration", mime);
103594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
103694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.duration_us = duration;
103794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t brate = -1;
103994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyBitRate, &brate)) {
104094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish bitrate", mime);
104194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald     }
104294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.bit_rate = brate;
104394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
104494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
104522612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent    info.stream_type = streamType;
104694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.has_video = hasVideo;
104794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.is_streaming = isStreaming;
104894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
104994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // Check if offload is possible for given format, stream type, sample rate,
105094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // bit rate, duration, video and streaming
105194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return AudioSystem::isOffloadSupported(info);
1052ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1053ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
1054a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) {
1055a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (incognito) {
1056a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return AString("<URI suppressed>");
1057a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1058a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1059a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    char prop[PROPERTY_VALUE_MAX];
1060a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (property_get("media.stagefright.log-uri", prop, "false") &&
1061a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
1062a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return uri;
1063a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1064a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1065a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    // find scheme
1066a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    AString scheme;
1067a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    const char *chars = uri.c_str();
1068a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    for (size_t i = 0; i < uri.size(); i++) {
1069a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        const char c = chars[i];
1070a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        if (!isascii(c)) {
1071a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1072a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isalpha(c)) {
1073a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1074a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (i == 0) {
1075a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            // first character must be a letter
1076a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1077a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
1078a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1079a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (c != ':') {
1080a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1081a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        }
1082a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme = AString(uri, 0, i);
1083a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme.append("://<suppressed>");
1084a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return scheme;
1085a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1086a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    return AString("<no-scheme URI suppressed>");
1087a1df816c0677185534babba6ffc29970b048e52eLajos Molnar}
1088a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1089d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) :
1090d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mSeq(-1),
1091d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mTimeUs(-1ll),
1092d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mMeta(meta) {
1093d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (meta != NULL) {
1094d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
1095d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt64("timeUs", &mTimeUs));
1096d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1097d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1098d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1099978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const {
1100d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t segmentStartTimeUs = -1ll;
1101d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (mMeta != NULL) {
1102d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
1103978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1104978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t segmentFirstTimeUs;
1105978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
1106978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
1107978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        }
1108978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1109978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        // adjust segment time by playlist age (for live streaming)
1110978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t playlistTimeUs;
1111978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
1112978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
1113978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1114d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t durationUs;
1115d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
1116978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1117978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            // round to nearest whole segment
1118978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            playlistAgeUs = (playlistAgeUs + durationUs / 2)
1119978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                    / durationUs * durationUs;
1120978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1121978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs -= playlistAgeUs;
1122978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            if (segmentStartTimeUs < 0) {
1123978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                segmentStartTimeUs = 0;
1124978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            }
1125d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1126d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1127d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return segmentStartTimeUs;
1128d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1129d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1130d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) {
1131d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // we can only compare discontinuity sequence and timestamp.
1132d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // (mSegmentTimeUs is not reliable in live streaming case, it's the
1133d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // time starting from beginning of playlist but playlist could change.)
1134d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return t0.mSeq < t1.mSeq
1135d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
1136d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1137d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
11383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
11393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("speed", rate.mSpeed);
11403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("pitch", rate.mPitch);
11413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
11423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
11433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
11463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
11473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("speed", &rate->mSpeed));
11483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("pitch", &rate->mPitch));
11493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
11503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
11513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
11543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("sync-source", sync.mSource);
11553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
11563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("tolerance", sync.mTolerance);
11573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("video-fps", videoFpsHint);
11583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(
11613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        const sp<AMessage> &msg,
11623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings *sync /* nonnull */,
11633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        float *videoFps /* nonnull */) {
11643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    AVSyncSettings settings;
11653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
11663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
11673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
11683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("video-fps", videoFps));
11693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *sync = settings;
11703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
117283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) {
117383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    const size_t SIZE = 256;
117483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    char buffer[SIZE];
117583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    AString result;
117683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
117783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    struct stat s;
117883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    if (lstat(buffer, &s) == 0) {
117983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        if ((s.st_mode & S_IFMT) == S_IFLNK) {
118083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            char linkto[256];
118183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            int len = readlink(buffer, linkto, sizeof(linkto));
118283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            if(len > 0) {
118383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                if(len > 255) {
118483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[252] = '.';
118583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[253] = '.';
118683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[254] = '.';
118783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[255] = 0;
118883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                } else {
118983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[len] = 0;
119083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                }
119183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                result.append(linkto);
119283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            }
119383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        } else {
119483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append("unexpected type for ");
119583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append(buffer);
119683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        }
119783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    } else {
119883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append("couldn't open ");
119983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append(buffer);
120083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    }
120183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    return result;
120283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen}
120383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
120420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
120520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1206