Utils.cpp revision f4101f746a4a2c407a220dd61860a2b742eade51
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" 259806555d3930be43e11106281dee354820ac1c88Andreas Huber 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 27cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#include <cutils/properties.h> 282829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad#include <media/openmax/OMX_Audio.h> 299806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 309806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h> 319806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h> 329806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h> 3394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/MediaDefs.h> 3494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioSystem.h> 3594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/MediaPlayerInterface.h> 3694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <hardware/audio.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioParameter.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 8 | ptr[1]; 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) { 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) { 55ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[0] | (ptr[1] << 8); 56ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 57ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 58ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) { 59ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 60ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 61ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 62ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) { 63ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr); 64ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 65ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host. 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) { 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) { 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 759c170c076382096b9e767da0e3f9f37dafa76546Wei Jiastatic status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) { 769c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) { 779c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024); 789c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) { 799c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 809c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 819c170c076382096b9e767da0e3f9f37dafa76546Wei Jia memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size()); 829c170c076382096b9e767da0e3f9f37dafa76546Wei Jia tmpBuffer->setRange(0, (*buffer)->size()); 839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia (*buffer) = tmpBuffer; 849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia 869c170c076382096b9e767da0e3f9f37dafa76546Wei Jia memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4); 879c170c076382096b9e767da0e3f9f37dafa76546Wei Jia memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length); 889c170c076382096b9e767da0e3f9f37dafa76546Wei Jia (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length); 899c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return OK; 909c170c076382096b9e767da0e3f9f37dafa76546Wei Jia} 919c170c076382096b9e767da0e3f9f37dafa76546Wei Jia 929806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage( 939806555d3930be43e11106281dee354820ac1c88Andreas Huber const sp<MetaData> &meta, sp<AMessage> *format) { 9459e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen 959806555d3930be43e11106281dee354820ac1c88Andreas Huber format->clear(); 969806555d3930be43e11106281dee354820ac1c88Andreas Huber 9759e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen if (meta == NULL) { 9859e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen ALOGE("convertMetaDataToMessage: NULL input"); 9959e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen return BAD_VALUE; 10059e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen } 10159e469e0b0d95bba2aee3bbda003b7042fd1cdd9Marco Nelissen 1029806555d3930be43e11106281dee354820ac1c88Andreas Huber const char *mime; 103f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih if (!meta->findCString(kKeyMIMEType, &mime)) { 104f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih return BAD_VALUE; 105f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih } 1069806555d3930be43e11106281dee354820ac1c88Andreas Huber 1079806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<AMessage> msg = new AMessage; 1089806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setString("mime", mime); 1099806555d3930be43e11106281dee354820ac1c88Andreas Huber 1109806555d3930be43e11106281dee354820ac1c88Andreas Huber int64_t durationUs; 1119806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 1129806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt64("durationUs", durationUs); 1139806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1149806555d3930be43e11106281dee354820ac1c88Andreas Huber 115bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int avgBitRate; 116bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (meta->findInt32(kKeyBitRate, &avgBitRate)) { 117bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia msg->setInt32("bit-rate", avgBitRate); 118bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 119bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 1208c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 1218c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 1228c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen msg->setInt32("is-sync-frame", 1); 1238c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 1248c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 1259806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!strncasecmp("video/", mime, 6)) { 1269806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t width, height; 127f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih if (!meta->findInt32(kKeyWidth, &width) 128f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih || !meta->findInt32(kKeyHeight, &height)) { 129f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih return BAD_VALUE; 130f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih } 1319806555d3930be43e11106281dee354820ac1c88Andreas Huber 1329806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("width", width); 1339806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("height", height); 134516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 135516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 136516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (meta->findInt32(kKeySARWidth, &sarWidth) 137516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && meta->findInt32(kKeySARHeight, &sarHeight)) { 138516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-width", sarWidth); 139516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-height", sarHeight); 140516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 141475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 142475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t colorFormat; 143475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findInt32(kKeyColorFormat, &colorFormat)) { 144475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setInt32("color-format", colorFormat); 145475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 146475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 147475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t cropLeft, cropTop, cropRight, cropBottom; 148475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findRect(kKeyCropRect, 149475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropLeft, 150475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropTop, 151475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropRight, 152475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropBottom)) { 153475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom); 154475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 155475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 156475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t rotationDegrees; 157475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 158475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setInt32("rotation-degrees", rotationDegrees); 159475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 1609806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 1619806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t numChannels, sampleRate; 162f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih if (!meta->findInt32(kKeyChannelCount, &numChannels) 163f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih || !meta->findInt32(kKeySampleRate, &sampleRate)) { 164f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih return BAD_VALUE; 165f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih } 1669806555d3930be43e11106281dee354820ac1c88Andreas Huber 1679806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-count", numChannels); 1689806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("sample-rate", sampleRate); 1699806555d3930be43e11106281dee354820ac1c88Andreas Huber 1709806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 1719806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1729806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-mask", channelMask); 1739806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1749806555d3930be43e11106281dee354820ac1c88Andreas Huber 1759806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t delay = 0; 1769806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1779806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-delay", delay); 1789806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1799806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t padding = 0; 1809806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1819806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-padding", padding); 1829806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1839806555d3930be43e11106281dee354820ac1c88Andreas Huber 1849806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t isADTS; 1859806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1869806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("is-adts", true); 1879806555d3930be43e11106281dee354820ac1c88Andreas Huber } 188ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad 189ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad int32_t aacProfile = -1; 190ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad if (meta->findInt32(kKeyAACAOT, &aacProfile)) { 191ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad msg->setInt32("aac-profile", aacProfile); 192ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad } 1939806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1949806555d3930be43e11106281dee354820ac1c88Andreas Huber 1959806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t maxInputSize; 1969806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1979806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("max-input-size", maxInputSize); 1989806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1999806555d3930be43e11106281dee354820ac1c88Andreas Huber 200a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxWidth; 201a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (meta->findInt32(kKeyMaxWidth, &maxWidth)) { 202a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang msg->setInt32("max-width", maxWidth); 203a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 204a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 205a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxHeight; 206a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (meta->findInt32(kKeyMaxHeight, &maxHeight)) { 207a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang msg->setInt32("max-height", maxHeight); 208a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 209a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 210e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang int32_t rotationDegrees; 211e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 212e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang msg->setInt32("rotation-degrees", rotationDegrees); 213e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang } 214e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang 2158f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang int32_t fps; 2162a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) { 2178f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang msg->setInt32("frame-rate", fps); 2188f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang } 2198f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang 2209806555d3930be43e11106281dee354820ac1c88Andreas Huber uint32_t type; 2219806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *data; 2229806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t size; 2239806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 2249806555d3930be43e11106281dee354820ac1c88Andreas Huber // Parse the AVCDecoderConfigurationRecord 2259806555d3930be43e11106281dee354820ac1c88Andreas Huber 2269806555d3930be43e11106281dee354820ac1c88Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 2279806555d3930be43e11106281dee354820ac1c88Andreas Huber 2287bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 7 || ptr[0] != 1) { // configurationVersion == 1 2297bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 2307bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 2317bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 232b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t profile __unused = ptr[1]; 233b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t level __unused = ptr[3]; 2349806555d3930be43e11106281dee354820ac1c88Andreas Huber 2359806555d3930be43e11106281dee354820ac1c88Andreas Huber // There is decodable content out there that fails the following 2369806555d3930be43e11106281dee354820ac1c88Andreas Huber // assertion, let's be lenient for now... 2379806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 2389806555d3930be43e11106281dee354820ac1c88Andreas Huber 239b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t lengthSize __unused = 1 + (ptr[4] & 3); 2409806555d3930be43e11106281dee354820ac1c88Andreas Huber 2419806555d3930be43e11106281dee354820ac1c88Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 2429806555d3930be43e11106281dee354820ac1c88Andreas Huber // violates it... 2439806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 2449806555d3930be43e11106281dee354820ac1c88Andreas Huber 2459806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 2469806555d3930be43e11106281dee354820ac1c88Andreas Huber 2479806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 6; 2489806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 6; 2499806555d3930be43e11106281dee354820ac1c88Andreas Huber 2509c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024); 2519c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 2529c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 2539c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 2549806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 2559806555d3930be43e11106281dee354820ac1c88Andreas Huber 2569806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 2577bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 2) { 2587bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 2597bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 2607bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 2619806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 2629806555d3930be43e11106281dee354820ac1c88Andreas Huber 2639806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 2649806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 2659806555d3930be43e11106281dee354820ac1c88Andreas Huber 2669c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (size < length) { 2679c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return BAD_VALUE; 2689c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 2699c170c076382096b9e767da0e3f9f37dafa76546Wei Jia status_t err = copyNALUToABuffer(&buffer, ptr, length); 2709c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (err != OK) { 2719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return err; 2729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 2739806555d3930be43e11106281dee354820ac1c88Andreas Huber 2749806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 2759806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 2769806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2779806555d3930be43e11106281dee354820ac1c88Andreas Huber 2789806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2799806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2809806555d3930be43e11106281dee354820ac1c88Andreas Huber 2819806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2829806555d3930be43e11106281dee354820ac1c88Andreas Huber 2839c170c076382096b9e767da0e3f9f37dafa76546Wei Jia buffer = new (std::nothrow) ABuffer(1024); 2849c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 2859c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 2869c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 2879806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 2889806555d3930be43e11106281dee354820ac1c88Andreas Huber 2897bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 1) { 2907bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 2917bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 2927bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 2939806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numPictureParameterSets = *ptr; 2949806555d3930be43e11106281dee354820ac1c88Andreas Huber ++ptr; 2959806555d3930be43e11106281dee354820ac1c88Andreas Huber --size; 2969806555d3930be43e11106281dee354820ac1c88Andreas Huber 2979806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 2987bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 2) { 2997bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 3007bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 3017bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 3029806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 3039806555d3930be43e11106281dee354820ac1c88Andreas Huber 3049806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 3059806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 3069806555d3930be43e11106281dee354820ac1c88Andreas Huber 3079c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (size < length) { 3089c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return BAD_VALUE; 3099c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 3109c170c076382096b9e767da0e3f9f37dafa76546Wei Jia status_t err = copyNALUToABuffer(&buffer, ptr, length); 3119c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (err != OK) { 3129c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return err; 3139c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 3149806555d3930be43e11106281dee354820ac1c88Andreas Huber 3159806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 3169806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 3179806555d3930be43e11106281dee354820ac1c88Andreas Huber } 3189806555d3930be43e11106281dee354820ac1c88Andreas Huber 3199806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 3209806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 3219806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 3223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { 3233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 3243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3257bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 23 || ptr[0] != 1) { // configurationVersion == 1 3267bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 3277bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 3287bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 329b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t profile __unused = ptr[1] & 31; 330b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t level __unused = ptr[12]; 3313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 22; 3323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 22; 3333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofArrays = (char)ptr[0]; 3363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 3373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 3383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t j = 0, i = 0; 3393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3409c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024); 3419c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 3429c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 3439c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 3443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->setRange(0, 0); 3453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (i = 0; i < numofArrays; i++) { 3477bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 3) { 3487bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 3497bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 3507bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 3513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 3523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 3533b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3543b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar //Num of nals 3553b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofNals = U16_AT(ptr); 3563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3573b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 3583b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 3593b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3603b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (j = 0; j < numofNals; j++) { 3617bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia if (size < 2) { 3627bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia ALOGE("b/23680780"); 3637bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia return BAD_VALUE; 3647bb772e0c643ff3292599cf485b9dbf232bf39a4Wei Jia } 3653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t length = U16_AT(ptr); 3663b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3673b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 3683b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 3693b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3709c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (size < length) { 3719c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return BAD_VALUE; 3729c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 3739c170c076382096b9e767da0e3f9f37dafa76546Wei Jia status_t err = copyNALUToABuffer(&buffer, ptr, length); 3749c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (err != OK) { 3759c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return err; 3769c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 3773b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += length; 3793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= length; 3803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt32("csd", true); 3833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt64("timeUs", 0); 3843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar msg->setBuffer("csd-0", buffer); 3853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3869806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 3879806555d3930be43e11106281dee354820ac1c88Andreas Huber ESDS esds((const char *)data, size); 388f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih if (esds.InitCheck() != (status_t)OK) { 389f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih return BAD_VALUE; 390f4101f746a4a2c407a220dd61860a2b742eade51Robert Shih } 3919806555d3930be43e11106281dee354820ac1c88Andreas Huber 3929806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *codec_specific_data; 3939806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t codec_specific_data_size; 3949806555d3930be43e11106281dee354820ac1c88Andreas Huber esds.getCodecSpecificInfo( 3959806555d3930be43e11106281dee354820ac1c88Andreas Huber &codec_specific_data, &codec_specific_data_size); 3969806555d3930be43e11106281dee354820ac1c88Andreas Huber 3979c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size); 3989c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 3999c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4009c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 4019806555d3930be43e11106281dee354820ac1c88Andreas Huber 4029806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), codec_specific_data, 4039806555d3930be43e11106281dee354820ac1c88Andreas Huber codec_specific_data_size); 4049806555d3930be43e11106281dee354820ac1c88Andreas Huber 4059806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 4069806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 4079806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 4089806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 4099c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 4109c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 4119c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4129c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 4139806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 4149806555d3930be43e11106281dee354820ac1c88Andreas Huber 4159806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 4169806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 4179806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 4189806555d3930be43e11106281dee354820ac1c88Andreas Huber 4199806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 4209806555d3930be43e11106281dee354820ac1c88Andreas Huber return -EINVAL; 4219806555d3930be43e11106281dee354820ac1c88Andreas Huber } 4229806555d3930be43e11106281dee354820ac1c88Andreas Huber 4239c170c076382096b9e767da0e3f9f37dafa76546Wei Jia buffer = new (std::nothrow) ABuffer(size); 4249c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 4259c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4269c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 4279806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 4289806555d3930be43e11106281dee354820ac1c88Andreas Huber 4299806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 4309806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 4319806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 432bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) { 4339c170c076382096b9e767da0e3f9f37dafa76546Wei Jia sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 4349c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 4359c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4369c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 437bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian memcpy(buffer->data(), data, size); 438bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 439bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 440bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 441bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian msg->setBuffer("csd-0", buffer); 4429b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4439b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) { 4449b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian return -EINVAL; 4459b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } 4469b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4479c170c076382096b9e767da0e3f9f37dafa76546Wei Jia buffer = new (std::nothrow) ABuffer(size); 4489c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 4499c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4509c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 4519b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(buffer->data(), data, size); 4529b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4539b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 4549b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 4559b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian msg->setBuffer("csd-1", buffer); 4569b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4579b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) { 4589b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian return -EINVAL; 4599b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } 4609b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4619c170c076382096b9e767da0e3f9f37dafa76546Wei Jia buffer = new (std::nothrow) ABuffer(size); 4629c170c076382096b9e767da0e3f9f37dafa76546Wei Jia if (buffer.get() == NULL || buffer->base() == NULL) { 4639c170c076382096b9e767da0e3f9f37dafa76546Wei Jia return NO_MEMORY; 4649c170c076382096b9e767da0e3f9f37dafa76546Wei Jia } 4659b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(buffer->data(), data, size); 4669b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 4679b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 4689b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 4699b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian msg->setBuffer("csd-2", buffer); 4709806555d3930be43e11106281dee354820ac1c88Andreas Huber } 4719806555d3930be43e11106281dee354820ac1c88Andreas Huber 472793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih // TODO expose "crypto-key"/kKeyCryptoKey through public api 473793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih if (meta->findData(kKeyCryptoKey, &type, &data, &size)) { 474793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih sp<ABuffer> buffer = new (std::nothrow) ABuffer(size); 475793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih msg->setBuffer("crypto-key", buffer); 476793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih memcpy(buffer->data(), data, size); 477793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih } 478793c9fb11114c7be4636b8cae5477995aadeb71dRobert Shih 4799806555d3930be43e11106281dee354820ac1c88Andreas Huber *format = msg; 4809806555d3930be43e11106281dee354820ac1c88Andreas Huber 4819806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 4829806555d3930be43e11106281dee354820ac1c88Andreas Huber} 4839806555d3930be43e11106281dee354820ac1c88Andreas Huber 48456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 48556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 48656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[0] = 1; // version 48756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[1] = 0x64; // profile 48856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[2] = 0; // unused (?) 48956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[3] = 0xd; // level 49056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[4] = 0xff; // reserved+size 49156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 49256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t i = 0; 49356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numparams = 0; 49456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int lastparamoffset = 0; 49556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int avccidx = 6; 49656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 49756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4 || 49856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 49956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4) { 50056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 50156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd0->size(); 50256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 503a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("block at %zu, last was %d", i, lastparamoffset); 50456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 50556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 50656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 50756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 50856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 50956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 51056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 51156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 51256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 51356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 51456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 51556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 51656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 51756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd0->size()); 51856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("csd0 contains %d params", numparams); 51956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 52056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[5] = 0xe0 | numparams; 52156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen //and now csd-1 52256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = 0; 52356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams = 0; 52456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = 0; 52556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numpicparamsoffset = avccidx; 52656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx++; 52756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 52856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4 || 52956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 53056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4) { 53156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 53256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd1->size(); 53356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 534a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("block at %zu, last was %d", i, lastparamoffset); 53556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 53656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 53756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 53856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 53956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 54056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 54156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 54256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 54356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 54456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 54556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 54656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 54756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 54856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd1->size()); 54956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[numpicparamsoffset] = numparams; 55056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return avccidx; 55156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 55256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[0] = 3; // kTag_ESDescriptor; 55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int esdescriptorsize = 26 + csd0size; 55756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[1] = 0x80 | (esdescriptorsize >> 21); 55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[4] = (esdescriptorsize & 0x7f); 56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[5] = esds[6] = 0; // es id 56356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[7] = 0; // flags 56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[8] = 4; // kTag_DecoderConfigDescriptor 56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int configdescriptorsize = 18 + csd0size; 56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[9] = 0x80 | (configdescriptorsize >> 21); 56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[12] = (configdescriptorsize & 0x7f); 57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[13] = 0x40; // objectTypeIndication 57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[15] = 0x00; // but the actual values here were taken from a real file. 57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[16] = 0x18; 57456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[17] = 0x00; 57556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[18] = 0x00; 57656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[19] = 0x00; 57756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[20] = 0xfa; 57856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[21] = 0x00; 57956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[22] = 0x00; 58056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[23] = 0x00; 58156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[24] = 0xfa; 58256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[25] = 0x00; 58356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[26] = 5; // kTag_DecoderSpecificInfo; 58456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[27] = 0x80 | (csd0size >> 21); 58556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 58656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 58756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[30] = (csd0size & 0x7f); 58856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy((void*)&esds[31], csd0->data(), csd0size); 58956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // data following this is ignored, so don't bother appending it 59056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 59156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 59256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 59356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 59456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen AString mime; 59556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findString("mime", &mime)) { 59656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setCString(kKeyMIMEType, mime.c_str()); 59756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 59856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find mime type"); 59956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 60056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 60156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int64_t durationUs; 60256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt64("durationUs", &durationUs)) { 60356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt64(kKeyDuration, durationUs); 60456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 6068c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 6078c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 6088c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen meta->setInt32(kKeyIsSyncFrame, 1); 6098c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 6108c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 61156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mime.startsWith("video/")) { 61256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t width; 61356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t height; 61456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 61556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyWidth, width); 61656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyHeight, height); 61756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 61856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find width and/or height"); 61956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 620516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 621516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 622516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (msg->findInt32("sar-width", &sarWidth) 623516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && msg->findInt32("sar-height", &sarHeight)) { 624516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARWidth, sarWidth); 625516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARHeight, sarHeight); 626516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 627475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 628475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t colorFormat; 629475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findInt32("color-format", &colorFormat)) { 630475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setInt32(kKeyColorFormat, colorFormat); 631475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 632475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 633475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t cropLeft, cropTop, cropRight, cropBottom; 634475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findRect("crop", 635475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropLeft, 636475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropTop, 637475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropRight, 638475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropBottom)) { 639475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom); 640475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 641475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 642475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t rotationDegrees; 643475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 644475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setInt32(kKeyRotation, rotationDegrees); 645475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 64656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else if (mime.startsWith("audio/")) { 64756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t numChannels; 64856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-count", &numChannels)) { 64956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelCount, numChannels); 65056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 65156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t sampleRate; 65256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("sample-rate", &sampleRate)) { 65356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeySampleRate, sampleRate); 65456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 65556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t channelMask; 65656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-mask", &channelMask)) { 65756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelMask, channelMask); 65856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 65956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t delay = 0; 66056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-delay", &delay)) { 66156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderDelay, delay); 66256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 66356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t padding = 0; 66456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-padding", &padding)) { 66556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderPadding, padding); 66656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 66756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 66856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t isADTS; 66956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("is-adts", &isADTS)) { 67056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyIsADTS, isADTS); 67156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 67256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 67356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 67456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t maxInputSize; 67556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("max-input-size", &maxInputSize)) { 67656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyMaxInputSize, maxInputSize); 67756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 67856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 679a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxWidth; 680a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (msg->findInt32("max-width", &maxWidth)) { 681a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang meta->setInt32(kKeyMaxWidth, maxWidth); 682a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 683a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 684a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxHeight; 685a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (msg->findInt32("max-height", &maxHeight)) { 686a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang meta->setInt32(kKeyMaxHeight, maxHeight); 687a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 688a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 6898f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang int32_t fps; 6902a886d196ae717adc353a9fb4371b6a5abbd89a5Lajos Molnar if (msg->findInt32("frame-rate", &fps) && fps > 0) { 6918f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang meta->setInt32(kKeyFrameRate, fps); 6928f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang } 6938f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang 69456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // reassemble the csd data into its original form 69556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd0; 69656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-0", &csd0)) { 69777f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { 69856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd1; 69956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-1", &csd1)) { 70056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char avcc[1024]; // that oughta be enough, right? 70156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t outsize = reassembleAVCC(csd0, csd1, avcc); 70256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 70356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 70477f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { 70556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 70656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char esds[csd0size + 31]; 70777f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo // The written ESDS is actually for an audio stream, but it's enough 70877f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo // for transporting the CSD to muxers. 70956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen reassembleESDS(csd0, esds); 71056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 71156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 71256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 71356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 7142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int32_t timeScale; 7152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (msg->findInt32("time-scale", &timeScale)) { 7162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang meta->setInt32(kKeyTimeScale, timeScale); 7172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 7182c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 71956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // XXX TODO add whatever other keys there are 72056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 72156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0 72256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGI("converted %s to:", msg->debugString(0).c_str()); 72356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->dumpToLog(); 72456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif 72556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 72656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 727cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() { 728cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber AString ua; 729cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append("stagefright/1.2 (Linux;Android "); 730cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 731cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8) 732cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8" 733cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif 734cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 735cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber char value[PROPERTY_VALUE_MAX]; 736cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber property_get("ro.build.version.release", value, "Unknown"); 737cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(value); 738cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(")"); 739cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 740cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber return ua; 741cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber} 74256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 743ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, 744ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald const sp<MetaData>& meta) 745ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 74694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t sampleRate = 0; 74794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t bitRate = 0; 74894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelMask = 0; 74994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t delaySamples = 0; 75094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t paddingSamples = 0; 75194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 75294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald AudioParameter param = AudioParameter(); 75394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 75494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeySampleRate, &sampleRate)) { 75594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate); 75694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 75794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyChannelMask, &channelMask)) { 75894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask); 75994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 76094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyBitRate, &bitRate)) { 76194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate); 76294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 76394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) { 76494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples); 76594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 76694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) { 76794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples); 76894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 76994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 77094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d," 77194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald "delaySample %d, paddingSample %d", bitRate, sampleRate, 77294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald channelMask, delaySamples, paddingSamples); 77394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 77494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald sink->setParameters(param.toString()); 775ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return OK; 776ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 777ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 77894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t { 77994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char* mime; 78094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_format_t format; 78194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 78294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 78394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = { 78494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 }, 78594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT }, 78694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB }, 78794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB }, 78894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC }, 78994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, 790bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, 79194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { 0, AUDIO_FORMAT_INVALID } 79294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 79394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 79494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime ) 795ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 79694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0]; 79794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald while (p->mime != NULL) { 79894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (0 == strcasecmp(mime, p->mime)) { 79994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald format = p->format; 80094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return OK; 80194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 80294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ++p; 80394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 80494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 805ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return BAD_VALUE; 806ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 807ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 8082829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t { 8092829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad OMX_AUDIO_AACPROFILETYPE eAacProfileType; 8102829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad audio_format_t format; 8112829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}; 8122829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 8132829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = { 8142829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN}, 8152829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC}, 8162829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR}, 8172829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP}, 8182829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1}, 8192829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE}, 8202829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC}, 8212829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD}, 8222829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2}, 8232829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD}, 8242829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC}, 8252829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}; 8262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 8272829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile) 8282829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{ 8292829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0]; 8302829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) { 8312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad if (eAacProfile == p->eAacProfileType) { 8322829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad format = p->format; 8332829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad return; 8342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad } 8352829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad ++p; 8362829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad } 8372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad format = AUDIO_FORMAT_AAC; 8382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad return; 8392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad} 8402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 84122612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, 84222612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent bool isStreaming, audio_stream_type_t streamType) 843ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 84494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char *mime; 845cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia if (meta == NULL) { 846cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia return false; 847cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia } 84894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald CHECK(meta->findCString(kKeyMIMEType, &mime)); 84994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 85094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_offload_info_t info = AUDIO_INFO_INITIALIZER; 85194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 85294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.format = AUDIO_FORMAT_INVALID; 85394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (mapMimeToAudioFormat(info.format, mime) != OK) { 85494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime); 85594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 85694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 85794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format); 85894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 85994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 86094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (AUDIO_FORMAT_INVALID == info.format) { 86194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // can't offload if we don't know what the source format is 86294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE("mime type \"%s\" not a known audio format", mime); 86394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 86494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 86594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 8662829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad // Redefine aac format according to its profile 8672829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad // Offloading depends on audio DSP capabilities. 868db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent int32_t aacaot = -1; 869db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent if (meta->findInt32(kKeyAACAOT, &aacaot)) { 8702829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot); 871db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent } 872db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 87394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t srate = -1; 87494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeySampleRate, &srate)) { 87594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish sample rate", mime); 87694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 87794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.sample_rate = srate; 87894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 87994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t cmask = 0; 88094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelMask, &cmask)) { 88194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel mask", mime); 88294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 88394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Try a channel count instead 88494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelCount; 88594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelCount, &channelCount)) { 88694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel count", mime); 88794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 88894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald cmask = audio_channel_out_mask_from_count(channelCount); 88994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 89094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 89194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.channel_mask = cmask; 89294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 89394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int64_t duration = 0; 89494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt64(kKeyDuration, &duration)) { 89594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish duration", mime); 89694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 89794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.duration_us = duration; 89894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 89994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t brate = -1; 90094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyBitRate, &brate)) { 90194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish bitrate", mime); 90294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 90394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.bit_rate = brate; 90494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 90594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 90622612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent info.stream_type = streamType; 90794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.has_video = hasVideo; 90894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.is_streaming = isStreaming; 90994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 91094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Check if offload is possible for given format, stream type, sample rate, 91194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // bit rate, duration, video and streaming 91294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return AudioSystem::isOffloadSupported(info); 913ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 914ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 915a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) { 916a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (incognito) { 917a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<URI suppressed>"); 918a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 919a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 920a1df816c0677185534babba6ffc29970b048e52eLajos Molnar char prop[PROPERTY_VALUE_MAX]; 921a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (property_get("media.stagefright.log-uri", prop, "false") && 922a1df816c0677185534babba6ffc29970b048e52eLajos Molnar (!strcmp(prop, "1") || !strcmp(prop, "true"))) { 923a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return uri; 924a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 925a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 926a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // find scheme 927a1df816c0677185534babba6ffc29970b048e52eLajos Molnar AString scheme; 928a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char *chars = uri.c_str(); 929a1df816c0677185534babba6ffc29970b048e52eLajos Molnar for (size_t i = 0; i < uri.size(); i++) { 930a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char c = chars[i]; 931a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (!isascii(c)) { 932a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 933a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isalpha(c)) { 934a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 935a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (i == 0) { 936a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // first character must be a letter 937a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 938a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 939a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 940a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (c != ':') { 941a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 942a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 943a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme = AString(uri, 0, i); 944a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme.append("://<suppressed>"); 945a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return scheme; 946a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 947a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<no-scheme URI suppressed>"); 948a1df816c0677185534babba6ffc29970b048e52eLajos Molnar} 949a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 950d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) : 951d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mSeq(-1), 952d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mTimeUs(-1ll), 953d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mMeta(meta) { 954d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (meta != NULL) { 955d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(meta->findInt32("discontinuitySeq", &mSeq)); 956d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(meta->findInt64("timeUs", &mTimeUs)); 957d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 958d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 959d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 960978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const { 961d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t segmentStartTimeUs = -1ll; 962d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (mMeta != NULL) { 963d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs)); 964978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 965978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t segmentFirstTimeUs; 966978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) { 967978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs += mTimeUs - segmentFirstTimeUs; 968978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang } 969978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 970978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang // adjust segment time by playlist age (for live streaming) 971978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t playlistTimeUs; 972978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) { 973978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs; 974978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 975d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t durationUs; 976d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(mMeta->findInt64("segmentDurationUs", &durationUs)); 977978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 978978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang // round to nearest whole segment 979978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang playlistAgeUs = (playlistAgeUs + durationUs / 2) 980978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang / durationUs * durationUs; 981978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 982978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs -= playlistAgeUs; 983978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (segmentStartTimeUs < 0) { 984978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs = 0; 985978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang } 986d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 987d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 988d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang return segmentStartTimeUs; 989d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 990d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 991d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) { 992d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // we can only compare discontinuity sequence and timestamp. 993d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // (mSegmentTimeUs is not reliable in live streaming case, it's the 994d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // time starting from beginning of playlist but playlist could change.) 995d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang return t0.mSeq < t1.mSeq 996d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs); 997d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 998d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 9993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) { 10003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("speed", rate.mSpeed); 10013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("pitch", rate.mPitch); 10023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-fallback-mode", rate.mFallbackMode); 10033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-stretch-mode", rate.mStretchMode); 10043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 10053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 10063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) { 10073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *rate = AUDIO_PLAYBACK_RATE_DEFAULT; 10083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("speed", &rate->mSpeed)); 10093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("pitch", &rate->mPitch)); 10103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode)); 10113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode)); 10123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 10133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 10143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) { 10153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("sync-source", sync.mSource); 10163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode); 10173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("tolerance", sync.mTolerance); 10183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("video-fps", videoFpsHint); 10193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 10203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 10213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage( 10223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar const sp<AMessage> &msg, 10233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings *sync /* nonnull */, 10243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float *videoFps /* nonnull */) { 10253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings settings; 10263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource)); 10273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode)); 10283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("tolerance", &settings.mTolerance)); 10293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("video-fps", videoFps)); 10303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *sync = settings; 10313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 10323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 103383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco NelissenAString nameForFd(int fd) { 103483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen const size_t SIZE = 256; 103583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen char buffer[SIZE]; 103683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen AString result; 103783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd); 103883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen struct stat s; 103983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen if (lstat(buffer, &s) == 0) { 104083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen if ((s.st_mode & S_IFMT) == S_IFLNK) { 104183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen char linkto[256]; 104283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen int len = readlink(buffer, linkto, sizeof(linkto)); 104383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen if(len > 0) { 104483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen if(len > 255) { 104583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen linkto[252] = '.'; 104683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen linkto[253] = '.'; 104783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen linkto[254] = '.'; 104883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen linkto[255] = 0; 104983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } else { 105083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen linkto[len] = 0; 105183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } 105283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen result.append(linkto); 105383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } 105483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } else { 105583b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen result.append("unexpected type for "); 105683b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen result.append(buffer); 105783b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } 105883b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } else { 105983b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen result.append("couldn't open "); 106083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen result.append(buffer); 106183b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen } 106283b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen return result; 106383b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen} 106483b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1067