Utils.cpp revision caaa15b1c8ca1632100cf8e64e82007239210339
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)) {
2359806555d3930be43e11106281dee354820ac1c88Andreas Huber            msg->setInt32("is-adts", true);
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        }
2429806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2439806555d3930be43e11106281dee354820ac1c88Andreas Huber
2449806555d3930be43e11106281dee354820ac1c88Andreas Huber    int32_t maxInputSize;
2459806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
2469806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setInt32("max-input-size", maxInputSize);
2479806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
2489806555d3930be43e11106281dee354820ac1c88Andreas Huber
249a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
250a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
251a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-width", maxWidth);
252a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
253a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
254a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
255a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
256a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        msg->setInt32("max-height", maxHeight);
257a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
258a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
259e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    int32_t rotationDegrees;
260e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
261e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        msg->setInt32("rotation-degrees", rotationDegrees);
262e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang    }
263e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
2648f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
2652a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
2668f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        msg->setInt32("frame-rate", fps);
2678f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
2688f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
2699806555d3930be43e11106281dee354820ac1c88Andreas Huber    uint32_t type;
2709806555d3930be43e11106281dee354820ac1c88Andreas Huber    const void *data;
2719806555d3930be43e11106281dee354820ac1c88Andreas Huber    size_t size;
2729806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
2739806555d3930be43e11106281dee354820ac1c88Andreas Huber        // Parse the AVCDecoderConfigurationRecord
2749806555d3930be43e11106281dee354820ac1c88Andreas Huber
2759806555d3930be43e11106281dee354820ac1c88Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
2769806555d3930be43e11106281dee354820ac1c88Andreas Huber
2777bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
2787bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
2797bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
2807bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
281b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1];
282b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[3];
2839806555d3930be43e11106281dee354820ac1c88Andreas Huber
2849806555d3930be43e11106281dee354820ac1c88Andreas Huber        // There is decodable content out there that fails the following
2859806555d3930be43e11106281dee354820ac1c88Andreas Huber        // assertion, let's be lenient for now...
2869806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
2879806555d3930be43e11106281dee354820ac1c88Andreas Huber
288b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        size_t lengthSize __unused = 1 + (ptr[4] & 3);
2899806555d3930be43e11106281dee354820ac1c88Andreas Huber
2909806555d3930be43e11106281dee354820ac1c88Andreas Huber        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
2919806555d3930be43e11106281dee354820ac1c88Andreas Huber        // violates it...
2929806555d3930be43e11106281dee354820ac1c88Andreas Huber        // CHECK((ptr[5] >> 5) == 7);  // reserved
2939806555d3930be43e11106281dee354820ac1c88Andreas Huber
2949806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numSeqParameterSets = ptr[5] & 31;
2959806555d3930be43e11106281dee354820ac1c88Andreas Huber
2969806555d3930be43e11106281dee354820ac1c88Andreas Huber        ptr += 6;
2979806555d3930be43e11106281dee354820ac1c88Andreas Huber        size -= 6;
2989806555d3930be43e11106281dee354820ac1c88Andreas Huber
2999c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
3009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3019c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3029c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3039806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3049806555d3930be43e11106281dee354820ac1c88Andreas Huber
3059806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numSeqParameterSets; ++i) {
3067bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3077bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3087bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3097bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3109806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3119806555d3930be43e11106281dee354820ac1c88Andreas Huber
3129806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3139806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3149806555d3930be43e11106281dee354820ac1c88Andreas Huber
3159c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3169c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3179c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3189c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3199c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3209c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3219c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3229806555d3930be43e11106281dee354820ac1c88Andreas Huber
3239806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3249806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3259806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3269806555d3930be43e11106281dee354820ac1c88Andreas Huber
3279806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3289806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3299806555d3930be43e11106281dee354820ac1c88Andreas Huber
3309806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
3319806555d3930be43e11106281dee354820ac1c88Andreas Huber
3329c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(1024);
3339c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3349c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3359c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3369806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->setRange(0, 0);
3379806555d3930be43e11106281dee354820ac1c88Andreas Huber
3387bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 1) {
3397bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3407bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3417bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t numPictureParameterSets = *ptr;
3439806555d3930be43e11106281dee354820ac1c88Andreas Huber        ++ptr;
3449806555d3930be43e11106281dee354820ac1c88Andreas Huber        --size;
3459806555d3930be43e11106281dee354820ac1c88Andreas Huber
3469806555d3930be43e11106281dee354820ac1c88Andreas Huber        for (size_t i = 0; i < numPictureParameterSets; ++i) {
3477bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 2) {
3487bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3497bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3507bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
3519806555d3930be43e11106281dee354820ac1c88Andreas Huber            size_t length = U16_AT(ptr);
3529806555d3930be43e11106281dee354820ac1c88Andreas Huber
3539806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += 2;
3549806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= 2;
3559806555d3930be43e11106281dee354820ac1c88Andreas Huber
3569c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (size < length) {
3579c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return BAD_VALUE;
3589c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3599c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            status_t err = copyNALUToABuffer(&buffer, ptr, length);
3609c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            if (err != OK) {
3619c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                return err;
3629c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            }
3639806555d3930be43e11106281dee354820ac1c88Andreas Huber
3649806555d3930be43e11106281dee354820ac1c88Andreas Huber            ptr += length;
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber            size -= length;
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
3713b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
3723b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        const uint8_t *ptr = (const uint8_t *)data;
3733b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3747bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
3757bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            ALOGE("b/23680780");
3767bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            return BAD_VALUE;
3777bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia        }
378b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t profile __unused = ptr[1] & 31;
379b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe        uint8_t level __unused = ptr[12];
3803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 22;
3813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 22;
3823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t numofArrays = (char)ptr[0];
3853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        ptr += 1;
3863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size -= 1;
3873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        size_t j = 0, i = 0;
3883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3899c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
3909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
3919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
3929c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
3933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->setRange(0, 0);
3943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
3953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        for (i = 0; i < numofArrays; i++) {
3967bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            if (size < 3) {
3977bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                ALOGE("b/23680780");
3987bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                return BAD_VALUE;
3997bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia            }
4003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 1;
4013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 1;
4023b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4033b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            //Num of nals
4043b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size_t numofNals = U16_AT(ptr);
4053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            ptr += 2;
4073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            size -= 2;
4083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            for (j = 0; j < numofNals; j++) {
4107bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                if (size < 2) {
4117bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    ALOGE("b/23680780");
4127bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                    return BAD_VALUE;
4137bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia                }
4143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size_t length = U16_AT(ptr);
4153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += 2;
4173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= 2;
4183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4199c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (size < length) {
4209c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return BAD_VALUE;
4219c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4229c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                status_t err = copyNALUToABuffer(&buffer, ptr, length);
4239c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                if (err != OK) {
4249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                    return err;
4259c170c076382096b9e767da0e3f9f37dafa76546Wei Jia                }
4263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                ptr += length;
4283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar                size -= length;
4293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar            }
4303b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        }
4313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt32("csd", true);
4323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        buffer->meta()->setInt64("timeUs", 0);
4333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar        msg->setBuffer("csd-0", buffer);
4343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar
4359806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
4369806555d3930be43e11106281dee354820ac1c88Andreas Huber        ESDS esds((const char *)data, size);
437f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        if (esds.InitCheck() != (status_t)OK) {
438f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih            return BAD_VALUE;
439f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih        }
4409806555d3930be43e11106281dee354820ac1c88Andreas Huber
4419806555d3930be43e11106281dee354820ac1c88Andreas Huber        const void *codec_specific_data;
4429806555d3930be43e11106281dee354820ac1c88Andreas Huber        size_t codec_specific_data_size;
4439806555d3930be43e11106281dee354820ac1c88Andreas Huber        esds.getCodecSpecificInfo(
4449806555d3930be43e11106281dee354820ac1c88Andreas Huber                &codec_specific_data, &codec_specific_data_size);
4459806555d3930be43e11106281dee354820ac1c88Andreas Huber
4469c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
4479c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4489c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4499c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4509806555d3930be43e11106281dee354820ac1c88Andreas Huber
4519806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), codec_specific_data,
4529806555d3930be43e11106281dee354820ac1c88Andreas Huber               codec_specific_data_size);
4539806555d3930be43e11106281dee354820ac1c88Andreas Huber
4549806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4559806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4569806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4579806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
4589c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4599c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4609c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4619c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4629806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4639806555d3930be43e11106281dee354820ac1c88Andreas Huber
4649806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4659806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4669806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-0", buffer);
4679806555d3930be43e11106281dee354820ac1c88Andreas Huber
4689806555d3930be43e11106281dee354820ac1c88Andreas Huber        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
4699806555d3930be43e11106281dee354820ac1c88Andreas Huber            return -EINVAL;
4709806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
4719806555d3930be43e11106281dee354820ac1c88Andreas Huber
4729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
4739c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4749c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4759c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
4769806555d3930be43e11106281dee354820ac1c88Andreas Huber        memcpy(buffer->data(), data, size);
4779806555d3930be43e11106281dee354820ac1c88Andreas Huber
4789806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt32("csd", true);
4799806555d3930be43e11106281dee354820ac1c88Andreas Huber        buffer->meta()->setInt64("timeUs", 0);
4809806555d3930be43e11106281dee354820ac1c88Andreas Huber        msg->setBuffer("csd-1", buffer);
481bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
4829c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
4839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
486bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
487bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian
488bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
489bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
490bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        msg->setBuffer("csd-0", buffer);
4919b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
4929b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
4939b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
4949b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
4959b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
4969c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
4979c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
4989c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
4999c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5009b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5019b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5029b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5039b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5049b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-1", buffer);
5059b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5069b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
5079b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian            return -EINVAL;
5089b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        }
5099b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5109c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        buffer = new (std::nothrow) ABuffer(size);
5119c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        if (buffer.get() == NULL || buffer->base() == NULL) {
5129c170c076382096b9e767da0e3f9f37dafa76546Wei Jia            return NO_MEMORY;
5139c170c076382096b9e767da0e3f9f37dafa76546Wei Jia        }
5149b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        memcpy(buffer->data(), data, size);
5159b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian
5169b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt32("csd", true);
5179b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        buffer->meta()->setInt64("timeUs", 0);
5189b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian        msg->setBuffer("csd-2", buffer);
5199806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
5209806555d3930be43e11106281dee354820ac1c88Andreas Huber
521793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    // TODO expose "crypto-key"/kKeyCryptoKey through public api
522793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
523793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
524793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        msg->setBuffer("crypto-key", buffer);
525793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih        memcpy(buffer->data(), data, size);
526793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih    }
527793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih
5289806555d3930be43e11106281dee354820ac1c88Andreas Huber    *format = msg;
5299806555d3930be43e11106281dee354820ac1c88Andreas Huber
5309806555d3930be43e11106281dee354820ac1c88Andreas Huber    return OK;
5319806555d3930be43e11106281dee354820ac1c88Andreas Huber}
5329806555d3930be43e11106281dee354820ac1c88Andreas Huber
53356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
53456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
53556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[0] = 1;        // version
53656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[1] = 0x64;     // profile
53756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[2] = 0;        // unused (?)
53856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[3] = 0xd;      // level
53956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[4] = 0xff;     // reserved+size
54056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
54156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    size_t i = 0;
54256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numparams = 0;
54356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int lastparamoffset = 0;
54456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int avccidx = 6;
54556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
54656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd0->size() - 4 ||
54756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) {
54856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd0->size() - 4) {
54956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
55056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd0->size();
55156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
552a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
55756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size);
55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
56356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd0->size());
56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGV("csd0 contains %d params", numparams);
56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[5] = 0xe0 | numparams;
57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    //and now csd-1
57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    i = 0;
57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    numparams = 0;
57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    lastparamoffset = 0;
57456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int numpicparamsoffset = avccidx;
57556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avccidx++;
57656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    do {
57756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (i >= csd1->size() - 4 ||
57856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) {
57956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (i >= csd1->size() - 4) {
58056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                // there can't be another param here, so use all the rest
58156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                i = csd1->size();
58256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
583a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn            ALOGV("block at %zu, last was %d", i, lastparamoffset);
58456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (lastparamoffset > 0) {
58556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                int size = i - lastparamoffset;
58656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size >> 8;
58756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avcc[avccidx++] = size & 0xff;
58856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
58956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                avccidx += size;
59056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                numparams++;
59156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
59256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i += 4;
59356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            lastparamoffset = i;
59456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            i++;
59656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
59756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } while(i < csd1->size());
59856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    avcc[numpicparamsoffset] = numparams;
59956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    return avccidx;
60056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
60156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
60256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
60356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int csd0size = csd0->size();
60456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[0] = 3; // kTag_ESDescriptor;
60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int esdescriptorsize = 26 + csd0size;
60656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
60756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[1] = 0x80 | (esdescriptorsize >> 21);
60856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
60956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
61056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[4] = (esdescriptorsize & 0x7f);
61156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[5] = esds[6] = 0; // es id
61256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[7] = 0; // flags
61356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[8] = 4; // kTag_DecoderConfigDescriptor
61456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int configdescriptorsize = 18 + csd0size;
61556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[9] = 0x80 | (configdescriptorsize >> 21);
61656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
61756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
61856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[12] = (configdescriptorsize & 0x7f);
61956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[13] = 0x40; // objectTypeIndication
62056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp,
62156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[15] = 0x00; // but the actual values here were taken from a real file.
62256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[16] = 0x18;
62356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[17] = 0x00;
62456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[18] = 0x00;
62556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[19] = 0x00;
62656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[20] = 0xfa;
62756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[21] = 0x00;
62856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[22] = 0x00;
62956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[23] = 0x00;
63056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[24] = 0xfa;
63156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[25] = 0x00;
63256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[26] = 5; // kTag_DecoderSpecificInfo;
63356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[27] = 0x80 | (csd0size >> 21);
63456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
63556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
63656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    esds[30] = (csd0size & 0x7f);
63756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    memcpy((void*)&esds[31], csd0->data(), csd0size);
63856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // data following this is ignored, so don't bother appending it
63956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
64056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
64156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
6429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
6439aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    HevcParameterSets paramSets;
6449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    uint8_t* data = csd0->data();
6459aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (csd0->size() < 4) {
6469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 too small");
6479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
6509aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        ALOGE("csd0 doesn't start with a start code");
6519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t prevNalOffset = 4;
6549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    status_t err = OK;
6559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    for (size_t i = 1; i < csd0->size() - 4; ++i) {
6569aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
6579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            continue;
6589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
6609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        if (err != OK) {
6619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            return 0;
6629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        }
6639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        prevNalOffset = i + 4;
6649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
6669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    size_t size = hvccSize;
6709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
6719aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    if (err != OK) {
6729aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        return 0;
6739aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    }
6749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    return size;
6759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}
6769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim
677caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataInt32(
678caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
679caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t value;
680caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (msg->findInt32(name, &value)) {
681caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(key, value);
682caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
683caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
684caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
685caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wustatic void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
686caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // 0 values are unspecified
687caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    int32_t range = 0, standard = 0, transfer = 0;
688caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-range", &range);
689caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-standard", &standard);
690caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    (void)msg->findInt32("color-transfer", &transfer);
691caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
692caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    ColorAspects colorAspects;
693caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    memset(&colorAspects, 0, sizeof(colorAspects));
694caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
695caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu            range, standard, transfer, colorAspects) != OK) {
696caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        return;
697caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
698caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
699caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    // save specified values to meta
700caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mRange != 0) {
701caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorRange, colorAspects.mRange);
702caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
703caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mPrimaries != 0) {
704caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
705caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
706caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mTransfer != 0) {
707caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
708caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
709caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    if (colorAspects.mMatrixCoeffs != 0) {
710caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
711caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu    }
712caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu}
713caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
71456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
71556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    AString mime;
71656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findString("mime", &mime)) {
71756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setCString(kKeyMIMEType, mime.c_str());
71856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else {
71956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        ALOGW("did not find mime type");
72056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
72156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
72256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int64_t durationUs;
72356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt64("durationUs", &durationUs)) {
72456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt64(kKeyDuration, durationUs);
72556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
72656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
7278c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    int32_t isSync;
7288c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
7298c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen        meta->setInt32(kKeyIsSyncFrame, 1);
7308c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen    }
7318c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen
73256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (mime.startsWith("video/")) {
73356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t width;
73456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t height;
73556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
73656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyWidth, width);
73756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyHeight, height);
73856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        } else {
73956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            ALOGW("did not find width and/or height");
74056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
741516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber
742516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        int32_t sarWidth, sarHeight;
743516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        if (msg->findInt32("sar-width", &sarWidth)
744516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                && msg->findInt32("sar-height", &sarHeight)) {
745516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARWidth, sarWidth);
746516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            meta->setInt32(kKeySARHeight, sarHeight);
747516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber        }
748475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
749475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t colorFormat;
750475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("color-format", &colorFormat)) {
751475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyColorFormat, colorFormat);
752475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
753475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
754475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t cropLeft, cropTop, cropRight, cropBottom;
755475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findRect("crop",
756475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropLeft,
757475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropTop,
758475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropRight,
759475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                          &cropBottom)) {
760475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
761475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
762475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
763475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        int32_t rotationDegrees;
764475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
765475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            meta->setInt32(kKeyRotation, rotationDegrees);
766475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        }
767caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu
768caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
769caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
770caaa15b1c8ca1632100cf8e64e82007239210339Ronghua Wu        convertMessageToMetaDataColorAspects(msg, meta);
77156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    } else if (mime.startsWith("audio/")) {
77256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t numChannels;
77356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-count", &numChannels)) {
77456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelCount, numChannels);
77556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
77656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t sampleRate;
77756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("sample-rate", &sampleRate)) {
77856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeySampleRate, sampleRate);
77956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t channelMask;
78156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("channel-mask", &channelMask)) {
78256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyChannelMask, channelMask);
78356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t delay = 0;
78556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-delay", &delay)) {
78656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderDelay, delay);
78756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
78856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t padding = 0;
78956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("encoder-padding", &padding)) {
79056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyEncoderPadding, padding);
79156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
79356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        int32_t isADTS;
79456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        if (msg->findInt32("is-adts", &isADTS)) {
79556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setInt32(kKeyIsADTS, isADTS);
79656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
79756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
79856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
79956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    int32_t maxInputSize;
80056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findInt32("max-input-size", &maxInputSize)) {
80156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        meta->setInt32(kKeyMaxInputSize, maxInputSize);
80256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
80356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
804a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxWidth;
805a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-width", &maxWidth)) {
806a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxWidth, maxWidth);
807a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
808a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
809a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    int32_t maxHeight;
810a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    if (msg->findInt32("max-height", &maxHeight)) {
811a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang        meta->setInt32(kKeyMaxHeight, maxHeight);
812a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang    }
813a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang
8148f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    int32_t fps;
8152a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
8168f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang        meta->setInt32(kKeyFrameRate, fps);
8178f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang    }
8188f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang
81956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // reassemble the csd data into its original form
82056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    sp<ABuffer> csd0;
82156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    if (msg->findBuffer("csd-0", &csd0)) {
82277f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
82356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            sp<ABuffer> csd1;
82456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            if (msg->findBuffer("csd-1", &csd1)) {
82556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                char avcc[1024]; // that oughta be enough, right?
82656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                size_t outsize = reassembleAVCC(csd0, csd1, avcc);
82756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen                meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
82856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            }
82977f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
83056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            int csd0size = csd0->size();
83156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            char esds[csd0size + 31];
83277f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // The written ESDS is actually for an audio stream, but it's enough
83377f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo            // for transporting the CSD to muxers.
83456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            reassembleESDS(csd0, esds);
83556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen            meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
8369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
8379aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            uint8_t hvcc[1024]; // that oughta be enough, right?
8389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
8399aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim            meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
84056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen        }
84156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    }
84256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
8432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    int32_t timeScale;
8442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (msg->findInt32("time-scale", &timeScale)) {
8452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        meta->setInt32(kKeyTimeScale, timeScale);
8462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
8472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
84856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    // XXX TODO add whatever other keys there are
84956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
85056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0
85156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    ALOGI("converted %s to:", msg->debugString(0).c_str());
85256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen    meta->dumpToLog();
85356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif
85456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen}
85556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
856cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() {
857cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    AString ua;
858cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
859cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
860cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8)
861cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
862cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif
863cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
864cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    char value[PROPERTY_VALUE_MAX];
865cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    property_get("ro.build.version.release", value, "Unknown");
866cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(value);
867cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    ua.append(")");
868cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber
869cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber    return ua;
870cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber}
87156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen
872ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
873ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                           const sp<MetaData>& meta)
874ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
87594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t sampleRate = 0;
87694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t bitRate = 0;
87794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t channelMask = 0;
87894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t delaySamples = 0;
87994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t paddingSamples = 0;
88094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
88194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    AudioParameter param = AudioParameter();
88294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
88394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
88494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
88594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
88694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
88794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
88894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
88994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyBitRate, &bitRate)) {
89094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
89194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
89294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
89394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
89494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
89594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
89694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
89794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
89894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
89994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
90094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          "delaySample %d, paddingSample %d", bitRate, sampleRate,
90194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald          channelMask, delaySamples, paddingSamples);
90294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
90394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    sink->setParameters(param.toString());
904ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return OK;
905ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
906ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
90794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t {
90894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char* mime;
90994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_format_t format;
91094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
91194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
91294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = {
91394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
91494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
91594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
91694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
91794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
91894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
919bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
92094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    { 0, AUDIO_FORMAT_INVALID }
92194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald};
92294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
92394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
924ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
92594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0];
92694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    while (p->mime != NULL) {
92794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (0 == strcasecmp(mime, p->mime)) {
92894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            format = p->format;
92994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            return OK;
93094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
93194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ++p;
93294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
93394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
934ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return BAD_VALUE;
935ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
936ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
9372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t {
9382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
9392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    audio_format_t format;
9402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = {
9432829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
9442829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
9452829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
9462829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
9472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
9482829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
9492829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
9502829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
9512829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
9522829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
9532829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
9542829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad};
9552829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
9562829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
9572829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{
9582829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0];
9592829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
9602829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        if (eAacProfile == p->eAacProfileType) {
9612829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            format = p->format;
9622829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad            return;
9632829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        }
9642829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        ++p;
9652829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    }
9662829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    format = AUDIO_FORMAT_AAC;
9672829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    return;
9682829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}
9692829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad
97022612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
97122612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent                      bool isStreaming, audio_stream_type_t streamType)
972ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
97394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    const char *mime;
974cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    if (meta == NULL) {
975cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia        return false;
976cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia    }
97794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    CHECK(meta->findCString(kKeyMIMEType, &mime));
97894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
97994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
98094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
98194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.format = AUDIO_FORMAT_INVALID;
98294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (mapMimeToAudioFormat(info.format, mime) != OK) {
98394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
98494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
98594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    } else {
98694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
98794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
98894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
98994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (AUDIO_FORMAT_INVALID == info.format) {
99094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // can't offload if we don't know what the source format is
99194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGE("mime type \"%s\" not a known audio format", mime);
99294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        return false;
99394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
99494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
9952829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Redefine aac format according to its profile
9962829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad    // Offloading depends on audio DSP capabilities.
997db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    int32_t aacaot = -1;
998db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
9992829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
1000db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent    }
1001db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent
100294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t srate = -1;
100394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeySampleRate, &srate)) {
100494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish sample rate", mime);
100594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
100694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.sample_rate = srate;
100794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
100894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t cmask = 0;
100994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
101094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish channel mask", mime);
101194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
101294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        // Try a channel count instead
101394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        int32_t channelCount;
101494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
101594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            ALOGV("track of type '%s' does not publish channel count", mime);
101694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        } else {
101794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald            cmask = audio_channel_out_mask_from_count(channelCount);
101894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        }
101994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
102094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.channel_mask = cmask;
102194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
102294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int64_t duration = 0;
102394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt64(kKeyDuration, &duration)) {
102494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish duration", mime);
102594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    }
102694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.duration_us = duration;
102794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
102894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    int32_t brate = -1;
102994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    if (!meta->findInt32(kKeyBitRate, &brate)) {
103094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald        ALOGV("track of type '%s' does not publish bitrate", mime);
103194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald     }
103294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.bit_rate = brate;
103394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103522612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent    info.stream_type = streamType;
103694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.has_video = hasVideo;
103794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    info.is_streaming = isStreaming;
103894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald
103994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // Check if offload is possible for given format, stream type, sample rate,
104094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    // bit rate, duration, video and streaming
104194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald    return AudioSystem::isOffloadSupported(info);
1042ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1043ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
1044a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) {
1045a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (incognito) {
1046a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return AString("<URI suppressed>");
1047a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1048a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1049a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    char prop[PROPERTY_VALUE_MAX];
1050a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    if (property_get("media.stagefright.log-uri", prop, "false") &&
1051a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
1052a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return uri;
1053a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1054a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1055a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    // find scheme
1056a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    AString scheme;
1057a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    const char *chars = uri.c_str();
1058a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    for (size_t i = 0; i < uri.size(); i++) {
1059a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        const char c = chars[i];
1060a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        if (!isascii(c)) {
1061a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1062a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isalpha(c)) {
1063a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1064a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (i == 0) {
1065a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            // first character must be a letter
1066a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1067a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
1068a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            continue;
1069a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        } else if (c != ':') {
1070a1df816c0677185534babba6ffc29970b048e52eLajos Molnar            break;
1071a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        }
1072a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme = AString(uri, 0, i);
1073a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        scheme.append("://<suppressed>");
1074a1df816c0677185534babba6ffc29970b048e52eLajos Molnar        return scheme;
1075a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    }
1076a1df816c0677185534babba6ffc29970b048e52eLajos Molnar    return AString("<no-scheme URI suppressed>");
1077a1df816c0677185534babba6ffc29970b048e52eLajos Molnar}
1078a1df816c0677185534babba6ffc29970b048e52eLajos Molnar
1079d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) :
1080d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mSeq(-1),
1081d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mTimeUs(-1ll),
1082d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    mMeta(meta) {
1083d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (meta != NULL) {
1084d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
1085d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(meta->findInt64("timeUs", &mTimeUs));
1086d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1087d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1088d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1089978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const {
1090d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t segmentStartTimeUs = -1ll;
1091d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if (mMeta != NULL) {
1092d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
1093978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1094978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t segmentFirstTimeUs;
1095978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
1096978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
1097978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        }
1098978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1099978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        // adjust segment time by playlist age (for live streaming)
1100978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        int64_t playlistTimeUs;
1101978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
1102978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
1103978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1104d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t durationUs;
1105d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
1106978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1107978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            // round to nearest whole segment
1108978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            playlistAgeUs = (playlistAgeUs + durationUs / 2)
1109978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                    / durationUs * durationUs;
1110978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang
1111978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            segmentStartTimeUs -= playlistAgeUs;
1112978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            if (segmentStartTimeUs < 0) {
1113978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang                segmentStartTimeUs = 0;
1114978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang            }
1115d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1116d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    }
1117d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return segmentStartTimeUs;
1118d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1119d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
1120d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) {
1121d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // we can only compare discontinuity sequence and timestamp.
1122d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // (mSegmentTimeUs is not reliable in live streaming case, it's the
1123d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    // time starting from beginning of playlist but playlist could change.)
1124d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    return t0.mSeq < t1.mSeq
1125d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
1126d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang}
1127d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang
11283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
11293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("speed", rate.mSpeed);
11303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("pitch", rate.mPitch);
11313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
11323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
11333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
11363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
11373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("speed", &rate->mSpeed));
11383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("pitch", &rate->mPitch));
11393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
11403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
11413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
11443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("sync-source", sync.mSource);
11453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
11463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("tolerance", sync.mTolerance);
11473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    msg->setFloat("video-fps", videoFpsHint);
11483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
11503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(
11513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        const sp<AMessage> &msg,
11523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        AVSyncSettings *sync /* nonnull */,
11533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        float *videoFps /* nonnull */) {
11543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    AVSyncSettings settings;
11553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
11563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
11573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
11583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    CHECK(msg->findFloat("video-fps", videoFps));
11593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    *sync = settings;
11603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar}
11613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
116283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) {
116383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    const size_t SIZE = 256;
116483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    char buffer[SIZE];
116583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    AString result;
116683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
116783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    struct stat s;
116883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    if (lstat(buffer, &s) == 0) {
116983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        if ((s.st_mode & S_IFMT) == S_IFLNK) {
117083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            char linkto[256];
117183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            int len = readlink(buffer, linkto, sizeof(linkto));
117283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            if(len > 0) {
117383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                if(len > 255) {
117483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[252] = '.';
117583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[253] = '.';
117683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[254] = '.';
117783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[255] = 0;
117883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                } else {
117983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                    linkto[len] = 0;
118083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                }
118183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen                result.append(linkto);
118283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            }
118383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        } else {
118483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append("unexpected type for ");
118583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen            result.append(buffer);
118683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        }
118783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    } else {
118883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append("couldn't open ");
118983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen        result.append(buffer);
119083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    }
119183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen    return result;
119283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen}
119383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen
119420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
119520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1196