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> 209806555d3930be43e11106281dee354820ac1c88Andreas Huber 219806555d3930be43e11106281dee354820ac1c88Andreas Huber#include "include/ESDS.h" 229806555d3930be43e11106281dee354820ac1c88Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 24190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber#include <cutils/properties.h> 259806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 269806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/ADebug.h> 279806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/foundation/AMessage.h> 289806555d3930be43e11106281dee354820ac1c88Andreas Huber#include <media/stagefright/MetaData.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint16_t U16_AT(const uint8_t *ptr) { 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 8 | ptr[1]; 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t U32_AT(const uint8_t *ptr) { 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t U64_AT(const uint8_t *ptr) { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint16_t U16LE_AT(const uint8_t *ptr) { 46ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[0] | (ptr[1] << 8); 47ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 48ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 49ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint32_t U32LE_AT(const uint8_t *ptr) { 50ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 51ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 52ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 53ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huberuint64_t U64LE_AT(const uint8_t *ptr) { 54ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr); 55ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber} 56ee7ff20e69498ebd53dd9717a0f984188341a75eAndreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX warning: these won't work on big-endian host. 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t ntoh64(uint64_t x) { 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint64_t hton64(uint64_t x) { 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 669806555d3930be43e11106281dee354820ac1c88Andreas Huberstatus_t convertMetaDataToMessage( 679806555d3930be43e11106281dee354820ac1c88Andreas Huber const sp<MetaData> &meta, sp<AMessage> *format) { 689806555d3930be43e11106281dee354820ac1c88Andreas Huber format->clear(); 699806555d3930be43e11106281dee354820ac1c88Andreas Huber 709806555d3930be43e11106281dee354820ac1c88Andreas Huber const char *mime; 719806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 729806555d3930be43e11106281dee354820ac1c88Andreas Huber 739806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<AMessage> msg = new AMessage; 749806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setString("mime", mime); 759806555d3930be43e11106281dee354820ac1c88Andreas Huber 769806555d3930be43e11106281dee354820ac1c88Andreas Huber int64_t durationUs; 779806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt64(kKeyDuration, &durationUs)) { 789806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt64("durationUs", durationUs); 799806555d3930be43e11106281dee354820ac1c88Andreas Huber } 809806555d3930be43e11106281dee354820ac1c88Andreas Huber 8175ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen int32_t isSync; 8275ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 8375ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen msg->setInt32("is-sync-frame", 1); 8475ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen } 8575ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen 869806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!strncasecmp("video/", mime, 6)) { 879806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t width, height; 889806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 899806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 909806555d3930be43e11106281dee354820ac1c88Andreas Huber 919806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("width", width); 929806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("height", height); 93e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber 94e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber int32_t sarWidth, sarHeight; 95e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber if (meta->findInt32(kKeySARWidth, &sarWidth) 96e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber && meta->findInt32(kKeySARHeight, &sarHeight)) { 97e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber msg->setInt32("sar-width", sarWidth); 98e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber msg->setInt32("sar-height", sarHeight); 99e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber } 1009806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 1019806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t numChannels, sampleRate; 1029806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 1039806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 1049806555d3930be43e11106281dee354820ac1c88Andreas Huber 1059806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-count", numChannels); 1069806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("sample-rate", sampleRate); 1079806555d3930be43e11106281dee354820ac1c88Andreas Huber 1089806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 1099806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyChannelMask, &channelMask)) { 1109806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-mask", channelMask); 1119806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1129806555d3930be43e11106281dee354820ac1c88Andreas Huber 1139806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t delay = 0; 1149806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1159806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-delay", delay); 1169806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1179806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t padding = 0; 1189806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1199806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-padding", padding); 1209806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1219806555d3930be43e11106281dee354820ac1c88Andreas Huber 1229806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t isADTS; 1239806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1249806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("is-adts", true); 1259806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1269806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1279806555d3930be43e11106281dee354820ac1c88Andreas Huber 1289806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t maxInputSize; 1299806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1309806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("max-input-size", maxInputSize); 1319806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1329806555d3930be43e11106281dee354820ac1c88Andreas Huber 1339806555d3930be43e11106281dee354820ac1c88Andreas Huber uint32_t type; 1349806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *data; 1359806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t size; 1369806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1379806555d3930be43e11106281dee354820ac1c88Andreas Huber // Parse the AVCDecoderConfigurationRecord 1389806555d3930be43e11106281dee354820ac1c88Andreas Huber 1399806555d3930be43e11106281dee354820ac1c88Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1409806555d3930be43e11106281dee354820ac1c88Andreas Huber 1419806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 7); 1429806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1439806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t profile = ptr[1]; 1449806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t level = ptr[3]; 1459806555d3930be43e11106281dee354820ac1c88Andreas Huber 1469806555d3930be43e11106281dee354820ac1c88Andreas Huber // There is decodable content out there that fails the following 1479806555d3930be43e11106281dee354820ac1c88Andreas Huber // assertion, let's be lenient for now... 1489806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 1499806555d3930be43e11106281dee354820ac1c88Andreas Huber 1509806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 1519806555d3930be43e11106281dee354820ac1c88Andreas Huber 1529806555d3930be43e11106281dee354820ac1c88Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 1539806555d3930be43e11106281dee354820ac1c88Andreas Huber // violates it... 1549806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 1559806555d3930be43e11106281dee354820ac1c88Andreas Huber 1569806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 1579806555d3930be43e11106281dee354820ac1c88Andreas Huber 1589806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 6; 1599806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 6; 1609806555d3930be43e11106281dee354820ac1c88Andreas Huber 1619806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 1629806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1639806555d3930be43e11106281dee354820ac1c88Andreas Huber 1649806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 1659806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 1669806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 1679806555d3930be43e11106281dee354820ac1c88Andreas Huber 1689806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 1699806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 1709806555d3930be43e11106281dee354820ac1c88Andreas Huber 1719806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 1729806555d3930be43e11106281dee354820ac1c88Andreas Huber 1739806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 1749806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 1759806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 1769806555d3930be43e11106281dee354820ac1c88Andreas Huber 1779806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 1789806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 1799806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1809806555d3930be43e11106281dee354820ac1c88Andreas Huber 1819806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 1829806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 1839806555d3930be43e11106281dee354820ac1c88Andreas Huber 1849806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 1859806555d3930be43e11106281dee354820ac1c88Andreas Huber 1869806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(1024); 1879806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1889806555d3930be43e11106281dee354820ac1c88Andreas Huber 1899806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 1); 1909806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numPictureParameterSets = *ptr; 1919806555d3930be43e11106281dee354820ac1c88Andreas Huber ++ptr; 1929806555d3930be43e11106281dee354820ac1c88Andreas Huber --size; 1939806555d3930be43e11106281dee354820ac1c88Andreas Huber 1949806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 1959806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 1969806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 1979806555d3930be43e11106281dee354820ac1c88Andreas Huber 1989806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 1999806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 2009806555d3930be43e11106281dee354820ac1c88Andreas Huber 2019806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 2029806555d3930be43e11106281dee354820ac1c88Andreas Huber 2039806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 2049806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 2059806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 2069806555d3930be43e11106281dee354820ac1c88Andreas Huber 2079806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 2089806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 2099806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2109806555d3930be43e11106281dee354820ac1c88Andreas Huber 2119806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2129806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2139806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2149806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 2159806555d3930be43e11106281dee354820ac1c88Andreas Huber ESDS esds((const char *)data, size); 2169806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 2179806555d3930be43e11106281dee354820ac1c88Andreas Huber 2189806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *codec_specific_data; 2199806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t codec_specific_data_size; 2209806555d3930be43e11106281dee354820ac1c88Andreas Huber esds.getCodecSpecificInfo( 2219806555d3930be43e11106281dee354820ac1c88Andreas Huber &codec_specific_data, &codec_specific_data_size); 2229806555d3930be43e11106281dee354820ac1c88Andreas Huber 2239806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 2249806555d3930be43e11106281dee354820ac1c88Andreas Huber 2259806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), codec_specific_data, 2269806555d3930be43e11106281dee354820ac1c88Andreas Huber codec_specific_data_size); 2279806555d3930be43e11106281dee354820ac1c88Andreas Huber 2289806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2299806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2309806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2319806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 2329806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 2339806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 2349806555d3930be43e11106281dee354820ac1c88Andreas Huber 2359806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2369806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2379806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2389806555d3930be43e11106281dee354820ac1c88Andreas Huber 2399806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 2409806555d3930be43e11106281dee354820ac1c88Andreas Huber return -EINVAL; 2419806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2429806555d3930be43e11106281dee354820ac1c88Andreas Huber 2439806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(size); 2449806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 2459806555d3930be43e11106281dee354820ac1c88Andreas Huber 2469806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2479806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2489806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2499806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2509806555d3930be43e11106281dee354820ac1c88Andreas Huber 2519806555d3930be43e11106281dee354820ac1c88Andreas Huber *format = msg; 2529806555d3930be43e11106281dee354820ac1c88Andreas Huber 2539806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 2549806555d3930be43e11106281dee354820ac1c88Andreas Huber} 2559806555d3930be43e11106281dee354820ac1c88Andreas Huber 2561e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissenstatic size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 2571e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 2581e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[0] = 1; // version 2591e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[1] = 0x64; // profile 2601e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[2] = 0; // unused (?) 2611e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[3] = 0xd; // level 2621e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[4] = 0xff; // reserved+size 2631e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 2641e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen size_t i = 0; 2651e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int numparams = 0; 2661e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int lastparamoffset = 0; 2671e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int avccidx = 6; 2681e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen do { 2691e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (i >= csd0->size() - 4 || 2701e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 2711e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (i >= csd0->size() - 4) { 2721e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen // there can't be another param here, so use all the rest 2731e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i = csd0->size(); 2741e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 2751e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGV("block at %d, last was %d", i, lastparamoffset); 2761e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (lastparamoffset > 0) { 2771e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int size = i - lastparamoffset; 2781e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[avccidx++] = size >> 8; 2791e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[avccidx++] = size & 0xff; 2801e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 2811e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avccidx += size; 2821e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen numparams++; 2831e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 2841e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i += 4; 2851e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen lastparamoffset = i; 2861e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else { 2871e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i++; 2881e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 2891e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } while(i < csd0->size()); 2901e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGV("csd0 contains %d params", numparams); 2911e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 2921e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[5] = 0xe0 | numparams; 2931e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen //and now csd-1 2941e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i = 0; 2951e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen numparams = 0; 2961e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen lastparamoffset = 0; 2971e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int numpicparamsoffset = avccidx; 2981e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avccidx++; 2991e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen do { 3001e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (i >= csd1->size() - 4 || 3011e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 3021e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (i >= csd1->size() - 4) { 3031e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen // there can't be another param here, so use all the rest 3041e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i = csd1->size(); 3051e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 3061e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGV("block at %d, last was %d", i, lastparamoffset); 3071e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (lastparamoffset > 0) { 3081e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int size = i - lastparamoffset; 3091e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[avccidx++] = size >> 8; 3101e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[avccidx++] = size & 0xff; 3111e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 3121e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avccidx += size; 3131e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen numparams++; 3141e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 3151e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i += 4; 3161e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen lastparamoffset = i; 3171e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else { 3181e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen i++; 3191e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 3201e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } while(i < csd1->size()); 3211e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen avcc[numpicparamsoffset] = numparams; 3221e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen return avccidx; 3231e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen} 3241e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 3251e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissenstatic void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 3261e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int csd0size = csd0->size(); 3271e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[0] = 3; // kTag_ESDescriptor; 3281e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int esdescriptorsize = 26 + csd0size; 3291e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 3301e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[1] = 0x80 | (esdescriptorsize >> 21); 3311e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 3321e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 3331e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[4] = (esdescriptorsize & 0x7f); 3341e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[5] = esds[6] = 0; // es id 3351e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[7] = 0; // flags 3361e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[8] = 4; // kTag_DecoderConfigDescriptor 3371e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int configdescriptorsize = 18 + csd0size; 3381e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[9] = 0x80 | (configdescriptorsize >> 21); 3391e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 3401e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 3411e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[12] = (configdescriptorsize & 0x7f); 3421e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[13] = 0x40; // objectTypeIndication 3431e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 3441e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[15] = 0x00; // but the actual values here were taken from a real file. 3451e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[16] = 0x18; 3461e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[17] = 0x00; 3471e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[18] = 0x00; 3481e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[19] = 0x00; 3491e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[20] = 0xfa; 3501e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[21] = 0x00; 3511e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[22] = 0x00; 3521e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[23] = 0x00; 3531e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[24] = 0xfa; 3541e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[25] = 0x00; 3551e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[26] = 5; // kTag_DecoderSpecificInfo; 3561e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[27] = 0x80 | (csd0size >> 21); 3571e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 3581e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 3591e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen esds[30] = (csd0size & 0x7f); 3601e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen memcpy((void*)&esds[31], csd0->data(), csd0size); 3611e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen // data following this is ignored, so don't bother appending it 3621e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 3631e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen} 3641e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 3651e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissenvoid convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 3661e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen AString mime; 3671e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findString("mime", &mime)) { 3681e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setCString(kKeyMIMEType, mime.c_str()); 3691e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else { 3701e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGW("did not find mime type"); 3711e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 3721e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 3731e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int64_t durationUs; 3741e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt64("durationUs", &durationUs)) { 3751e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt64(kKeyDuration, durationUs); 3761e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 3771e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 37875ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen int32_t isSync; 37975ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 38075ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen meta->setInt32(kKeyIsSyncFrame, 1); 38175ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen } 38275ce7656a2c0d2391b224e9c473e57b17ca23efbMarco Nelissen 3831e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (mime.startsWith("video/")) { 3841e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t width; 3851e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t height; 3861e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 3871e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyWidth, width); 3881e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyHeight, height); 3891e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else { 3901e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGW("did not find width and/or height"); 3911e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 392e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber 393e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber int32_t sarWidth, sarHeight; 394e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber if (msg->findInt32("sar-width", &sarWidth) 395e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber && msg->findInt32("sar-height", &sarHeight)) { 396e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber meta->setInt32(kKeySARWidth, sarWidth); 397e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber meta->setInt32(kKeySARHeight, sarHeight); 398e9810fae2ca6620337b75a787786cc0ea52adecdAndreas Huber } 3991e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else if (mime.startsWith("audio/")) { 4001e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t numChannels; 4011e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("channel-count", &numChannels)) { 4021e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyChannelCount, numChannels); 4031e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4041e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t sampleRate; 4051e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("sample-rate", &sampleRate)) { 4061e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeySampleRate, sampleRate); 4071e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4081e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t channelMask; 4091e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("channel-mask", &channelMask)) { 4101e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyChannelMask, channelMask); 4111e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4121e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t delay = 0; 4131e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("encoder-delay", &delay)) { 4141e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyEncoderDelay, delay); 4151e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4161e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t padding = 0; 4171e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("encoder-padding", &padding)) { 4181e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyEncoderPadding, padding); 4191e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4201e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 4211e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t isADTS; 4221e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("is-adts", &isADTS)) { 4231e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyIsADTS, isADTS); 4241e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4251e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4261e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 4271e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int32_t maxInputSize; 4281e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findInt32("max-input-size", &maxInputSize)) { 4291e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setInt32(kKeyMaxInputSize, maxInputSize); 4301e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4311e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 4321e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen // reassemble the csd data into its original form 4331e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen sp<ABuffer> csd0; 4341e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findBuffer("csd-0", &csd0)) { 4351e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (mime.startsWith("video/")) { // do we need to be stricter than this? 4361e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen sp<ABuffer> csd1; 4371e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen if (msg->findBuffer("csd-1", &csd1)) { 4381e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen char avcc[1024]; // that oughta be enough, right? 4391e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen size_t outsize = reassembleAVCC(csd0, csd1, avcc); 4401e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 4411e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4421e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } else if (mime.startsWith("audio/")) { 4431e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen int csd0size = csd0->size(); 4441e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen char esds[csd0size + 31]; 4451e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen reassembleESDS(csd0, esds); 4461e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 4471e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4481e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen } 4491e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 4501e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen // XXX TODO add whatever other keys there are 4511e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 4521e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen#if 0 4531e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen ALOGI("converted %s to:", msg->debugString(0).c_str()); 4541e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen meta->dumpToLog(); 4551e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen#endif 4561e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen} 4571e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 458190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas HuberAString MakeUserAgent() { 459190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber AString ua; 460190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber ua.append("stagefright/1.2 (Linux;Android "); 461190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber 462190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber#if (PROPERTY_VALUE_MAX < 8) 463190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber#error "PROPERTY_VALUE_MAX must be at least 8" 464190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber#endif 465190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber 466190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber char value[PROPERTY_VALUE_MAX]; 467190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber property_get("ro.build.version.release", value, "Unknown"); 468190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber ua.append(value); 469190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber ua.append(")"); 470190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber 471190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber return ua; 472190cdbab6ba24519d6b5e8bec6c2c74e6650e284Andreas Huber} 4731e9ee018c6fa906c99270616456c32f0bb30c9c0Marco Nelissen 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 476