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 #include <cutils/properties.h> 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 int32_t isSync; 82 if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) { 83 msg->setInt32("is-sync-frame", 1); 84 } 85 86 if (!strncasecmp("video/", mime, 6)) { 87 int32_t width, height; 88 CHECK(meta->findInt32(kKeyWidth, &width)); 89 CHECK(meta->findInt32(kKeyHeight, &height)); 90 91 msg->setInt32("width", width); 92 msg->setInt32("height", height); 93 94 int32_t sarWidth, sarHeight; 95 if (meta->findInt32(kKeySARWidth, &sarWidth) 96 && meta->findInt32(kKeySARHeight, &sarHeight)) { 97 msg->setInt32("sar-width", sarWidth); 98 msg->setInt32("sar-height", sarHeight); 99 } 100 } else if (!strncasecmp("audio/", mime, 6)) { 101 int32_t numChannels, sampleRate; 102 CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); 103 CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); 104 105 msg->setInt32("channel-count", numChannels); 106 msg->setInt32("sample-rate", sampleRate); 107 108 int32_t channelMask; 109 if (meta->findInt32(kKeyChannelMask, &channelMask)) { 110 msg->setInt32("channel-mask", channelMask); 111 } 112 113 int32_t delay = 0; 114 if (meta->findInt32(kKeyEncoderDelay, &delay)) { 115 msg->setInt32("encoder-delay", delay); 116 } 117 int32_t padding = 0; 118 if (meta->findInt32(kKeyEncoderPadding, &padding)) { 119 msg->setInt32("encoder-padding", padding); 120 } 121 122 int32_t isADTS; 123 if (meta->findInt32(kKeyIsADTS, &isADTS)) { 124 msg->setInt32("is-adts", true); 125 } 126 } 127 128 int32_t maxInputSize; 129 if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) { 130 msg->setInt32("max-input-size", maxInputSize); 131 } 132 133 uint32_t type; 134 const void *data; 135 size_t size; 136 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 137 // Parse the AVCDecoderConfigurationRecord 138 139 const uint8_t *ptr = (const uint8_t *)data; 140 141 CHECK(size >= 7); 142 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 143 uint8_t profile = ptr[1]; 144 uint8_t level = ptr[3]; 145 146 // There is decodable content out there that fails the following 147 // assertion, let's be lenient for now... 148 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 149 150 size_t lengthSize = 1 + (ptr[4] & 3); 151 152 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 153 // violates it... 154 // CHECK((ptr[5] >> 5) == 7); // reserved 155 156 size_t numSeqParameterSets = ptr[5] & 31; 157 158 ptr += 6; 159 size -= 6; 160 161 sp<ABuffer> buffer = new ABuffer(1024); 162 buffer->setRange(0, 0); 163 164 for (size_t i = 0; i < numSeqParameterSets; ++i) { 165 CHECK(size >= 2); 166 size_t length = U16_AT(ptr); 167 168 ptr += 2; 169 size -= 2; 170 171 CHECK(size >= length); 172 173 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 174 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 175 buffer->setRange(0, buffer->size() + 4 + length); 176 177 ptr += length; 178 size -= length; 179 } 180 181 buffer->meta()->setInt32("csd", true); 182 buffer->meta()->setInt64("timeUs", 0); 183 184 msg->setBuffer("csd-0", buffer); 185 186 buffer = new ABuffer(1024); 187 buffer->setRange(0, 0); 188 189 CHECK(size >= 1); 190 size_t numPictureParameterSets = *ptr; 191 ++ptr; 192 --size; 193 194 for (size_t i = 0; i < numPictureParameterSets; ++i) { 195 CHECK(size >= 2); 196 size_t length = U16_AT(ptr); 197 198 ptr += 2; 199 size -= 2; 200 201 CHECK(size >= length); 202 203 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 204 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 205 buffer->setRange(0, buffer->size() + 4 + length); 206 207 ptr += length; 208 size -= length; 209 } 210 211 buffer->meta()->setInt32("csd", true); 212 buffer->meta()->setInt64("timeUs", 0); 213 msg->setBuffer("csd-1", buffer); 214 } else if (meta->findData(kKeyESDS, &type, &data, &size)) { 215 ESDS esds((const char *)data, size); 216 CHECK_EQ(esds.InitCheck(), (status_t)OK); 217 218 const void *codec_specific_data; 219 size_t codec_specific_data_size; 220 esds.getCodecSpecificInfo( 221 &codec_specific_data, &codec_specific_data_size); 222 223 sp<ABuffer> buffer = new ABuffer(codec_specific_data_size); 224 225 memcpy(buffer->data(), codec_specific_data, 226 codec_specific_data_size); 227 228 buffer->meta()->setInt32("csd", true); 229 buffer->meta()->setInt64("timeUs", 0); 230 msg->setBuffer("csd-0", buffer); 231 } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { 232 sp<ABuffer> buffer = new ABuffer(size); 233 memcpy(buffer->data(), data, size); 234 235 buffer->meta()->setInt32("csd", true); 236 buffer->meta()->setInt64("timeUs", 0); 237 msg->setBuffer("csd-0", buffer); 238 239 if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) { 240 return -EINVAL; 241 } 242 243 buffer = new ABuffer(size); 244 memcpy(buffer->data(), data, size); 245 246 buffer->meta()->setInt32("csd", true); 247 buffer->meta()->setInt64("timeUs", 0); 248 msg->setBuffer("csd-1", buffer); 249 } 250 251 *format = msg; 252 253 return OK; 254 } 255 256 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) { 257 258 avcc[0] = 1; // version 259 avcc[1] = 0x64; // profile 260 avcc[2] = 0; // unused (?) 261 avcc[3] = 0xd; // level 262 avcc[4] = 0xff; // reserved+size 263 264 size_t i = 0; 265 int numparams = 0; 266 int lastparamoffset = 0; 267 int avccidx = 6; 268 do { 269 if (i >= csd0->size() - 4 || 270 memcmp(csd0->data() + i, "\x00\x00\x00\x01", 4) == 0) { 271 if (i >= csd0->size() - 4) { 272 // there can't be another param here, so use all the rest 273 i = csd0->size(); 274 } 275 ALOGV("block at %d, last was %d", i, lastparamoffset); 276 if (lastparamoffset > 0) { 277 int size = i - lastparamoffset; 278 avcc[avccidx++] = size >> 8; 279 avcc[avccidx++] = size & 0xff; 280 memcpy(avcc+avccidx, csd0->data() + lastparamoffset, size); 281 avccidx += size; 282 numparams++; 283 } 284 i += 4; 285 lastparamoffset = i; 286 } else { 287 i++; 288 } 289 } while(i < csd0->size()); 290 ALOGV("csd0 contains %d params", numparams); 291 292 avcc[5] = 0xe0 | numparams; 293 //and now csd-1 294 i = 0; 295 numparams = 0; 296 lastparamoffset = 0; 297 int numpicparamsoffset = avccidx; 298 avccidx++; 299 do { 300 if (i >= csd1->size() - 4 || 301 memcmp(csd1->data() + i, "\x00\x00\x00\x01", 4) == 0) { 302 if (i >= csd1->size() - 4) { 303 // there can't be another param here, so use all the rest 304 i = csd1->size(); 305 } 306 ALOGV("block at %d, last was %d", i, lastparamoffset); 307 if (lastparamoffset > 0) { 308 int size = i - lastparamoffset; 309 avcc[avccidx++] = size >> 8; 310 avcc[avccidx++] = size & 0xff; 311 memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size); 312 avccidx += size; 313 numparams++; 314 } 315 i += 4; 316 lastparamoffset = i; 317 } else { 318 i++; 319 } 320 } while(i < csd1->size()); 321 avcc[numpicparamsoffset] = numparams; 322 return avccidx; 323 } 324 325 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) { 326 int csd0size = csd0->size(); 327 esds[0] = 3; // kTag_ESDescriptor; 328 int esdescriptorsize = 26 + csd0size; 329 CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1 330 esds[1] = 0x80 | (esdescriptorsize >> 21); 331 esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f); 332 esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f); 333 esds[4] = (esdescriptorsize & 0x7f); 334 esds[5] = esds[6] = 0; // es id 335 esds[7] = 0; // flags 336 esds[8] = 4; // kTag_DecoderConfigDescriptor 337 int configdescriptorsize = 18 + csd0size; 338 esds[9] = 0x80 | (configdescriptorsize >> 21); 339 esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f); 340 esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f); 341 esds[12] = (configdescriptorsize & 0x7f); 342 esds[13] = 0x40; // objectTypeIndication 343 esds[14] = 0x15; // not sure what 14-25 mean, they are ignored by ESDS.cpp, 344 esds[15] = 0x00; // but the actual values here were taken from a real file. 345 esds[16] = 0x18; 346 esds[17] = 0x00; 347 esds[18] = 0x00; 348 esds[19] = 0x00; 349 esds[20] = 0xfa; 350 esds[21] = 0x00; 351 esds[22] = 0x00; 352 esds[23] = 0x00; 353 esds[24] = 0xfa; 354 esds[25] = 0x00; 355 esds[26] = 5; // kTag_DecoderSpecificInfo; 356 esds[27] = 0x80 | (csd0size >> 21); 357 esds[28] = 0x80 | ((csd0size >> 14) & 0x7f); 358 esds[29] = 0x80 | ((csd0size >> 7) & 0x7f); 359 esds[30] = (csd0size & 0x7f); 360 memcpy((void*)&esds[31], csd0->data(), csd0size); 361 // data following this is ignored, so don't bother appending it 362 363 } 364 365 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { 366 AString mime; 367 if (msg->findString("mime", &mime)) { 368 meta->setCString(kKeyMIMEType, mime.c_str()); 369 } else { 370 ALOGW("did not find mime type"); 371 } 372 373 int64_t durationUs; 374 if (msg->findInt64("durationUs", &durationUs)) { 375 meta->setInt64(kKeyDuration, durationUs); 376 } 377 378 int32_t isSync; 379 if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) { 380 meta->setInt32(kKeyIsSyncFrame, 1); 381 } 382 383 if (mime.startsWith("video/")) { 384 int32_t width; 385 int32_t height; 386 if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) { 387 meta->setInt32(kKeyWidth, width); 388 meta->setInt32(kKeyHeight, height); 389 } else { 390 ALOGW("did not find width and/or height"); 391 } 392 393 int32_t sarWidth, sarHeight; 394 if (msg->findInt32("sar-width", &sarWidth) 395 && msg->findInt32("sar-height", &sarHeight)) { 396 meta->setInt32(kKeySARWidth, sarWidth); 397 meta->setInt32(kKeySARHeight, sarHeight); 398 } 399 } else if (mime.startsWith("audio/")) { 400 int32_t numChannels; 401 if (msg->findInt32("channel-count", &numChannels)) { 402 meta->setInt32(kKeyChannelCount, numChannels); 403 } 404 int32_t sampleRate; 405 if (msg->findInt32("sample-rate", &sampleRate)) { 406 meta->setInt32(kKeySampleRate, sampleRate); 407 } 408 int32_t channelMask; 409 if (msg->findInt32("channel-mask", &channelMask)) { 410 meta->setInt32(kKeyChannelMask, channelMask); 411 } 412 int32_t delay = 0; 413 if (msg->findInt32("encoder-delay", &delay)) { 414 meta->setInt32(kKeyEncoderDelay, delay); 415 } 416 int32_t padding = 0; 417 if (msg->findInt32("encoder-padding", &padding)) { 418 meta->setInt32(kKeyEncoderPadding, padding); 419 } 420 421 int32_t isADTS; 422 if (msg->findInt32("is-adts", &isADTS)) { 423 meta->setInt32(kKeyIsADTS, isADTS); 424 } 425 } 426 427 int32_t maxInputSize; 428 if (msg->findInt32("max-input-size", &maxInputSize)) { 429 meta->setInt32(kKeyMaxInputSize, maxInputSize); 430 } 431 432 // reassemble the csd data into its original form 433 sp<ABuffer> csd0; 434 if (msg->findBuffer("csd-0", &csd0)) { 435 if (mime.startsWith("video/")) { // do we need to be stricter than this? 436 sp<ABuffer> csd1; 437 if (msg->findBuffer("csd-1", &csd1)) { 438 char avcc[1024]; // that oughta be enough, right? 439 size_t outsize = reassembleAVCC(csd0, csd1, avcc); 440 meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize); 441 } 442 } else if (mime.startsWith("audio/")) { 443 int csd0size = csd0->size(); 444 char esds[csd0size + 31]; 445 reassembleESDS(csd0, esds); 446 meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds)); 447 } 448 } 449 450 // XXX TODO add whatever other keys there are 451 452 #if 0 453 ALOGI("converted %s to:", msg->debugString(0).c_str()); 454 meta->dumpToLog(); 455 #endif 456 } 457 458 AString MakeUserAgent() { 459 AString ua; 460 ua.append("stagefright/1.2 (Linux;Android "); 461 462 #if (PROPERTY_VALUE_MAX < 8) 463 #error "PROPERTY_VALUE_MAX must be at least 8" 464 #endif 465 466 char value[PROPERTY_VALUE_MAX]; 467 property_get("ro.build.version.release", value, "Unknown"); 468 ua.append(value); 469 ua.append(")"); 470 471 return ua; 472 } 473 474 } // namespace android 475 476