Utils.cpp revision 9806555d3930be43e11106281dee354820ac1c88
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> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 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 819806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!strncasecmp("video/", mime, 6)) { 829806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t width, height; 839806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyWidth, &width)); 849806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyHeight, &height)); 859806555d3930be43e11106281dee354820ac1c88Andreas Huber 869806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("width", width); 879806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("height", height); 889806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (!strncasecmp("audio/", mime, 6)) { 899806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t numChannels, sampleRate; 909806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 919806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 929806555d3930be43e11106281dee354820ac1c88Andreas Huber 939806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-count", numChannels); 949806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("sample-rate", sampleRate); 959806555d3930be43e11106281dee354820ac1c88Andreas Huber 969806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t channelMask; 979806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyChannelMask, &channelMask)) { 989806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("channel-mask", channelMask); 999806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1009806555d3930be43e11106281dee354820ac1c88Andreas Huber 1019806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t delay = 0; 1029806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderDelay, &delay)) { 1039806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-delay", delay); 1049806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1059806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t padding = 0; 1069806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyEncoderPadding, &padding)) { 1079806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("encoder-padding", padding); 1089806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1099806555d3930be43e11106281dee354820ac1c88Andreas Huber 1109806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t isADTS; 1119806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyIsADTS, &isADTS)) { 1129806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("is-adts", true); 1139806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1149806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1159806555d3930be43e11106281dee354820ac1c88Andreas Huber 1169806555d3930be43e11106281dee354820ac1c88Andreas Huber int32_t maxInputSize; 1179806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 1189806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setInt32("max-input-size", maxInputSize); 1199806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1209806555d3930be43e11106281dee354820ac1c88Andreas Huber 1219806555d3930be43e11106281dee354820ac1c88Andreas Huber uint32_t type; 1229806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *data; 1239806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t size; 1249806555d3930be43e11106281dee354820ac1c88Andreas Huber if (meta->findData(kKeyAVCC, &type, &data, &size)) { 1259806555d3930be43e11106281dee354820ac1c88Andreas Huber // Parse the AVCDecoderConfigurationRecord 1269806555d3930be43e11106281dee354820ac1c88Andreas Huber 1279806555d3930be43e11106281dee354820ac1c88Andreas Huber const uint8_t *ptr = (const uint8_t *)data; 1289806555d3930be43e11106281dee354820ac1c88Andreas Huber 1299806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 7); 1309806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1319806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t profile = ptr[1]; 1329806555d3930be43e11106281dee354820ac1c88Andreas Huber uint8_t level = ptr[3]; 1339806555d3930be43e11106281dee354820ac1c88Andreas Huber 1349806555d3930be43e11106281dee354820ac1c88Andreas Huber // There is decodable content out there that fails the following 1359806555d3930be43e11106281dee354820ac1c88Andreas Huber // assertion, let's be lenient for now... 1369806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[4] >> 2) == 0x3f); // reserved 1379806555d3930be43e11106281dee354820ac1c88Andreas Huber 1389806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t lengthSize = 1 + (ptr[4] & 3); 1399806555d3930be43e11106281dee354820ac1c88Andreas Huber 1409806555d3930be43e11106281dee354820ac1c88Andreas Huber // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 1419806555d3930be43e11106281dee354820ac1c88Andreas Huber // violates it... 1429806555d3930be43e11106281dee354820ac1c88Andreas Huber // CHECK((ptr[5] >> 5) == 7); // reserved 1439806555d3930be43e11106281dee354820ac1c88Andreas Huber 1449806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numSeqParameterSets = ptr[5] & 31; 1459806555d3930be43e11106281dee354820ac1c88Andreas Huber 1469806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 6; 1479806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 6; 1489806555d3930be43e11106281dee354820ac1c88Andreas Huber 1499806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(1024); 1509806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1519806555d3930be43e11106281dee354820ac1c88Andreas Huber 1529806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numSeqParameterSets; ++i) { 1539806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 1549806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 1559806555d3930be43e11106281dee354820ac1c88Andreas Huber 1569806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 1579806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 1589806555d3930be43e11106281dee354820ac1c88Andreas Huber 1599806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 1609806555d3930be43e11106281dee354820ac1c88Andreas Huber 1619806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 1629806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 1639806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 1649806555d3930be43e11106281dee354820ac1c88Andreas Huber 1659806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 1669806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 1679806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1689806555d3930be43e11106281dee354820ac1c88Andreas Huber 1699806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 1709806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 1719806555d3930be43e11106281dee354820ac1c88Andreas Huber 1729806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 1739806555d3930be43e11106281dee354820ac1c88Andreas Huber 1749806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(1024); 1759806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, 0); 1769806555d3930be43e11106281dee354820ac1c88Andreas Huber 1779806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 1); 1789806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t numPictureParameterSets = *ptr; 1799806555d3930be43e11106281dee354820ac1c88Andreas Huber ++ptr; 1809806555d3930be43e11106281dee354820ac1c88Andreas Huber --size; 1819806555d3930be43e11106281dee354820ac1c88Andreas Huber 1829806555d3930be43e11106281dee354820ac1c88Andreas Huber for (size_t i = 0; i < numPictureParameterSets; ++i) { 1839806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= 2); 1849806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t length = U16_AT(ptr); 1859806555d3930be43e11106281dee354820ac1c88Andreas Huber 1869806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += 2; 1879806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= 2; 1889806555d3930be43e11106281dee354820ac1c88Andreas Huber 1899806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK(size >= length); 1909806555d3930be43e11106281dee354820ac1c88Andreas Huber 1919806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 1929806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data() + buffer->size() + 4, ptr, length); 1939806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->setRange(0, buffer->size() + 4 + length); 1949806555d3930be43e11106281dee354820ac1c88Andreas Huber 1959806555d3930be43e11106281dee354820ac1c88Andreas Huber ptr += length; 1969806555d3930be43e11106281dee354820ac1c88Andreas Huber size -= length; 1979806555d3930be43e11106281dee354820ac1c88Andreas Huber } 1989806555d3930be43e11106281dee354820ac1c88Andreas Huber 1999806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2009806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2019806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2029806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 2039806555d3930be43e11106281dee354820ac1c88Andreas Huber ESDS esds((const char *)data, size); 2049806555d3930be43e11106281dee354820ac1c88Andreas Huber CHECK_EQ(esds.InitCheck(), (status_t)OK); 2059806555d3930be43e11106281dee354820ac1c88Andreas Huber 2069806555d3930be43e11106281dee354820ac1c88Andreas Huber const void *codec_specific_data; 2079806555d3930be43e11106281dee354820ac1c88Andreas Huber size_t codec_specific_data_size; 2089806555d3930be43e11106281dee354820ac1c88Andreas Huber esds.getCodecSpecificInfo( 2099806555d3930be43e11106281dee354820ac1c88Andreas Huber &codec_specific_data, &codec_specific_data_size); 2109806555d3930be43e11106281dee354820ac1c88Andreas Huber 2119806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 2129806555d3930be43e11106281dee354820ac1c88Andreas Huber 2139806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), codec_specific_data, 2149806555d3930be43e11106281dee354820ac1c88Andreas Huber codec_specific_data_size); 2159806555d3930be43e11106281dee354820ac1c88Andreas Huber 2169806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2179806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2189806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2199806555d3930be43e11106281dee354820ac1c88Andreas Huber } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 2209806555d3930be43e11106281dee354820ac1c88Andreas Huber sp<ABuffer> buffer = new ABuffer(size); 2219806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 2229806555d3930be43e11106281dee354820ac1c88Andreas Huber 2239806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2249806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2259806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-0", buffer); 2269806555d3930be43e11106281dee354820ac1c88Andreas Huber 2279806555d3930be43e11106281dee354820ac1c88Andreas Huber if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 2289806555d3930be43e11106281dee354820ac1c88Andreas Huber return -EINVAL; 2299806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2309806555d3930be43e11106281dee354820ac1c88Andreas Huber 2319806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer = new ABuffer(size); 2329806555d3930be43e11106281dee354820ac1c88Andreas Huber memcpy(buffer->data(), data, size); 2339806555d3930be43e11106281dee354820ac1c88Andreas Huber 2349806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt32("csd", true); 2359806555d3930be43e11106281dee354820ac1c88Andreas Huber buffer->meta()->setInt64("timeUs", 0); 2369806555d3930be43e11106281dee354820ac1c88Andreas Huber msg->setBuffer("csd-1", buffer); 2379806555d3930be43e11106281dee354820ac1c88Andreas Huber } 2389806555d3930be43e11106281dee354820ac1c88Andreas Huber 2399806555d3930be43e11106281dee354820ac1c88Andreas Huber *format = msg; 2409806555d3930be43e11106281dee354820ac1c88Andreas Huber 2419806555d3930be43e11106281dee354820ac1c88Andreas Huber return OK; 2429806555d3930be43e11106281dee354820ac1c88Andreas Huber} 2439806555d3930be43e11106281dee354820ac1c88Andreas Huber 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 246