Utils.cpp revision 77f101b342b6d206b6f530991f3333dfedeebab6
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> 219806555d3930be43e11106281dee354820ac1c88Andreas Huber 229806555d3930be43e11106281dee354820ac1c88Andreas Huber#include "include/ESDS.h" 239806555d3930be43e11106281dee354820ac1c88Andreas Huber 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 25cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#include <cutils/properties.h> 262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad#include <media/openmax/OMX_Audio.h> 279806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 289806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h> 299806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h> 309806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h> 3194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/MediaDefs.h> 3294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioSystem.h> 3394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/MediaPlayerInterface.h> 3494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <hardware/audio.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioParameter.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) { 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 8 | ptr[1]; 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) { 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) { 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) { 53ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[0] | (ptr[1] << 8); 54ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 55ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 56ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) { 57ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 58ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 59ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 60ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) { 61ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr); 62ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 63ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host. 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) { 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) { 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 739806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage( 749806555d3930be43e11106281dee354820ac1c88Andreas Huber const sp<MetaData> &meta, sp<AMessage> *format) { 759806555d3930be43e11106281dee354820ac1c88Andreas Huber format->clear(); 769806555d3930be43e11106281dee354820ac1c88Andreas Huber 779806555d3930be43e11106281dee354820ac1c88Andreas Huber const char *mime; 789806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 799806555d3930be43e11106281dee354820ac1c88Andreas Huber 809806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<AMessage> msg = new AMessage; 819806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setString("mime", mime); 829806555d3930be43e11106281dee354820ac1c88Andreas Huber 839806555d3930be43e11106281dee354820ac1c88Andreas Huber int64_t durationUs; 849806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 859806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt64("durationUs", durationUs); 869806555d3930be43e11106281dee354820ac1c88Andreas Huber } 879806555d3930be43e11106281dee354820ac1c88Andreas Huber 88bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia int avgBitRate; 89bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia if (meta->findInt32(kKeyBitRate, &avgBitRate)) { 90bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia msg->setInt32("bit-rate", avgBitRate); 91bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia } 92bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia 938c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 948c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 958c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen msg->setInt32("is-sync-frame", 1); 968c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 978c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 989806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!strncasecmp("video/", mime, 6)) { 999806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t width, height; 1009806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 1019806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 1029806555d3930be43e11106281dee354820ac1c88Andreas Huber 1039806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("width", width); 1049806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("height", height); 105516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 106516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 107516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (meta->findInt32(kKeySARWidth, &sarWidth) 108516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && meta->findInt32(kKeySARHeight, &sarHeight)) { 109516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-width", sarWidth); 110516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-height", sarHeight); 111516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 112475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 113475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t colorFormat; 114475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findInt32(kKeyColorFormat, &colorFormat)) { 115475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setInt32("color-format", colorFormat); 116475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 117475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 118475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t cropLeft, cropTop, cropRight, cropBottom; 119475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findRect(kKeyCropRect, 120475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropLeft, 121475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropTop, 122475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropRight, 123475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropBottom)) { 124475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom); 125475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 126475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 127475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t rotationDegrees; 128475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 129475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu msg->setInt32("rotation-degrees", rotationDegrees); 130475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 1319806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 1329806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t numChannels, sampleRate; 1339806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 1349806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 1359806555d3930be43e11106281dee354820ac1c88Andreas Huber 1369806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-count", numChannels); 1379806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("sample-rate", sampleRate); 1389806555d3930be43e11106281dee354820ac1c88Andreas Huber 1399806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 1409806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1419806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-mask", channelMask); 1429806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1439806555d3930be43e11106281dee354820ac1c88Andreas Huber 1449806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t delay = 0; 1459806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1469806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-delay", delay); 1479806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1489806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t padding = 0; 1499806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1509806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-padding", padding); 1519806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1529806555d3930be43e11106281dee354820ac1c88Andreas Huber 1539806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t isADTS; 1549806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1559806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("is-adts", true); 1569806555d3930be43e11106281dee354820ac1c88Andreas Huber } 157ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad 158ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad int32_t aacProfile = -1; 159ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad if (meta->findInt32(kKeyAACAOT, &aacProfile)) { 160ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad msg->setInt32("aac-profile", aacProfile); 161ccad786f3497f223cbc5af981b08b460433ee622aarti jadhav-gaikwad } 1629806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1639806555d3930be43e11106281dee354820ac1c88Andreas Huber 1649806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t maxInputSize; 1659806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1669806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("max-input-size", maxInputSize); 1679806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1689806555d3930be43e11106281dee354820ac1c88Andreas Huber 169a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxWidth; 170a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (meta->findInt32(kKeyMaxWidth, &maxWidth)) { 171a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang msg->setInt32("max-width", maxWidth); 172a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 173a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 174a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxHeight; 175a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (meta->findInt32(kKeyMaxHeight, &maxHeight)) { 176a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang msg->setInt32("max-height", maxHeight); 177a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 178a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 179e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang int32_t rotationDegrees; 180e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang if (meta->findInt32(kKeyRotation, &rotationDegrees)) { 181e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang msg->setInt32("rotation-degrees", rotationDegrees); 182e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang } 183e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang 1848f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang int32_t fps; 1858f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang if (meta->findInt32(kKeyFrameRate, &fps)) { 1868f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang msg->setInt32("frame-rate", fps); 1878f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang } 1888f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang 1899806555d3930be43e11106281dee354820ac1c88Andreas Huber uint32_t type; 1909806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *data; 1919806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t size; 1929806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1939806555d3930be43e11106281dee354820ac1c88Andreas Huber // Parse the AVCDecoderConfigurationRecord 1949806555d3930be43e11106281dee354820ac1c88Andreas Huber 1959806555d3930be43e11106281dee354820ac1c88Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1969806555d3930be43e11106281dee354820ac1c88Andreas Huber 1979806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 7); 1989806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 199b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t profile __unused = ptr[1]; 200b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t level __unused = ptr[3]; 2019806555d3930be43e11106281dee354820ac1c88Andreas Huber 2029806555d3930be43e11106281dee354820ac1c88Andreas Huber // There is decodable content out there that fails the following 2039806555d3930be43e11106281dee354820ac1c88Andreas Huber // assertion, let's be lenient for now... 2049806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 2059806555d3930be43e11106281dee354820ac1c88Andreas Huber 206b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe size_t lengthSize __unused = 1 + (ptr[4] & 3); 2079806555d3930be43e11106281dee354820ac1c88Andreas Huber 2089806555d3930be43e11106281dee354820ac1c88Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 2099806555d3930be43e11106281dee354820ac1c88Andreas Huber // violates it... 2109806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 2119806555d3930be43e11106281dee354820ac1c88Andreas Huber 2129806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 2139806555d3930be43e11106281dee354820ac1c88Andreas Huber 2149806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 6; 2159806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 6; 2169806555d3930be43e11106281dee354820ac1c88Andreas Huber 2179806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 2189806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 2199806555d3930be43e11106281dee354820ac1c88Andreas Huber 2209806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 2219806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 2229806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 2239806555d3930be43e11106281dee354820ac1c88Andreas Huber 2249806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 2259806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 2269806555d3930be43e11106281dee354820ac1c88Andreas Huber 2279806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 2289806555d3930be43e11106281dee354820ac1c88Andreas Huber 2299806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2309806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2319806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2329806555d3930be43e11106281dee354820ac1c88Andreas Huber 2339806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 2349806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 2359806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2369806555d3930be43e11106281dee354820ac1c88Andreas Huber 2379806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2389806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2399806555d3930be43e11106281dee354820ac1c88Andreas Huber 2409806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2419806555d3930be43e11106281dee354820ac1c88Andreas Huber 2429806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(1024); 2439806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 2449806555d3930be43e11106281dee354820ac1c88Andreas Huber 2459806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 1); 2469806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numPictureParameterSets = *ptr; 2479806555d3930be43e11106281dee354820ac1c88Andreas Huber ++ptr; 2489806555d3930be43e11106281dee354820ac1c88Andreas Huber --size; 2499806555d3930be43e11106281dee354820ac1c88Andreas Huber 2509806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 2519806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 2529806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 2539806555d3930be43e11106281dee354820ac1c88Andreas Huber 2549806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 2559806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 2569806555d3930be43e11106281dee354820ac1c88Andreas Huber 2579806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 2589806555d3930be43e11106281dee354820ac1c88Andreas Huber 2599806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2609806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2619806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2629806555d3930be43e11106281dee354820ac1c88Andreas Huber 2639806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 2649806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 2659806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2669806555d3930be43e11106281dee354820ac1c88Andreas Huber 2679806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2689806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2699806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2703b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { 2713b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 2723b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2733b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 7); 2743b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 275b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t profile __unused = ptr[1] & 31; 276b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t level __unused = ptr[12]; 2773b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 22; 2783b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 22; 2793b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2803b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2813b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofArrays = (char)ptr[0]; 2823b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 2833b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 2843b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t j = 0, i = 0; 2853b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2863b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(1024); 2873b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->setRange(0, 0); 2883b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2893b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (i = 0; i < numofArrays; i++) { 2903b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 2913b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 2923b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2933b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar //Num of nals 2943b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofNals = U16_AT(ptr); 2953b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2963b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 2973b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 2983b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2993b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (j = 0; j < numofNals; j++) { 3003b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 2); 3013b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t length = U16_AT(ptr); 3023b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3033b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 3043b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 3053b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3063b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= length); 3073b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3083b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 3093b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar memcpy(buffer->data() + buffer->size() + 4, ptr, length); 3103b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->setRange(0, buffer->size() + 4 + length); 3113b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3123b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += length; 3133b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= length; 3143b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3153b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 3163b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt32("csd", true); 3173b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt64("timeUs", 0); 3183b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar msg->setBuffer("csd-0", buffer); 3193b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 3209806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 3219806555d3930be43e11106281dee354820ac1c88Andreas Huber ESDS esds((const char *)data, size); 3229806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 3239806555d3930be43e11106281dee354820ac1c88Andreas Huber 3249806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *codec_specific_data; 3259806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t codec_specific_data_size; 3269806555d3930be43e11106281dee354820ac1c88Andreas Huber esds.getCodecSpecificInfo( 3279806555d3930be43e11106281dee354820ac1c88Andreas Huber &codec_specific_data, &codec_specific_data_size); 3289806555d3930be43e11106281dee354820ac1c88Andreas Huber 3299806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 3309806555d3930be43e11106281dee354820ac1c88Andreas Huber 3319806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), codec_specific_data, 3329806555d3930be43e11106281dee354820ac1c88Andreas Huber codec_specific_data_size); 3339806555d3930be43e11106281dee354820ac1c88Andreas Huber 3349806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 3359806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 3369806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 3379806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 3389806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 3399806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 3409806555d3930be43e11106281dee354820ac1c88Andreas Huber 3419806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 3429806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 3439806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 3449806555d3930be43e11106281dee354820ac1c88Andreas Huber 3459806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 3469806555d3930be43e11106281dee354820ac1c88Andreas Huber return -EINVAL; 3479806555d3930be43e11106281dee354820ac1c88Andreas Huber } 3489806555d3930be43e11106281dee354820ac1c88Andreas Huber 3499806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(size); 3509806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 3519806555d3930be43e11106281dee354820ac1c88Andreas Huber 3529806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 3539806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 3549806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 355bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) { 356bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian sp<ABuffer> buffer = new ABuffer(size); 357bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian memcpy(buffer->data(), data, size); 358bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 359bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 360bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 361bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian msg->setBuffer("csd-0", buffer); 3629b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3639b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) { 3649b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian return -EINVAL; 3659b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } 3669b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3679b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer = new ABuffer(size); 3689b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(buffer->data(), data, size); 3699b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3709b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 3719b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 3729b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian msg->setBuffer("csd-1", buffer); 3739b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3749b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) { 3759b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian return -EINVAL; 3769b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian } 3779b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3789b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer = new ABuffer(size); 3799b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian memcpy(buffer->data(), data, size); 3809b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian 3819b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 3829b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 3839b4b24a46f3f76ebb186df8bc01c58848af02108Vignesh Venkatasubramanian msg->setBuffer("csd-2", buffer); 3849806555d3930be43e11106281dee354820ac1c88Andreas Huber } 3859806555d3930be43e11106281dee354820ac1c88Andreas Huber 3869806555d3930be43e11106281dee354820ac1c88Andreas Huber *format = msg; 3879806555d3930be43e11106281dee354820ac1c88Andreas Huber 3889806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 3899806555d3930be43e11106281dee354820ac1c88Andreas Huber} 3909806555d3930be43e11106281dee354820ac1c88Andreas Huber 39156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 39256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 39356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[0] = 1; // version 39456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[1] = 0x64; // profile 39556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[2] = 0; // unused (?) 39656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[3] = 0xd; // level 39756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[4] = 0xff; // reserved+size 39856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 39956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t i = 0; 40056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numparams = 0; 40156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int lastparamoffset = 0; 40256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int avccidx = 6; 40356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 40456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4 || 40556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 40656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4) { 40756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 40856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd0->size(); 40956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 410a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("block at %zu, last was %d", i, lastparamoffset); 41156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 41256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 41356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 41456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 41556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 41656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 41756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 41856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 41956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 42056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 42156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 42256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 42356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 42456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd0->size()); 42556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("csd0 contains %d params", numparams); 42656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 42756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[5] = 0xe0 | numparams; 42856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen //and now csd-1 42956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = 0; 43056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams = 0; 43156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = 0; 43256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numpicparamsoffset = avccidx; 43356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx++; 43456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 43556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4 || 43656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 43756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4) { 43856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 43956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd1->size(); 44056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 441a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("block at %zu, last was %d", i, lastparamoffset); 44256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 44356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 44456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 44556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 44656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 44756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 44856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 44956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 45056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 45156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 45256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 45356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 45456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 45556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd1->size()); 45656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[numpicparamsoffset] = numparams; 45756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return avccidx; 45856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 45956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 46056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 46156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 46256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[0] = 3; // kTag_ESDescriptor; 46356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int esdescriptorsize = 26 + csd0size; 46456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 46556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[1] = 0x80 | (esdescriptorsize >> 21); 46656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 46756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 46856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[4] = (esdescriptorsize & 0x7f); 46956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[5] = esds[6] = 0; // es id 47056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[7] = 0; // flags 47156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[8] = 4; // kTag_DecoderConfigDescriptor 47256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int configdescriptorsize = 18 + csd0size; 47356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[9] = 0x80 | (configdescriptorsize >> 21); 47456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 47556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 47656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[12] = (configdescriptorsize & 0x7f); 47756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[13] = 0x40; // objectTypeIndication 47856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 47956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[15] = 0x00; // but the actual values here were taken from a real file. 48056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[16] = 0x18; 48156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[17] = 0x00; 48256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[18] = 0x00; 48356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[19] = 0x00; 48456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[20] = 0xfa; 48556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[21] = 0x00; 48656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[22] = 0x00; 48756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[23] = 0x00; 48856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[24] = 0xfa; 48956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[25] = 0x00; 49056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[26] = 5; // kTag_DecoderSpecificInfo; 49156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[27] = 0x80 | (csd0size >> 21); 49256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 49356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 49456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[30] = (csd0size & 0x7f); 49556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy((void*)&esds[31], csd0->data(), csd0size); 49656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // data following this is ignored, so don't bother appending it 49756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 49856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 49956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 50056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 50156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen AString mime; 50256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findString("mime", &mime)) { 50356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setCString(kKeyMIMEType, mime.c_str()); 50456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 50556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find mime type"); 50656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 50756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 50856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int64_t durationUs; 50956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt64("durationUs", &durationUs)) { 51056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt64(kKeyDuration, durationUs); 51156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 51256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 5138c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 5148c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 5158c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen meta->setInt32(kKeyIsSyncFrame, 1); 5168c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 5178c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 51856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mime.startsWith("video/")) { 51956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t width; 52056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t height; 52156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 52256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyWidth, width); 52356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyHeight, height); 52456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 52556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find width and/or height"); 52656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 527516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 528516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 529516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (msg->findInt32("sar-width", &sarWidth) 530516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && msg->findInt32("sar-height", &sarHeight)) { 531516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARWidth, sarWidth); 532516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARHeight, sarHeight); 533516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 534475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 535475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t colorFormat; 536475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findInt32("color-format", &colorFormat)) { 537475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setInt32(kKeyColorFormat, colorFormat); 538475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 539475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 540475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t cropLeft, cropTop, cropRight, cropBottom; 541475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findRect("crop", 542475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropLeft, 543475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropTop, 544475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropRight, 545475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu &cropBottom)) { 546475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom); 547475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 548475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 549475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t rotationDegrees; 550475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (msg->findInt32("rotation-degrees", &rotationDegrees)) { 551475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu meta->setInt32(kKeyRotation, rotationDegrees); 552475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 55356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else if (mime.startsWith("audio/")) { 55456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t numChannels; 55556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-count", &numChannels)) { 55656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelCount, numChannels); 55756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 55856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t sampleRate; 55956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("sample-rate", &sampleRate)) { 56056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeySampleRate, sampleRate); 56156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 56256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t channelMask; 56356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-mask", &channelMask)) { 56456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelMask, channelMask); 56556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 56656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t delay = 0; 56756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-delay", &delay)) { 56856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderDelay, delay); 56956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 57056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t padding = 0; 57156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-padding", &padding)) { 57256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderPadding, padding); 57356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 57456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 57556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t isADTS; 57656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("is-adts", &isADTS)) { 57756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyIsADTS, isADTS); 57856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 57956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 58056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 58156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t maxInputSize; 58256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("max-input-size", &maxInputSize)) { 58356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyMaxInputSize, maxInputSize); 58456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 58556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 586a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxWidth; 587a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (msg->findInt32("max-width", &maxWidth)) { 588a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang meta->setInt32(kKeyMaxWidth, maxWidth); 589a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 590a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 591a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang int32_t maxHeight; 592a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang if (msg->findInt32("max-height", &maxHeight)) { 593a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang meta->setInt32(kKeyMaxHeight, maxHeight); 594a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang } 595a0d0ba51ad60a68117a0ee78e37ab78715b8a069Chong Zhang 5968f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang int32_t fps; 5978f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang if (msg->findInt32("frame-rate", &fps)) { 5988f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang meta->setInt32(kKeyFrameRate, fps); 5998f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang } 6008f5919da04fb6aa7eb7cff70b061d8702627436cChong Zhang 60156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // reassemble the csd data into its original form 60256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd0; 60356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-0", &csd0)) { 60477f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo if (mime == MEDIA_MIMETYPE_VIDEO_AVC) { 60556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd1; 60656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-1", &csd1)) { 60756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char avcc[1024]; // that oughta be enough, right? 60856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t outsize = reassembleAVCC(csd0, csd1, avcc); 60956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 61056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 61177f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) { 61256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 61356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char esds[csd0size + 31]; 61477f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo // The written ESDS is actually for an audio stream, but it's enough 61577f101b342b6d206b6f530991f3333dfedeebab6Martin Storsjo // for transporting the CSD to muxers. 61656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen reassembleESDS(csd0, esds); 61756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 61856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 61956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 62056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 6212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int32_t timeScale; 6222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (msg->findInt32("time-scale", &timeScale)) { 6232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang meta->setInt32(kKeyTimeScale, timeScale); 6242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 6252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 62656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // XXX TODO add whatever other keys there are 62756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 62856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0 62956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGI("converted %s to:", msg->debugString(0).c_str()); 63056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->dumpToLog(); 63156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif 63256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 63356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 634cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() { 635cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber AString ua; 636cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append("stagefright/1.2 (Linux;Android "); 637cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 638cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8) 639cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8" 640cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif 641cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 642cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber char value[PROPERTY_VALUE_MAX]; 643cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber property_get("ro.build.version.release", value, "Unknown"); 644cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(value); 645cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(")"); 646cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 647cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber return ua; 648cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber} 64956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 650ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, 651ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald const sp<MetaData>& meta) 652ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 65394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t sampleRate = 0; 65494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t bitRate = 0; 65594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelMask = 0; 65694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t delaySamples = 0; 65794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t paddingSamples = 0; 65894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 65994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald AudioParameter param = AudioParameter(); 66094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 66194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeySampleRate, &sampleRate)) { 66294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate); 66394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 66494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyChannelMask, &channelMask)) { 66594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask); 66694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 66794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyBitRate, &bitRate)) { 66894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate); 66994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 67094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) { 67194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples); 67294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 67394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) { 67494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples); 67594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 67694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 67794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d," 67894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald "delaySample %d, paddingSample %d", bitRate, sampleRate, 67994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald channelMask, delaySamples, paddingSamples); 68094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 68194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald sink->setParameters(param.toString()); 682ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return OK; 683ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 684ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 68594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t { 68694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char* mime; 68794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_format_t format; 68894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 68994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 69094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = { 69194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 }, 69294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT }, 69394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB }, 69494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB }, 69594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC }, 69694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, 697bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, 69894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { 0, AUDIO_FORMAT_INVALID } 69994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 70094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 70194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime ) 702ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 70394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0]; 70494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald while (p->mime != NULL) { 70594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (0 == strcasecmp(mime, p->mime)) { 70694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald format = p->format; 70794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return OK; 70894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 70994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ++p; 71094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 71194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 712ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return BAD_VALUE; 713ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 714ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 7152829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstruct aac_format_conv_t { 7162829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad OMX_AUDIO_AACPROFILETYPE eAacProfileType; 7172829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad audio_format_t format; 7182829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}; 7192829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 7202829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadstatic const struct aac_format_conv_t profileLookup[] = { 7212829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectMain, AUDIO_FORMAT_AAC_MAIN}, 7222829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLC, AUDIO_FORMAT_AAC_LC}, 7232829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectSSR, AUDIO_FORMAT_AAC_SSR}, 7242829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLTP, AUDIO_FORMAT_AAC_LTP}, 7252829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectHE, AUDIO_FORMAT_AAC_HE_V1}, 7262829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectScalable, AUDIO_FORMAT_AAC_SCALABLE}, 7272829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectERLC, AUDIO_FORMAT_AAC_ERLC}, 7282829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectLD, AUDIO_FORMAT_AAC_LD}, 7292829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectHE_PS, AUDIO_FORMAT_AAC_HE_V2}, 7302829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectELD, AUDIO_FORMAT_AAC_ELD}, 7312829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad { OMX_AUDIO_AACObjectNull, AUDIO_FORMAT_AAC}, 7322829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad}; 7332829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 7342829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadvoid mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile) 7352829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad{ 7362829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwadconst struct aac_format_conv_t* p = &profileLookup[0]; 7372829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) { 7382829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad if (eAacProfile == p->eAacProfileType) { 7392829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad format = p->format; 7402829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad return; 7412829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad } 7422829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad ++p; 7432829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad } 7442829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad format = AUDIO_FORMAT_AAC; 7452829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad return; 7462829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad} 7472829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad 74822612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, 74922612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent bool isStreaming, audio_stream_type_t streamType) 750ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 75194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char *mime; 752cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia if (meta == NULL) { 753cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia return false; 754cd249c40c51584e89e065bf7d51999b04db2eb57Wei Jia } 75594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald CHECK(meta->findCString(kKeyMIMEType, &mime)); 75694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 75794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_offload_info_t info = AUDIO_INFO_INITIALIZER; 75894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 75994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.format = AUDIO_FORMAT_INVALID; 76094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (mapMimeToAudioFormat(info.format, mime) != OK) { 76194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime); 76294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 76394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 76494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format); 76594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 76694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 76794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (AUDIO_FORMAT_INVALID == info.format) { 76894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // can't offload if we don't know what the source format is 76994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE("mime type \"%s\" not a known audio format", mime); 77094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 77194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 77294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 7732829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad // Redefine aac format according to its profile 7742829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad // Offloading depends on audio DSP capabilities. 775db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent int32_t aacaot = -1; 776db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent if (meta->findInt32(kKeyAACAOT, &aacaot)) { 7772829edccd7d2bb8244246f316face82b650b8949aarti jadhav-gaikwad mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot); 778db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent } 779db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 78094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t srate = -1; 78194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeySampleRate, &srate)) { 78294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish sample rate", mime); 78394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 78494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.sample_rate = srate; 78594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 78694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t cmask = 0; 78794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelMask, &cmask)) { 78894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel mask", mime); 78994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 79094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Try a channel count instead 79194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelCount; 79294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelCount, &channelCount)) { 79394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel count", mime); 79494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 79594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald cmask = audio_channel_out_mask_from_count(channelCount); 79694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 79794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 79894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.channel_mask = cmask; 79994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 80094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int64_t duration = 0; 80194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt64(kKeyDuration, &duration)) { 80294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish duration", mime); 80394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 80494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.duration_us = duration; 80594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 80694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t brate = -1; 80794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyBitRate, &brate)) { 80894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish bitrate", mime); 80994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 81094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.bit_rate = brate; 81194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 81294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 81322612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent info.stream_type = streamType; 81494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.has_video = hasVideo; 81594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.is_streaming = isStreaming; 81694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 81794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Check if offload is possible for given format, stream type, sample rate, 81894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // bit rate, duration, video and streaming 81994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return AudioSystem::isOffloadSupported(info); 820ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 821ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 822a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) { 823a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (incognito) { 824a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<URI suppressed>"); 825a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 826a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 827a1df816c0677185534babba6ffc29970b048e52eLajos Molnar char prop[PROPERTY_VALUE_MAX]; 828a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (property_get("media.stagefright.log-uri", prop, "false") && 829a1df816c0677185534babba6ffc29970b048e52eLajos Molnar (!strcmp(prop, "1") || !strcmp(prop, "true"))) { 830a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return uri; 831a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 832a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 833a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // find scheme 834a1df816c0677185534babba6ffc29970b048e52eLajos Molnar AString scheme; 835a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char *chars = uri.c_str(); 836a1df816c0677185534babba6ffc29970b048e52eLajos Molnar for (size_t i = 0; i < uri.size(); i++) { 837a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char c = chars[i]; 838a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (!isascii(c)) { 839a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 840a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isalpha(c)) { 841a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 842a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (i == 0) { 843a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // first character must be a letter 844a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 845a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 846a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 847a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (c != ':') { 848a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 849a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 850a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme = AString(uri, 0, i); 851a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme.append("://<suppressed>"); 852a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return scheme; 853a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 854a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<no-scheme URI suppressed>"); 855a1df816c0677185534babba6ffc29970b048e52eLajos Molnar} 856a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 857d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong ZhangHLSTime::HLSTime(const sp<AMessage>& meta) : 858d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mSeq(-1), 859d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mTimeUs(-1ll), 860d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mMeta(meta) { 861d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (meta != NULL) { 862d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(meta->findInt32("discontinuitySeq", &mSeq)); 863d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(meta->findInt64("timeUs", &mTimeUs)); 864d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 865d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 866d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 867978449984366946a2e5c9f7cf350746f4306caf8Chong Zhangint64_t HLSTime::getSegmentTimeUs() const { 868d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t segmentStartTimeUs = -1ll; 869d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (mMeta != NULL) { 870d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs)); 871978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 872978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t segmentFirstTimeUs; 873978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) { 874978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs += mTimeUs - segmentFirstTimeUs; 875978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang } 876978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 877978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang // adjust segment time by playlist age (for live streaming) 878978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t playlistTimeUs; 879978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) { 880978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs; 881978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 882d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t durationUs; 883d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang CHECK(mMeta->findInt64("segmentDurationUs", &durationUs)); 884978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 885978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang // round to nearest whole segment 886978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang playlistAgeUs = (playlistAgeUs + durationUs / 2) 887978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang / durationUs * durationUs; 888978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang 889978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs -= playlistAgeUs; 890978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang if (segmentStartTimeUs < 0) { 891978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang segmentStartTimeUs = 0; 892978449984366946a2e5c9f7cf350746f4306caf8Chong Zhang } 893d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 894d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 895d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang return segmentStartTimeUs; 896d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 897d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 898d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhangbool operator <(const HLSTime &t0, const HLSTime &t1) { 899d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // we can only compare discontinuity sequence and timestamp. 900d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // (mSegmentTimeUs is not reliable in live streaming case, it's the 901d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang // time starting from beginning of playlist but playlist could change.) 902d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang return t0.mSeq < t1.mSeq 903d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs); 904d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang} 905d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang 9063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) { 9073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("speed", rate.mSpeed); 9083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("pitch", rate.mPitch); 9093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-fallback-mode", rate.mFallbackMode); 9103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-stretch-mode", rate.mStretchMode); 9113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 9123a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 9133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) { 9143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *rate = AUDIO_PLAYBACK_RATE_DEFAULT; 9153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("speed", &rate->mSpeed)); 9163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("pitch", &rate->mPitch)); 9173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode)); 9183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode)); 9193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 9203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 9213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) { 9223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("sync-source", sync.mSource); 9233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode); 9243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("tolerance", sync.mTolerance); 9253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar msg->setFloat("video-fps", videoFpsHint); 9263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 9273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 9283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnarvoid readFromAMessage( 9293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar const sp<AMessage> &msg, 9303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings *sync /* nonnull */, 9313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar float *videoFps /* nonnull */) { 9323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar AVSyncSettings settings; 9333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource)); 9343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode)); 9353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("tolerance", &settings.mTolerance)); 9363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar CHECK(msg->findFloat("video-fps", videoFps)); 9373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar *sync = settings; 9383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar} 9393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar 94020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 94120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 942