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 31namespace android { 32 33uint16_t U16_AT(const uint8_t *ptr) { 34 return ptr[0] << 8 | ptr[1]; 35} 36 37uint32_t U32_AT(const uint8_t *ptr) { 38 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 39} 40 41uint64_t U64_AT(const uint8_t *ptr) { 42 return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4); 43} 44 45uint16_t U16LE_AT(const uint8_t *ptr) { 46 return ptr[0] | (ptr[1] << 8); 47} 48 49uint32_t U32LE_AT(const uint8_t *ptr) { 50 return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0]; 51} 52 53uint64_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. 58uint64_t ntoh64(uint64_t x) { 59 return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32); 60} 61 62uint64_t hton64(uint64_t x) { 63 return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32); 64} 65 66status_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 244static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 245 246 avcc[0] = 1; // version 247 avcc[1] = 0x64; // profile 248 avcc[2] = 0; // unused (?) 249 avcc[3] = 0xd; // level 250 avcc[4] = 0xff; // reserved+size 251 252 size_t i = 0; 253 int numparams = 0; 254 int lastparamoffset = 0; 255 int avccidx = 6; 256 do { 257 if (i >= csd0->size() - 4 || 258 memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 259 if (i >= csd0->size() - 4) { 260 // there can't be another param here, so use all the rest 261 i = csd0->size(); 262 } 263 ALOGV("block at %d, last was %d", i, lastparamoffset); 264 if (lastparamoffset > 0) { 265 int size = i - lastparamoffset; 266 avcc[avccidx++] = size >> 8; 267 avcc[avccidx++] = size & 0xff; 268 memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 269 avccidx += size; 270 numparams++; 271 } 272 i += 4; 273 lastparamoffset = i; 274 } else { 275 i++; 276 } 277 } while(i < csd0->size()); 278 ALOGV("csd0 contains %d params", numparams); 279 280 avcc[5] = 0xe0 | numparams; 281 //and now csd-1 282 i = 0; 283 numparams = 0; 284 lastparamoffset = 0; 285 int numpicparamsoffset = avccidx; 286 avccidx++; 287 do { 288 if (i >= csd1->size() - 4 || 289 memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 290 if (i >= csd1->size() - 4) { 291 // there can't be another param here, so use all the rest 292 i = csd1->size(); 293 } 294 ALOGV("block at %d, last was %d", i, lastparamoffset); 295 if (lastparamoffset > 0) { 296 int size = i - lastparamoffset; 297 avcc[avccidx++] = size >> 8; 298 avcc[avccidx++] = size & 0xff; 299 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 300 avccidx += size; 301 numparams++; 302 } 303 i += 4; 304 lastparamoffset = i; 305 } else { 306 i++; 307 } 308 } while(i < csd1->size()); 309 avcc[numpicparamsoffset] = numparams; 310 return avccidx; 311} 312 313static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 314 int csd0size = csd0->size(); 315 esds[0] = 3; // kTag_ESDescriptor; 316 int esdescriptorsize = 26 + csd0size; 317 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 318 esds[1] = 0x80 | (esdescriptorsize >> 21); 319 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 320 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 321 esds[4] = (esdescriptorsize & 0x7f); 322 esds[5] = esds[6] = 0; // es id 323 esds[7] = 0; // flags 324 esds[8] = 4; // kTag_DecoderConfigDescriptor 325 int configdescriptorsize = 18 + csd0size; 326 esds[9] = 0x80 | (configdescriptorsize >> 21); 327 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 328 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 329 esds[12] = (configdescriptorsize & 0x7f); 330 esds[13] = 0x40; // objectTypeIndication 331 esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 332 esds[15] = 0x00; // but the actual values here were taken from a real file. 333 esds[16] = 0x18; 334 esds[17] = 0x00; 335 esds[18] = 0x00; 336 esds[19] = 0x00; 337 esds[20] = 0xfa; 338 esds[21] = 0x00; 339 esds[22] = 0x00; 340 esds[23] = 0x00; 341 esds[24] = 0xfa; 342 esds[25] = 0x00; 343 esds[26] = 5; // kTag_DecoderSpecificInfo; 344 esds[27] = 0x80 | (csd0size >> 21); 345 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 346 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 347 esds[30] = (csd0size & 0x7f); 348 memcpy((void*)&esds[31], csd0->data(), csd0size); 349 // data following this is ignored, so don't bother appending it 350 351} 352 353void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 354 AString mime; 355 if (msg->findString("mime", &mime)) { 356 meta->setCString(kKeyMIMEType, mime.c_str()); 357 } else { 358 ALOGW("did not find mime type"); 359 } 360 361 int64_t durationUs; 362 if (msg->findInt64("durationUs", &durationUs)) { 363 meta->setInt64(kKeyDuration, durationUs); 364 } 365 366 if (mime.startsWith("video/")) { 367 int32_t width; 368 int32_t height; 369 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 370 meta->setInt32(kKeyWidth, width); 371 meta->setInt32(kKeyHeight, height); 372 } else { 373 ALOGW("did not find width and/or height"); 374 } 375 } else if (mime.startsWith("audio/")) { 376 int32_t numChannels; 377 if (msg->findInt32("channel-count", &numChannels)) { 378 meta->setInt32(kKeyChannelCount, numChannels); 379 } 380 int32_t sampleRate; 381 if (msg->findInt32("sample-rate", &sampleRate)) { 382 meta->setInt32(kKeySampleRate, sampleRate); 383 } 384 int32_t channelMask; 385 if (msg->findInt32("channel-mask", &channelMask)) { 386 meta->setInt32(kKeyChannelMask, channelMask); 387 } 388 int32_t delay = 0; 389 if (msg->findInt32("encoder-delay", &delay)) { 390 meta->setInt32(kKeyEncoderDelay, delay); 391 } 392 int32_t padding = 0; 393 if (msg->findInt32("encoder-padding", &padding)) { 394 meta->setInt32(kKeyEncoderPadding, padding); 395 } 396 397 int32_t isADTS; 398 if (msg->findInt32("is-adts", &isADTS)) { 399 meta->setInt32(kKeyIsADTS, isADTS); 400 } 401 } 402 403 int32_t maxInputSize; 404 if (msg->findInt32("max-input-size", &maxInputSize)) { 405 meta->setInt32(kKeyMaxInputSize, maxInputSize); 406 } 407 408 // reassemble the csd data into its original form 409 sp<ABuffer> csd0; 410 if (msg->findBuffer("csd-0", &csd0)) { 411 if (mime.startsWith("video/")) { // do we need to be stricter than this? 412 sp<ABuffer> csd1; 413 if (msg->findBuffer("csd-1", &csd1)) { 414 char avcc[1024]; // that oughta be enough, right? 415 size_t outsize = reassembleAVCC(csd0, csd1, avcc); 416 meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 417 } 418 } else if (mime.startsWith("audio/")) { 419 int csd0size = csd0->size(); 420 char esds[csd0size + 31]; 421 reassembleESDS(csd0, esds); 422 meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 423 } 424 } 425 426 // XXX TODO add whatever other keys there are 427 428#if 0 429 ALOGI("converted %s to:", msg->debugString(0).c_str()); 430 meta->dumpToLog(); 431#endif 432} 433 434 435} // namespace android 436 437