1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "Utils" 19 #include <utils/Log.h> 20 21 #include "include/ESDS.h" 22 23 #include <arpa/inet.h> 24 25 #include <media/stagefright/foundation/ABuffer.h> 26 #include <media/stagefright/foundation/ADebug.h> 27 #include <media/stagefright/foundation/AMessage.h> 28 #include <media/stagefright/MetaData.h> 29 #include <media/stagefright/Utils.h> 30 31 namespace android { 32 33 uint16_t U16_AT(const uint8_t *ptr) { 34 return ptr[0] << 8 | ptr[1]; 35 } 36 37 uint32_t U32_AT(const uint8_t *ptr) { 38 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 39 } 40 41 uint64_t U64_AT(const uint8_t *ptr) { 42 return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 43 } 44 45 uint16_t U16LE_AT(const uint8_t *ptr) { 46 return ptr[0] | (ptr[1] << 8); 47 } 48 49 uint32_t U32LE_AT(const uint8_t *ptr) { 50 return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 51 } 52 53 uint64_t U64LE_AT(const uint8_t *ptr) { 54 return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr); 55 } 56 57 // XXX warning: these won't work on big-endian host. 58 uint64_t ntoh64(uint64_t x) { 59 return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 60 } 61 62 uint64_t hton64(uint64_t x) { 63 return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 64 } 65 66 status_t convertMetaDataToMessage( 67 const sp<MetaData> &meta, sp<AMessage> *format) { 68 format->clear(); 69 70 const char *mime; 71 CHECK(meta->findCString(kKeyMIMEType, &mime)); 72 73 sp<AMessage> msg = new AMessage; 74 msg->setString("mime", mime); 75 76 int64_t durationUs; 77 if (meta->findInt64(kKeyDuration, &durationUs)) { 78 msg->setInt64("durationUs", durationUs); 79 } 80 81 if (!strncasecmp("video/", mime, 6)) { 82 int32_t width, height; 83 CHECK(meta->findInt32(kKeyWidth, &width)); 84 CHECK(meta->findInt32(kKeyHeight, &height)); 85 86 msg->setInt32("width", width); 87 msg->setInt32("height", height); 88 } else if (!strncasecmp("audio/", mime, 6)) { 89 int32_t numChannels, sampleRate; 90 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 91 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 92 93 msg->setInt32("channel-count", numChannels); 94 msg->setInt32("sample-rate", sampleRate); 95 96 int32_t channelMask; 97 if (meta->findInt32(kKeyChannelMask, &channelMask)) { 98 msg->setInt32("channel-mask", channelMask); 99 } 100 101 int32_t delay = 0; 102 if (meta->findInt32(kKeyEncoderDelay, &delay)) { 103 msg->setInt32("encoder-delay", delay); 104 } 105 int32_t padding = 0; 106 if (meta->findInt32(kKeyEncoderPadding, &padding)) { 107 msg->setInt32("encoder-padding", padding); 108 } 109 110 int32_t isADTS; 111 if (meta->findInt32(kKeyIsADTS, &isADTS)) { 112 msg->setInt32("is-adts", true); 113 } 114 } 115 116 int32_t maxInputSize; 117 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 118 msg->setInt32("max-input-size", maxInputSize); 119 } 120 121 uint32_t type; 122 const void *data; 123 size_t size; 124 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 125 // Parse the AVCDecoderConfigurationRecord 126 127 const uint8_t *ptr = (const uint8_t *)data; 128 129 CHECK(size >= 7); 130 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 131 uint8_t profile = ptr[1]; 132 uint8_t level = ptr[3]; 133 134 // There is decodable content out there that fails the following 135 // assertion, let's be lenient for now... 136 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 137 138 size_t lengthSize = 1 + (ptr[4] & 3); 139 140 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 141 // violates it... 142 // CHECK((ptr[5] >> 5) == 7); // reserved 143 144 size_t numSeqParameterSets = ptr[5] & 31; 145 146 ptr += 6; 147 size -= 6; 148 149 sp<ABuffer> buffer = new ABuffer(1024); 150 buffer->setRange(0, 0); 151 152 for (size_t i = 0; i < numSeqParameterSets; ++i) { 153 CHECK(size >= 2); 154 size_t length = U16_AT(ptr); 155 156 ptr += 2; 157 size -= 2; 158 159 CHECK(size >= length); 160 161 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 162 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 163 buffer->setRange(0, buffer->size() + 4 + length); 164 165 ptr += length; 166 size -= length; 167 } 168 169 buffer->meta()->setInt32("csd", true); 170 buffer->meta()->setInt64("timeUs", 0); 171 172 msg->setBuffer("csd-0", buffer); 173 174 buffer = new ABuffer(1024); 175 buffer->setRange(0, 0); 176 177 CHECK(size >= 1); 178 size_t numPictureParameterSets = *ptr; 179 ++ptr; 180 --size; 181 182 for (size_t i = 0; i < numPictureParameterSets; ++i) { 183 CHECK(size >= 2); 184 size_t length = U16_AT(ptr); 185 186 ptr += 2; 187 size -= 2; 188 189 CHECK(size >= length); 190 191 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 192 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 193 buffer->setRange(0, buffer->size() + 4 + length); 194 195 ptr += length; 196 size -= length; 197 } 198 199 buffer->meta()->setInt32("csd", true); 200 buffer->meta()->setInt64("timeUs", 0); 201 msg->setBuffer("csd-1", buffer); 202 } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 203 ESDS esds((const char *)data, size); 204 CHECK_EQ(esds.InitCheck(), (status_t)OK); 205 206 const void *codec_specific_data; 207 size_t codec_specific_data_size; 208 esds.getCodecSpecificInfo( 209 &codec_specific_data, &codec_specific_data_size); 210 211 sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 212 213 memcpy(buffer->data(), codec_specific_data, 214 codec_specific_data_size); 215 216 buffer->meta()->setInt32("csd", true); 217 buffer->meta()->setInt64("timeUs", 0); 218 msg->setBuffer("csd-0", buffer); 219 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 220 sp<ABuffer> buffer = new ABuffer(size); 221 memcpy(buffer->data(), data, size); 222 223 buffer->meta()->setInt32("csd", true); 224 buffer->meta()->setInt64("timeUs", 0); 225 msg->setBuffer("csd-0", buffer); 226 227 if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 228 return -EINVAL; 229 } 230 231 buffer = new ABuffer(size); 232 memcpy(buffer->data(), data, size); 233 234 buffer->meta()->setInt32("csd", true); 235 buffer->meta()->setInt64("timeUs", 0); 236 msg->setBuffer("csd-1", buffer); 237 } 238 239 *format = msg; 240 241 return OK; 242 } 243 244 } // namespace android 245 246