Utils.cpp revision 3b5a6b9fa6c6825a1d0b441429e2bb365b259827
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> 269806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 279806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h> 289806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h> 299806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h> 3094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/stagefright/MediaDefs.h> 3194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioSystem.h> 3294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/MediaPlayerInterface.h> 3394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <hardware/audio.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald#include <media/AudioParameter.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) { 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 8 | ptr[1]; 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) { 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) { 52ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[0] | (ptr[1] << 8); 53ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 54ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 55ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) { 56ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 57ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 58ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 59ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) { 60ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr); 61ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 62ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host. 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) { 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) { 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 729806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage( 739806555d3930be43e11106281dee354820ac1c88Andreas Huber const sp<MetaData> &meta, sp<AMessage> *format) { 749806555d3930be43e11106281dee354820ac1c88Andreas Huber format->clear(); 759806555d3930be43e11106281dee354820ac1c88Andreas Huber 769806555d3930be43e11106281dee354820ac1c88Andreas Huber const char *mime; 779806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 789806555d3930be43e11106281dee354820ac1c88Andreas Huber 799806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<AMessage> msg = new AMessage; 809806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setString("mime", mime); 819806555d3930be43e11106281dee354820ac1c88Andreas Huber 829806555d3930be43e11106281dee354820ac1c88Andreas Huber int64_t durationUs; 839806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 849806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt64("durationUs", durationUs); 859806555d3930be43e11106281dee354820ac1c88Andreas Huber } 869806555d3930be43e11106281dee354820ac1c88Andreas Huber 878c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 888c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 898c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen msg->setInt32("is-sync-frame", 1); 908c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 918c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 929806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!strncasecmp("video/", mime, 6)) { 939806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t width, height; 949806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 959806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 969806555d3930be43e11106281dee354820ac1c88Andreas Huber 979806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("width", width); 989806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("height", height); 99516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 100516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 101516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (meta->findInt32(kKeySARWidth, &sarWidth) 102516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && meta->findInt32(kKeySARHeight, &sarHeight)) { 103516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-width", sarWidth); 104516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber msg->setInt32("sar-height", sarHeight); 105516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 1069806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 1079806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t numChannels, sampleRate; 1089806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 1099806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 1109806555d3930be43e11106281dee354820ac1c88Andreas Huber 1119806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-count", numChannels); 1129806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("sample-rate", sampleRate); 1139806555d3930be43e11106281dee354820ac1c88Andreas Huber 1149806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 1159806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1169806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-mask", channelMask); 1179806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1189806555d3930be43e11106281dee354820ac1c88Andreas Huber 1199806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t delay = 0; 1209806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1219806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-delay", delay); 1229806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1239806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t padding = 0; 1249806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1259806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-padding", padding); 1269806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1279806555d3930be43e11106281dee354820ac1c88Andreas Huber 1289806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t isADTS; 1299806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1309806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("is-adts", true); 1319806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1329806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1339806555d3930be43e11106281dee354820ac1c88Andreas Huber 1349806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t maxInputSize; 1359806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1369806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("max-input-size", maxInputSize); 1379806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1389806555d3930be43e11106281dee354820ac1c88Andreas Huber 1399806555d3930be43e11106281dee354820ac1c88Andreas Huber uint32_t type; 1409806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *data; 1419806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t size; 1429806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1439806555d3930be43e11106281dee354820ac1c88Andreas Huber // Parse the AVCDecoderConfigurationRecord 1449806555d3930be43e11106281dee354820ac1c88Andreas Huber 1459806555d3930be43e11106281dee354820ac1c88Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1469806555d3930be43e11106281dee354820ac1c88Andreas Huber 1479806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 7); 1489806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1499806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t profile = ptr[1]; 1509806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t level = ptr[3]; 1519806555d3930be43e11106281dee354820ac1c88Andreas Huber 1529806555d3930be43e11106281dee354820ac1c88Andreas Huber // There is decodable content out there that fails the following 1539806555d3930be43e11106281dee354820ac1c88Andreas Huber // assertion, let's be lenient for now... 1549806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 1559806555d3930be43e11106281dee354820ac1c88Andreas Huber 1569806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 1579806555d3930be43e11106281dee354820ac1c88Andreas Huber 1589806555d3930be43e11106281dee354820ac1c88Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 1599806555d3930be43e11106281dee354820ac1c88Andreas Huber // violates it... 1609806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 1619806555d3930be43e11106281dee354820ac1c88Andreas Huber 1629806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 1639806555d3930be43e11106281dee354820ac1c88Andreas Huber 1649806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 6; 1659806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 6; 1669806555d3930be43e11106281dee354820ac1c88Andreas Huber 1679806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 1689806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1699806555d3930be43e11106281dee354820ac1c88Andreas Huber 1709806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 1719806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 1729806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 1739806555d3930be43e11106281dee354820ac1c88Andreas Huber 1749806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 1759806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 1769806555d3930be43e11106281dee354820ac1c88Andreas Huber 1779806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 1789806555d3930be43e11106281dee354820ac1c88Andreas Huber 1799806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 1809806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 1819806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 1829806555d3930be43e11106281dee354820ac1c88Andreas Huber 1839806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 1849806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 1859806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1869806555d3930be43e11106281dee354820ac1c88Andreas Huber 1879806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 1889806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 1899806555d3930be43e11106281dee354820ac1c88Andreas Huber 1909806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 1919806555d3930be43e11106281dee354820ac1c88Andreas Huber 1929806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(1024); 1939806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1949806555d3930be43e11106281dee354820ac1c88Andreas Huber 1959806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 1); 1969806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numPictureParameterSets = *ptr; 1979806555d3930be43e11106281dee354820ac1c88Andreas Huber ++ptr; 1989806555d3930be43e11106281dee354820ac1c88Andreas Huber --size; 1999806555d3930be43e11106281dee354820ac1c88Andreas Huber 2009806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 2019806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 2029806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 2039806555d3930be43e11106281dee354820ac1c88Andreas Huber 2049806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 2059806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 2069806555d3930be43e11106281dee354820ac1c88Andreas Huber 2079806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 2089806555d3930be43e11106281dee354820ac1c88Andreas Huber 2099806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2109806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2119806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2129806555d3930be43e11106281dee354820ac1c88Andreas Huber 2139806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 2149806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 2159806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2169806555d3930be43e11106281dee354820ac1c88Andreas Huber 2179806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2189806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2199806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2203b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { 2213b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar const uint8_t *ptr = (const uint8_t *)data; 2223b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2233b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 7); 2243b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 2253b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint8_t profile = ptr[1] & 31; 2263b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar uint8_t level = ptr[12]; 2273b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 22; 2283b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 22; 2293b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2303b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2313b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofArrays = (char)ptr[0]; 2323b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 2333b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 2343b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t j = 0, i = 0; 2353b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2363b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar sp<ABuffer> buffer = new ABuffer(1024); 2373b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->setRange(0, 0); 2383b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2393b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (i = 0; i < numofArrays; i++) { 2403b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 1; 2413b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 1; 2423b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2433b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar //Num of nals 2443b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t numofNals = U16_AT(ptr); 2453b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2463b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 2473b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 2483b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2493b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar for (j = 0; j < numofNals; j++) { 2503b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= 2); 2513b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size_t length = U16_AT(ptr); 2523b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2533b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += 2; 2543b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= 2; 2553b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2563b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar CHECK(size >= length); 2573b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2583b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2593b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2603b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->setRange(0, buffer->size() + 4 + length); 2613b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2623b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar ptr += length; 2633b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar size -= length; 2643b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2653b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar } 2663b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt32("csd", true); 2673b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar buffer->meta()->setInt64("timeUs", 0); 2683b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar msg->setBuffer("csd-0", buffer); 2693b5a6b9fa6c6825a1d0b441429e2bb365b259827Harish Mahendrakar 2709806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 2719806555d3930be43e11106281dee354820ac1c88Andreas Huber ESDS esds((const char *)data, size); 2729806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 2739806555d3930be43e11106281dee354820ac1c88Andreas Huber 2749806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *codec_specific_data; 2759806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t codec_specific_data_size; 2769806555d3930be43e11106281dee354820ac1c88Andreas Huber esds.getCodecSpecificInfo( 2779806555d3930be43e11106281dee354820ac1c88Andreas Huber &codec_specific_data, &codec_specific_data_size); 2789806555d3930be43e11106281dee354820ac1c88Andreas Huber 2799806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 2809806555d3930be43e11106281dee354820ac1c88Andreas Huber 2819806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), codec_specific_data, 2829806555d3930be43e11106281dee354820ac1c88Andreas Huber codec_specific_data_size); 2839806555d3930be43e11106281dee354820ac1c88Andreas Huber 2849806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2859806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2869806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2879806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 2889806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 2899806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 2909806555d3930be43e11106281dee354820ac1c88Andreas Huber 2919806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2929806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2939806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2949806555d3930be43e11106281dee354820ac1c88Andreas Huber 2959806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 2969806555d3930be43e11106281dee354820ac1c88Andreas Huber return -EINVAL; 2979806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2989806555d3930be43e11106281dee354820ac1c88Andreas Huber 2999806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(size); 3009806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 3019806555d3930be43e11106281dee354820ac1c88Andreas Huber 3029806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 3039806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 3049806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 305bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) { 306bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian sp<ABuffer> buffer = new ABuffer(size); 307bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian memcpy(buffer->data(), data, size); 308bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian 309bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt32("csd", true); 310bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian buffer->meta()->setInt64("timeUs", 0); 311bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian msg->setBuffer("csd-0", buffer); 3129806555d3930be43e11106281dee354820ac1c88Andreas Huber } 3139806555d3930be43e11106281dee354820ac1c88Andreas Huber 3149806555d3930be43e11106281dee354820ac1c88Andreas Huber *format = msg; 3159806555d3930be43e11106281dee354820ac1c88Andreas Huber 3169806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 3179806555d3930be43e11106281dee354820ac1c88Andreas Huber} 3189806555d3930be43e11106281dee354820ac1c88Andreas Huber 31956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 32056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 32156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[0] = 1; // version 32256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[1] = 0x64; // profile 32356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[2] = 0; // unused (?) 32456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[3] = 0xd; // level 32556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[4] = 0xff; // reserved+size 32656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 32756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t i = 0; 32856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numparams = 0; 32956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int lastparamoffset = 0; 33056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int avccidx = 6; 33156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 33256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4 || 33356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 33456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd0->size() - 4) { 33556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 33656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd0->size(); 33756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 33856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("block at %d, last was %d", i, lastparamoffset); 33956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 34056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 34156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 34256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 34356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 34456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 34556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 34656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 34756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 34856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 34956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 35056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 35156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 35256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd0->size()); 35356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("csd0 contains %d params", numparams); 35456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 35556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[5] = 0xe0 | numparams; 35656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen //and now csd-1 35756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = 0; 35856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams = 0; 35956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = 0; 36056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int numpicparamsoffset = avccidx; 36156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx++; 36256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen do { 36356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4 || 36456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 36556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (i >= csd1->size() - 4) { 36656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // there can't be another param here, so use all the rest 36756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i = csd1->size(); 36856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 36956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGV("block at %d, last was %d", i, lastparamoffset); 37056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (lastparamoffset > 0) { 37156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int size = i - lastparamoffset; 37256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size >> 8; 37356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[avccidx++] = size & 0xff; 37456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 37556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avccidx += size; 37656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen numparams++; 37756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 37856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i += 4; 37956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen lastparamoffset = i; 38056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 38156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen i++; 38256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 38356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } while(i < csd1->size()); 38456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen avcc[numpicparamsoffset] = numparams; 38556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen return avccidx; 38656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 38756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 38856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 38956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 39056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[0] = 3; // kTag_ESDescriptor; 39156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int esdescriptorsize = 26 + csd0size; 39256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 39356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[1] = 0x80 | (esdescriptorsize >> 21); 39456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 39556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 39656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[4] = (esdescriptorsize & 0x7f); 39756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[5] = esds[6] = 0; // es id 39856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[7] = 0; // flags 39956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[8] = 4; // kTag_DecoderConfigDescriptor 40056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int configdescriptorsize = 18 + csd0size; 40156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[9] = 0x80 | (configdescriptorsize >> 21); 40256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 40356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 40456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[12] = (configdescriptorsize & 0x7f); 40556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[13] = 0x40; // objectTypeIndication 40656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 40756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[15] = 0x00; // but the actual values here were taken from a real file. 40856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[16] = 0x18; 40956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[17] = 0x00; 41056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[18] = 0x00; 41156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[19] = 0x00; 41256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[20] = 0xfa; 41356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[21] = 0x00; 41456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[22] = 0x00; 41556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[23] = 0x00; 41656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[24] = 0xfa; 41756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[25] = 0x00; 41856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[26] = 5; // kTag_DecoderSpecificInfo; 41956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[27] = 0x80 | (csd0size >> 21); 42056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 42156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 42256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen esds[30] = (csd0size & 0x7f); 42356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen memcpy((void*)&esds[31], csd0->data(), csd0size); 42456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // data following this is ignored, so don't bother appending it 42556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 42656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 42756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 42856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 42956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen AString mime; 43056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findString("mime", &mime)) { 43156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setCString(kKeyMIMEType, mime.c_str()); 43256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 43356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find mime type"); 43456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 43556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 43656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int64_t durationUs; 43756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt64("durationUs", &durationUs)) { 43856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt64(kKeyDuration, durationUs); 43956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 44056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 4418c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen int32_t isSync; 4428c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 4438c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen meta->setInt32(kKeyIsSyncFrame, 1); 4448c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen } 4458c95fa91fff6e8726df03598d52243f22e5ff8e7Marco Nelissen 44656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mime.startsWith("video/")) { 44756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t width; 44856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t height; 44956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 45056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyWidth, width); 45156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyHeight, height); 45256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else { 45356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGW("did not find width and/or height"); 45456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 455516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber 456516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber int32_t sarWidth, sarHeight; 457516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber if (msg->findInt32("sar-width", &sarWidth) 458516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber && msg->findInt32("sar-height", &sarHeight)) { 459516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARWidth, sarWidth); 460516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber meta->setInt32(kKeySARHeight, sarHeight); 461516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber } 46256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else if (mime.startsWith("audio/")) { 46356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t numChannels; 46456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-count", &numChannels)) { 46556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelCount, numChannels); 46656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 46756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t sampleRate; 46856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("sample-rate", &sampleRate)) { 46956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeySampleRate, sampleRate); 47056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 47156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t channelMask; 47256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("channel-mask", &channelMask)) { 47356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyChannelMask, channelMask); 47456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 47556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t delay = 0; 47656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-delay", &delay)) { 47756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderDelay, delay); 47856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 47956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t padding = 0; 48056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("encoder-padding", &padding)) { 48156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyEncoderPadding, padding); 48256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 48356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 48456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t isADTS; 48556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("is-adts", &isADTS)) { 48656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyIsADTS, isADTS); 48756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 48856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 48956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 49056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int32_t maxInputSize; 49156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findInt32("max-input-size", &maxInputSize)) { 49256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setInt32(kKeyMaxInputSize, maxInputSize); 49356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 49456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 49556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // reassemble the csd data into its original form 49656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd0; 49756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-0", &csd0)) { 49856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (mime.startsWith("video/")) { // do we need to be stricter than this? 49956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen sp<ABuffer> csd1; 50056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen if (msg->findBuffer("csd-1", &csd1)) { 50156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char avcc[1024]; // that oughta be enough, right? 50256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen size_t outsize = reassembleAVCC(csd0, csd1, avcc); 50356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 50456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 50556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } else if (mime.startsWith("audio/")) { 50656997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen int csd0size = csd0->size(); 50756997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen char esds[csd0size + 31]; 50856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen reassembleESDS(csd0, esds); 50956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 51056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 51156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen } 51256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 5132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang int32_t timeScale; 5142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang if (msg->findInt32("time-scale", &timeScale)) { 5152c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang meta->setInt32(kKeyTimeScale, timeScale); 5162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang } 5172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang 51856997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen // XXX TODO add whatever other keys there are 51956997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 52056997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#if 0 52156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen ALOGI("converted %s to:", msg->debugString(0).c_str()); 52256997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen meta->dumpToLog(); 52356997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen#endif 52456997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen} 52556997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 526cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas HuberAString MakeUserAgent() { 527cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber AString ua; 528cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append("stagefright/1.2 (Linux;Android "); 529cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 530cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#if (PROPERTY_VALUE_MAX < 8) 531cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#error "PROPERTY_VALUE_MAX must be at least 8" 532cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber#endif 533cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 534cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber char value[PROPERTY_VALUE_MAX]; 535cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber property_get("ro.build.version.release", value, "Unknown"); 536cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(value); 537cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber ua.append(")"); 538cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber 539cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber return ua; 540cd77d4a1d38b7609a03f6826a1ff5fa7c98aa34fAndreas Huber} 54156997121c5031598fbbba7b7c53980b7fd529c2dMarco Nelissen 542ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldstatus_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, 543ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald const sp<MetaData>& meta) 544ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 54594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t sampleRate = 0; 54694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t bitRate = 0; 54794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelMask = 0; 54894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t delaySamples = 0; 54994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t paddingSamples = 0; 55094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 55194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald AudioParameter param = AudioParameter(); 55294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 55394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeySampleRate, &sampleRate)) { 55494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate); 55594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 55694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyChannelMask, &channelMask)) { 55794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask); 55894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 55994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyBitRate, &bitRate)) { 56094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate); 56194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 56294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) { 56394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples); 56494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 56594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) { 56694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples); 56794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 56894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 56994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d," 57094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald "delaySample %d, paddingSample %d", bitRate, sampleRate, 57194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald channelMask, delaySamples, paddingSamples); 57294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 57394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald sink->setParameters(param.toString()); 574ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return OK; 575ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 576ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 57794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstruct mime_conv_t { 57894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char* mime; 57994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_format_t format; 58094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 58194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 58294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatic const struct mime_conv_t mimeLookup[] = { 58394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 }, 58494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT }, 58594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB }, 58694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB }, 58794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC }, 58894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS }, 589bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS}, 59094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald { 0, AUDIO_FORMAT_INVALID } 59194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald}; 59294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 59394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldstatus_t mapMimeToAudioFormat( audio_format_t& format, const char* mime ) 594ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 59594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgeraldconst struct mime_conv_t* p = &mimeLookup[0]; 59694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald while (p->mime != NULL) { 59794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (0 == strcasecmp(mime, p->mime)) { 59894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald format = p->format; 59994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return OK; 60094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 60194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ++p; 60294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 60394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 604ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald return BAD_VALUE; 605ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 606ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 60722612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurentbool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, 60822612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent bool isStreaming, audio_stream_type_t streamType) 609ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{ 61094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald const char *mime; 61194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald CHECK(meta->findCString(kKeyMIMEType, &mime)); 61294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 61394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald audio_offload_info_t info = AUDIO_INFO_INITIALIZER; 61494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 61594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.format = AUDIO_FORMAT_INVALID; 61694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (mapMimeToAudioFormat(info.format, mime) != OK) { 61794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime); 61894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 61994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 62094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format); 62194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 62294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 62394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (AUDIO_FORMAT_INVALID == info.format) { 62494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // can't offload if we don't know what the source format is 62594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGE("mime type \"%s\" not a known audio format", mime); 62694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return false; 62794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 62894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 629db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent // check whether it is ELD/LD content -> no offloading 630db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent // FIXME: this should depend on audio DSP capabilities. mapMimeToAudioFormat() should use the 631db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent // metadata to refine the AAC format and the audio HAL should only list supported profiles. 632db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent int32_t aacaot = -1; 633db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent if (meta->findInt32(kKeyAACAOT, &aacaot)) { 634db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent if (aacaot == 23 || aacaot == 39 ) { 635db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent ALOGV("track of type '%s' is ELD/LD content", mime); 636db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent return false; 637db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent } 638db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent } 639db170bb1cae145d07efc803a3c208963de0c6087Eric Laurent 64094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t srate = -1; 64194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeySampleRate, &srate)) { 64294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish sample rate", mime); 64394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 64494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.sample_rate = srate; 64594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 64694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t cmask = 0; 64794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelMask, &cmask)) { 64894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel mask", mime); 64994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 65094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Try a channel count instead 65194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t channelCount; 65294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyChannelCount, &channelCount)) { 65394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish channel count", mime); 65494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } else { 65594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald cmask = audio_channel_out_mask_from_count(channelCount); 65694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 65794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 65894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.channel_mask = cmask; 65994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 66094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int64_t duration = 0; 66194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt64(kKeyDuration, &duration)) { 66294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish duration", mime); 66394ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 66494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.duration_us = duration; 66594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 66694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald int32_t brate = -1; 66794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald if (!meta->findInt32(kKeyBitRate, &brate)) { 66894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald ALOGV("track of type '%s' does not publish bitrate", mime); 66994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald } 67094ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.bit_rate = brate; 67194ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 67294ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 67322612345ae97648d5b6db43cc1aa30aad77f7bbaEric Laurent info.stream_type = streamType; 67494ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.has_video = hasVideo; 67594ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald info.is_streaming = isStreaming; 67694ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald 67794ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // Check if offload is possible for given format, stream type, sample rate, 67894ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald // bit rate, duration, video and streaming 67994ea60f975c3eb7ce6d2a4430538a42a5fc3babdRichard Fitzgerald return AudioSystem::isOffloadSupported(info); 680ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald} 681ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald 682a1df816c0677185534babba6ffc29970b048e52eLajos MolnarAString uriDebugString(const AString &uri, bool incognito) { 683a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (incognito) { 684a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<URI suppressed>"); 685a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 686a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 687a1df816c0677185534babba6ffc29970b048e52eLajos Molnar char prop[PROPERTY_VALUE_MAX]; 688a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (property_get("media.stagefright.log-uri", prop, "false") && 689a1df816c0677185534babba6ffc29970b048e52eLajos Molnar (!strcmp(prop, "1") || !strcmp(prop, "true"))) { 690a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return uri; 691a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 692a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 693a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // find scheme 694a1df816c0677185534babba6ffc29970b048e52eLajos Molnar AString scheme; 695a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char *chars = uri.c_str(); 696a1df816c0677185534babba6ffc29970b048e52eLajos Molnar for (size_t i = 0; i < uri.size(); i++) { 697a1df816c0677185534babba6ffc29970b048e52eLajos Molnar const char c = chars[i]; 698a1df816c0677185534babba6ffc29970b048e52eLajos Molnar if (!isascii(c)) { 699a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 700a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isalpha(c)) { 701a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 702a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (i == 0) { 703a1df816c0677185534babba6ffc29970b048e52eLajos Molnar // first character must be a letter 704a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 705a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (isdigit(c) || c == '+' || c == '.' || c =='-') { 706a1df816c0677185534babba6ffc29970b048e52eLajos Molnar continue; 707a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } else if (c != ':') { 708a1df816c0677185534babba6ffc29970b048e52eLajos Molnar break; 709a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 710a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme = AString(uri, 0, i); 711a1df816c0677185534babba6ffc29970b048e52eLajos Molnar scheme.append("://<suppressed>"); 712a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return scheme; 713a1df816c0677185534babba6ffc29970b048e52eLajos Molnar } 714a1df816c0677185534babba6ffc29970b048e52eLajos Molnar return AString("<no-scheme URI suppressed>"); 715a1df816c0677185534babba6ffc29970b048e52eLajos Molnar} 716a1df816c0677185534babba6ffc29970b048e52eLajos Molnar 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 719