MPEG4Extractor.cpp revision 5d2f8ba30c24ea597d54468cda01c7ec5f6a0e66
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_TAG "MPEG4Extractor" 18#include <utils/Log.h> 19 20#include "include/MPEG4Extractor.h" 21#include "include/SampleTable.h" 22#include "include/ESDS.h" 23 24#include <arpa/inet.h> 25 26#include <ctype.h> 27#include <stdint.h> 28#include <stdlib.h> 29#include <string.h> 30 31#include <media/stagefright/foundation/ADebug.h> 32#include <media/stagefright/foundation/AMessage.h> 33#include <media/stagefright/DataSource.h> 34#include <media/stagefright/MediaBuffer.h> 35#include <media/stagefright/MediaBufferGroup.h> 36#include <media/stagefright/MediaDefs.h> 37#include <media/stagefright/MediaSource.h> 38#include <media/stagefright/MetaData.h> 39#include <media/stagefright/Utils.h> 40#include <utils/String8.h> 41 42namespace android { 43 44class MPEG4Source : public MediaSource { 45public: 46 // Caller retains ownership of both "dataSource" and "sampleTable". 47 MPEG4Source(const sp<MetaData> &format, 48 const sp<DataSource> &dataSource, 49 int32_t timeScale, 50 const sp<SampleTable> &sampleTable); 51 52 virtual status_t start(MetaData *params = NULL); 53 virtual status_t stop(); 54 55 virtual sp<MetaData> getFormat(); 56 57 virtual status_t read( 58 MediaBuffer **buffer, const ReadOptions *options = NULL); 59 60protected: 61 virtual ~MPEG4Source(); 62 63private: 64 Mutex mLock; 65 66 sp<MetaData> mFormat; 67 sp<DataSource> mDataSource; 68 int32_t mTimescale; 69 sp<SampleTable> mSampleTable; 70 uint32_t mCurrentSampleIndex; 71 72 bool mIsAVC; 73 size_t mNALLengthSize; 74 75 bool mStarted; 76 77 MediaBufferGroup *mGroup; 78 79 MediaBuffer *mBuffer; 80 81 bool mWantsNALFragments; 82 83 uint8_t *mSrcBuffer; 84 85 size_t parseNALSize(const uint8_t *data) const; 86 87 MPEG4Source(const MPEG4Source &); 88 MPEG4Source &operator=(const MPEG4Source &); 89}; 90 91// This custom data source wraps an existing one and satisfies requests 92// falling entirely within a cached range from the cache while forwarding 93// all remaining requests to the wrapped datasource. 94// This is used to cache the full sampletable metadata for a single track, 95// possibly wrapping multiple times to cover all tracks, i.e. 96// Each MPEG4DataSource caches the sampletable metadata for a single track. 97 98struct MPEG4DataSource : public DataSource { 99 MPEG4DataSource(const sp<DataSource> &source); 100 101 virtual status_t initCheck() const; 102 virtual ssize_t readAt(off64_t offset, void *data, size_t size); 103 virtual status_t getSize(off64_t *size); 104 virtual uint32_t flags(); 105 106 status_t setCachedRange(off64_t offset, size_t size); 107 108protected: 109 virtual ~MPEG4DataSource(); 110 111private: 112 Mutex mLock; 113 114 sp<DataSource> mSource; 115 off64_t mCachedOffset; 116 size_t mCachedSize; 117 uint8_t *mCache; 118 119 void clearCache(); 120 121 MPEG4DataSource(const MPEG4DataSource &); 122 MPEG4DataSource &operator=(const MPEG4DataSource &); 123}; 124 125MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 126 : mSource(source), 127 mCachedOffset(0), 128 mCachedSize(0), 129 mCache(NULL) { 130} 131 132MPEG4DataSource::~MPEG4DataSource() { 133 clearCache(); 134} 135 136void MPEG4DataSource::clearCache() { 137 if (mCache) { 138 free(mCache); 139 mCache = NULL; 140 } 141 142 mCachedOffset = 0; 143 mCachedSize = 0; 144} 145 146status_t MPEG4DataSource::initCheck() const { 147 return mSource->initCheck(); 148} 149 150ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 151 Mutex::Autolock autoLock(mLock); 152 153 if (offset >= mCachedOffset 154 && offset + size <= mCachedOffset + mCachedSize) { 155 memcpy(data, &mCache[offset - mCachedOffset], size); 156 return size; 157 } 158 159 return mSource->readAt(offset, data, size); 160} 161 162status_t MPEG4DataSource::getSize(off64_t *size) { 163 return mSource->getSize(size); 164} 165 166uint32_t MPEG4DataSource::flags() { 167 return mSource->flags(); 168} 169 170status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 171 Mutex::Autolock autoLock(mLock); 172 173 clearCache(); 174 175 mCache = (uint8_t *)malloc(size); 176 177 if (mCache == NULL) { 178 return -ENOMEM; 179 } 180 181 mCachedOffset = offset; 182 mCachedSize = size; 183 184 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 185 186 if (err < (ssize_t)size) { 187 clearCache(); 188 189 return ERROR_IO; 190 } 191 192 return OK; 193} 194 195//////////////////////////////////////////////////////////////////////////////// 196 197static void hexdump(const void *_data, size_t size) { 198 const uint8_t *data = (const uint8_t *)_data; 199 size_t offset = 0; 200 while (offset < size) { 201 printf("0x%04x ", offset); 202 203 size_t n = size - offset; 204 if (n > 16) { 205 n = 16; 206 } 207 208 for (size_t i = 0; i < 16; ++i) { 209 if (i == 8) { 210 printf(" "); 211 } 212 213 if (offset + i < size) { 214 printf("%02x ", data[offset + i]); 215 } else { 216 printf(" "); 217 } 218 } 219 220 printf(" "); 221 222 for (size_t i = 0; i < n; ++i) { 223 if (isprint(data[offset + i])) { 224 printf("%c", data[offset + i]); 225 } else { 226 printf("."); 227 } 228 } 229 230 printf("\n"); 231 232 offset += 16; 233 } 234} 235 236static const char *FourCC2MIME(uint32_t fourcc) { 237 switch (fourcc) { 238 case FOURCC('m', 'p', '4', 'a'): 239 return MEDIA_MIMETYPE_AUDIO_AAC; 240 241 case FOURCC('s', 'a', 'm', 'r'): 242 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 243 244 case FOURCC('s', 'a', 'w', 'b'): 245 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 246 247 case FOURCC('m', 'p', '4', 'v'): 248 return MEDIA_MIMETYPE_VIDEO_MPEG4; 249 250 case FOURCC('s', '2', '6', '3'): 251 case FOURCC('h', '2', '6', '3'): 252 case FOURCC('H', '2', '6', '3'): 253 return MEDIA_MIMETYPE_VIDEO_H263; 254 255 case FOURCC('a', 'v', 'c', '1'): 256 return MEDIA_MIMETYPE_VIDEO_AVC; 257 258 default: 259 CHECK(!"should not be here."); 260 return NULL; 261 } 262} 263 264MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 265 : mDataSource(source), 266 mInitCheck(NO_INIT), 267 mHasVideo(false), 268 mFirstTrack(NULL), 269 mLastTrack(NULL), 270 mFileMetaData(new MetaData), 271 mFirstSINF(NULL), 272 mIsDrm(false) { 273} 274 275MPEG4Extractor::~MPEG4Extractor() { 276 Track *track = mFirstTrack; 277 while (track) { 278 Track *next = track->next; 279 280 delete track; 281 track = next; 282 } 283 mFirstTrack = mLastTrack = NULL; 284 285 SINF *sinf = mFirstSINF; 286 while (sinf) { 287 SINF *next = sinf->next; 288 delete sinf->IPMPData; 289 delete sinf; 290 sinf = next; 291 } 292 mFirstSINF = NULL; 293} 294 295sp<MetaData> MPEG4Extractor::getMetaData() { 296 status_t err; 297 if ((err = readMetaData()) != OK) { 298 return new MetaData; 299 } 300 301 return mFileMetaData; 302} 303 304size_t MPEG4Extractor::countTracks() { 305 status_t err; 306 if ((err = readMetaData()) != OK) { 307 return 0; 308 } 309 310 size_t n = 0; 311 Track *track = mFirstTrack; 312 while (track) { 313 ++n; 314 track = track->next; 315 } 316 317 return n; 318} 319 320sp<MetaData> MPEG4Extractor::getTrackMetaData( 321 size_t index, uint32_t flags) { 322 status_t err; 323 if ((err = readMetaData()) != OK) { 324 return NULL; 325 } 326 327 Track *track = mFirstTrack; 328 while (index > 0) { 329 if (track == NULL) { 330 return NULL; 331 } 332 333 track = track->next; 334 --index; 335 } 336 337 if (track == NULL) { 338 return NULL; 339 } 340 341 if ((flags & kIncludeExtensiveMetaData) 342 && !track->includes_expensive_metadata) { 343 track->includes_expensive_metadata = true; 344 345 const char *mime; 346 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 347 if (!strncasecmp("video/", mime, 6)) { 348 uint32_t sampleIndex; 349 uint32_t sampleTime; 350 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 351 && track->sampleTable->getMetaDataForSample( 352 sampleIndex, NULL /* offset */, NULL /* size */, 353 &sampleTime) == OK) { 354 track->meta->setInt64( 355 kKeyThumbnailTime, 356 ((int64_t)sampleTime * 1000000) / track->timescale); 357 } 358 } 359 } 360 361 return track->meta; 362} 363 364status_t MPEG4Extractor::readMetaData() { 365 if (mInitCheck != NO_INIT) { 366 return mInitCheck; 367 } 368 369 off64_t offset = 0; 370 status_t err; 371 while ((err = parseChunk(&offset, 0)) == OK) { 372 } 373 374 if (mInitCheck == OK) { 375 if (mHasVideo) { 376 mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 377 } else { 378 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 379 } 380 381 mInitCheck = OK; 382 } else { 383 mInitCheck = err; 384 } 385 386 CHECK_NE(err, (status_t)NO_INIT); 387 return mInitCheck; 388} 389 390char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 391 if (mFirstSINF == NULL) { 392 return NULL; 393 } 394 395 SINF *sinf = mFirstSINF; 396 while (sinf && (trackID != sinf->trackID)) { 397 sinf = sinf->next; 398 } 399 400 if (sinf == NULL) { 401 return NULL; 402 } 403 404 *len = sinf->len; 405 return sinf->IPMPData; 406} 407 408// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 409int32_t readSize(off64_t offset, 410 const sp<DataSource> DataSource, uint8_t *numOfBytes) { 411 uint32_t size = 0; 412 uint8_t data; 413 bool moreData = true; 414 *numOfBytes = 0; 415 416 while (moreData) { 417 if (DataSource->readAt(offset, &data, 1) < 1) { 418 return -1; 419 } 420 offset ++; 421 moreData = (data >= 128) ? true : false; 422 size = (size << 7) | (data & 0x7f); // Take last 7 bits 423 (*numOfBytes) ++; 424 } 425 426 return size; 427} 428 429status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 430 uint8_t updateIdTag; 431 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 432 return ERROR_IO; 433 } 434 data_offset ++; 435 436 if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 437 return ERROR_MALFORMED; 438 } 439 440 uint8_t numOfBytes; 441 int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 442 if (size < 0) { 443 return ERROR_IO; 444 } 445 int32_t classSize = size; 446 data_offset += numOfBytes; 447 448 while(size >= 11 ) { 449 uint8_t descriptorTag; 450 if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 451 return ERROR_IO; 452 } 453 data_offset ++; 454 455 if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 456 return ERROR_MALFORMED; 457 } 458 459 uint8_t buffer[8]; 460 //ObjectDescriptorID and ObjectDescriptor url flag 461 if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 462 return ERROR_IO; 463 } 464 data_offset += 2; 465 466 if ((buffer[1] >> 5) & 0x0001) { //url flag is set 467 return ERROR_MALFORMED; 468 } 469 470 if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 471 return ERROR_IO; 472 } 473 data_offset += 8; 474 475 if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 476 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 477 return ERROR_MALFORMED; 478 } 479 480 SINF *sinf = new SINF; 481 sinf->trackID = U16_AT(&buffer[3]); 482 sinf->IPMPDescriptorID = buffer[7]; 483 sinf->next = mFirstSINF; 484 mFirstSINF = sinf; 485 486 size -= (8 + 2 + 1); 487 } 488 489 if (size != 0) { 490 return ERROR_MALFORMED; 491 } 492 493 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 494 return ERROR_IO; 495 } 496 data_offset ++; 497 498 if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 499 return ERROR_MALFORMED; 500 } 501 502 size = readSize(data_offset, mDataSource, &numOfBytes); 503 if (size < 0) { 504 return ERROR_IO; 505 } 506 classSize = size; 507 data_offset += numOfBytes; 508 509 while (size > 0) { 510 uint8_t tag; 511 int32_t dataLen; 512 if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 513 return ERROR_IO; 514 } 515 data_offset ++; 516 517 if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 518 uint8_t id; 519 dataLen = readSize(data_offset, mDataSource, &numOfBytes); 520 if (dataLen < 0) { 521 return ERROR_IO; 522 } else if (dataLen < 4) { 523 return ERROR_MALFORMED; 524 } 525 data_offset += numOfBytes; 526 527 if (mDataSource->readAt(data_offset, &id, 1) < 1) { 528 return ERROR_IO; 529 } 530 data_offset ++; 531 532 SINF *sinf = mFirstSINF; 533 while (sinf && (sinf->IPMPDescriptorID != id)) { 534 sinf = sinf->next; 535 } 536 if (sinf == NULL) { 537 return ERROR_MALFORMED; 538 } 539 sinf->len = dataLen - 3; 540 sinf->IPMPData = new char[sinf->len]; 541 542 if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 543 return ERROR_IO; 544 } 545 data_offset += sinf->len; 546 547 size -= (dataLen + numOfBytes + 1); 548 } 549 } 550 551 if (size != 0) { 552 return ERROR_MALFORMED; 553 } 554 555 return UNKNOWN_ERROR; // Return a dummy error. 556} 557 558static void MakeFourCCString(uint32_t x, char *s) { 559 s[0] = x >> 24; 560 s[1] = (x >> 16) & 0xff; 561 s[2] = (x >> 8) & 0xff; 562 s[3] = x & 0xff; 563 s[4] = '\0'; 564} 565 566struct PathAdder { 567 PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 568 : mPath(path) { 569 mPath->push(chunkType); 570 } 571 572 ~PathAdder() { 573 mPath->pop(); 574 } 575 576private: 577 Vector<uint32_t> *mPath; 578 579 PathAdder(const PathAdder &); 580 PathAdder &operator=(const PathAdder &); 581}; 582 583static bool underMetaDataPath(const Vector<uint32_t> &path) { 584 return path.size() >= 5 585 && path[0] == FOURCC('m', 'o', 'o', 'v') 586 && path[1] == FOURCC('u', 'd', 't', 'a') 587 && path[2] == FOURCC('m', 'e', 't', 'a') 588 && path[3] == FOURCC('i', 'l', 's', 't'); 589} 590 591// Given a time in seconds since Jan 1 1904, produce a human-readable string. 592static void convertTimeToDate(int64_t time_1904, String8 *s) { 593 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 594 595 char tmp[32]; 596 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 597 598 s->setTo(tmp); 599} 600 601status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 602 ALOGV("entering parseChunk %lld/%d", *offset, depth); 603 uint32_t hdr[2]; 604 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 605 return ERROR_IO; 606 } 607 uint64_t chunk_size = ntohl(hdr[0]); 608 uint32_t chunk_type = ntohl(hdr[1]); 609 off64_t data_offset = *offset + 8; 610 611 if (chunk_size == 1) { 612 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 613 return ERROR_IO; 614 } 615 chunk_size = ntoh64(chunk_size); 616 data_offset += 8; 617 618 if (chunk_size < 16) { 619 // The smallest valid chunk is 16 bytes long in this case. 620 return ERROR_MALFORMED; 621 } 622 } else if (chunk_size < 8) { 623 // The smallest valid chunk is 8 bytes long. 624 return ERROR_MALFORMED; 625 } 626 627 char chunk[5]; 628 MakeFourCCString(chunk_type, chunk); 629 ALOGV("chunk: %s @ %lld", chunk, *offset); 630 631#if 0 632 static const char kWhitespace[] = " "; 633 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 634 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 635 636 char buffer[256]; 637 size_t n = chunk_size; 638 if (n > sizeof(buffer)) { 639 n = sizeof(buffer); 640 } 641 if (mDataSource->readAt(*offset, buffer, n) 642 < (ssize_t)n) { 643 return ERROR_IO; 644 } 645 646 hexdump(buffer, n); 647#endif 648 649 PathAdder autoAdder(&mPath, chunk_type); 650 651 off64_t chunk_data_size = *offset + chunk_size - data_offset; 652 653 if (chunk_type != FOURCC('c', 'p', 'r', 't') 654 && chunk_type != FOURCC('c', 'o', 'v', 'r') 655 && mPath.size() == 5 && underMetaDataPath(mPath)) { 656 off64_t stop_offset = *offset + chunk_size; 657 *offset = data_offset; 658 while (*offset < stop_offset) { 659 status_t err = parseChunk(offset, depth + 1); 660 if (err != OK) { 661 return err; 662 } 663 } 664 665 if (*offset != stop_offset) { 666 return ERROR_MALFORMED; 667 } 668 669 return OK; 670 } 671 672 switch(chunk_type) { 673 case FOURCC('m', 'o', 'o', 'v'): 674 case FOURCC('t', 'r', 'a', 'k'): 675 case FOURCC('m', 'd', 'i', 'a'): 676 case FOURCC('m', 'i', 'n', 'f'): 677 case FOURCC('d', 'i', 'n', 'f'): 678 case FOURCC('s', 't', 'b', 'l'): 679 case FOURCC('m', 'v', 'e', 'x'): 680 case FOURCC('m', 'o', 'o', 'f'): 681 case FOURCC('t', 'r', 'a', 'f'): 682 case FOURCC('m', 'f', 'r', 'a'): 683 case FOURCC('u', 'd', 't', 'a'): 684 case FOURCC('i', 'l', 's', 't'): 685 { 686 if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 687 ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 688 689 if (mDataSource->flags() 690 & (DataSource::kWantsPrefetching 691 | DataSource::kIsCachingDataSource)) { 692 sp<MPEG4DataSource> cachedSource = 693 new MPEG4DataSource(mDataSource); 694 695 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 696 mDataSource = cachedSource; 697 } 698 } 699 700 mLastTrack->sampleTable = new SampleTable(mDataSource); 701 } 702 703 bool isTrack = false; 704 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 705 isTrack = true; 706 707 Track *track = new Track; 708 track->next = NULL; 709 if (mLastTrack) { 710 mLastTrack->next = track; 711 } else { 712 mFirstTrack = track; 713 } 714 mLastTrack = track; 715 716 track->meta = new MetaData; 717 track->includes_expensive_metadata = false; 718 track->skipTrack = false; 719 track->timescale = 0; 720 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 721 } 722 723 off64_t stop_offset = *offset + chunk_size; 724 *offset = data_offset; 725 while (*offset < stop_offset) { 726 status_t err = parseChunk(offset, depth + 1); 727 if (err != OK) { 728 return err; 729 } 730 } 731 732 if (*offset != stop_offset) { 733 return ERROR_MALFORMED; 734 } 735 736 if (isTrack) { 737 if (mLastTrack->skipTrack) { 738 Track *cur = mFirstTrack; 739 740 if (cur == mLastTrack) { 741 delete cur; 742 mFirstTrack = mLastTrack = NULL; 743 } else { 744 while (cur && cur->next != mLastTrack) { 745 cur = cur->next; 746 } 747 cur->next = NULL; 748 delete mLastTrack; 749 mLastTrack = cur; 750 } 751 752 return OK; 753 } 754 755 status_t err = verifyTrack(mLastTrack); 756 757 if (err != OK) { 758 return err; 759 } 760 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 761 mInitCheck = OK; 762 763 if (!mIsDrm) { 764 return UNKNOWN_ERROR; // Return a dummy error. 765 } else { 766 return OK; 767 } 768 } 769 break; 770 } 771 772 case FOURCC('t', 'k', 'h', 'd'): 773 { 774 status_t err; 775 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 776 return err; 777 } 778 779 *offset += chunk_size; 780 break; 781 } 782 783 case FOURCC('m', 'd', 'h', 'd'): 784 { 785 if (chunk_data_size < 4) { 786 return ERROR_MALFORMED; 787 } 788 789 uint8_t version; 790 if (mDataSource->readAt( 791 data_offset, &version, sizeof(version)) 792 < (ssize_t)sizeof(version)) { 793 return ERROR_IO; 794 } 795 796 off64_t timescale_offset; 797 798 if (version == 1) { 799 timescale_offset = data_offset + 4 + 16; 800 } else if (version == 0) { 801 timescale_offset = data_offset + 4 + 8; 802 } else { 803 return ERROR_IO; 804 } 805 806 uint32_t timescale; 807 if (mDataSource->readAt( 808 timescale_offset, ×cale, sizeof(timescale)) 809 < (ssize_t)sizeof(timescale)) { 810 return ERROR_IO; 811 } 812 813 mLastTrack->timescale = ntohl(timescale); 814 815 int64_t duration; 816 if (version == 1) { 817 if (mDataSource->readAt( 818 timescale_offset + 4, &duration, sizeof(duration)) 819 < (ssize_t)sizeof(duration)) { 820 return ERROR_IO; 821 } 822 duration = ntoh64(duration); 823 } else { 824 int32_t duration32; 825 if (mDataSource->readAt( 826 timescale_offset + 4, &duration32, sizeof(duration32)) 827 < (ssize_t)sizeof(duration32)) { 828 return ERROR_IO; 829 } 830 duration = ntohl(duration32); 831 } 832 mLastTrack->meta->setInt64( 833 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 834 835 uint8_t lang[2]; 836 off64_t lang_offset; 837 if (version == 1) { 838 lang_offset = timescale_offset + 4 + 8; 839 } else if (version == 0) { 840 lang_offset = timescale_offset + 4 + 4; 841 } else { 842 return ERROR_IO; 843 } 844 845 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 846 < (ssize_t)sizeof(lang)) { 847 return ERROR_IO; 848 } 849 850 // To get the ISO-639-2/T three character language code 851 // 1 bit pad followed by 3 5-bits characters. Each character 852 // is packed as the difference between its ASCII value and 0x60. 853 char lang_code[4]; 854 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 855 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 856 lang_code[2] = (lang[1] & 0x1f) + 0x60; 857 lang_code[3] = '\0'; 858 859 mLastTrack->meta->setCString( 860 kKeyMediaLanguage, lang_code); 861 862 *offset += chunk_size; 863 break; 864 } 865 866 case FOURCC('s', 't', 's', 'd'): 867 { 868 if (chunk_data_size < 8) { 869 return ERROR_MALFORMED; 870 } 871 872 uint8_t buffer[8]; 873 if (chunk_data_size < (off64_t)sizeof(buffer)) { 874 return ERROR_MALFORMED; 875 } 876 877 if (mDataSource->readAt( 878 data_offset, buffer, 8) < 8) { 879 return ERROR_IO; 880 } 881 882 if (U32_AT(buffer) != 0) { 883 // Should be version 0, flags 0. 884 return ERROR_MALFORMED; 885 } 886 887 uint32_t entry_count = U32_AT(&buffer[4]); 888 889 if (entry_count > 1) { 890 // For 3GPP timed text, there could be multiple tx3g boxes contain 891 // multiple text display formats. These formats will be used to 892 // display the timed text. 893 const char *mime; 894 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 895 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 896 // For now we only support a single type of media per track. 897 mLastTrack->skipTrack = true; 898 *offset += chunk_size; 899 break; 900 } 901 } 902 903 off64_t stop_offset = *offset + chunk_size; 904 *offset = data_offset + 8; 905 for (uint32_t i = 0; i < entry_count; ++i) { 906 status_t err = parseChunk(offset, depth + 1); 907 if (err != OK) { 908 return err; 909 } 910 } 911 912 if (*offset != stop_offset) { 913 return ERROR_MALFORMED; 914 } 915 break; 916 } 917 918 case FOURCC('m', 'p', '4', 'a'): 919 case FOURCC('s', 'a', 'm', 'r'): 920 case FOURCC('s', 'a', 'w', 'b'): 921 { 922 uint8_t buffer[8 + 20]; 923 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 924 // Basic AudioSampleEntry size. 925 return ERROR_MALFORMED; 926 } 927 928 if (mDataSource->readAt( 929 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 930 return ERROR_IO; 931 } 932 933 uint16_t data_ref_index = U16_AT(&buffer[6]); 934 uint16_t num_channels = U16_AT(&buffer[16]); 935 936 uint16_t sample_size = U16_AT(&buffer[18]); 937 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 938 939 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 940 FourCC2MIME(chunk_type))) { 941 // AMR NB audio is always mono, 8kHz 942 num_channels = 1; 943 sample_rate = 8000; 944 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 945 FourCC2MIME(chunk_type))) { 946 // AMR WB audio is always mono, 16kHz 947 num_channels = 1; 948 sample_rate = 16000; 949 } 950 951#if 0 952 printf("*** coding='%s' %d channels, size %d, rate %d\n", 953 chunk, num_channels, sample_size, sample_rate); 954#endif 955 956 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 957 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 958 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 959 960 off64_t stop_offset = *offset + chunk_size; 961 *offset = data_offset + sizeof(buffer); 962 while (*offset < stop_offset) { 963 status_t err = parseChunk(offset, depth + 1); 964 if (err != OK) { 965 return err; 966 } 967 } 968 969 if (*offset != stop_offset) { 970 return ERROR_MALFORMED; 971 } 972 break; 973 } 974 975 case FOURCC('m', 'p', '4', 'v'): 976 case FOURCC('s', '2', '6', '3'): 977 case FOURCC('H', '2', '6', '3'): 978 case FOURCC('h', '2', '6', '3'): 979 case FOURCC('a', 'v', 'c', '1'): 980 { 981 mHasVideo = true; 982 983 uint8_t buffer[78]; 984 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 985 // Basic VideoSampleEntry size. 986 return ERROR_MALFORMED; 987 } 988 989 if (mDataSource->readAt( 990 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 991 return ERROR_IO; 992 } 993 994 uint16_t data_ref_index = U16_AT(&buffer[6]); 995 uint16_t width = U16_AT(&buffer[6 + 18]); 996 uint16_t height = U16_AT(&buffer[6 + 20]); 997 998 // The video sample is not stand-compliant if it has invalid dimension. 999 // Use some default width and height value, and 1000 // let the decoder figure out the actual width and height (and thus 1001 // be prepared for INFO_FOMRAT_CHANGED event). 1002 if (width == 0) width = 352; 1003 if (height == 0) height = 288; 1004 1005 // printf("*** coding='%s' width=%d height=%d\n", 1006 // chunk, width, height); 1007 1008 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1009 mLastTrack->meta->setInt32(kKeyWidth, width); 1010 mLastTrack->meta->setInt32(kKeyHeight, height); 1011 1012 off64_t stop_offset = *offset + chunk_size; 1013 *offset = data_offset + sizeof(buffer); 1014 while (*offset < stop_offset) { 1015 status_t err = parseChunk(offset, depth + 1); 1016 if (err != OK) { 1017 return err; 1018 } 1019 } 1020 1021 if (*offset != stop_offset) { 1022 return ERROR_MALFORMED; 1023 } 1024 break; 1025 } 1026 1027 case FOURCC('s', 't', 'c', 'o'): 1028 case FOURCC('c', 'o', '6', '4'): 1029 { 1030 status_t err = 1031 mLastTrack->sampleTable->setChunkOffsetParams( 1032 chunk_type, data_offset, chunk_data_size); 1033 1034 if (err != OK) { 1035 return err; 1036 } 1037 1038 *offset += chunk_size; 1039 break; 1040 } 1041 1042 case FOURCC('s', 't', 's', 'c'): 1043 { 1044 status_t err = 1045 mLastTrack->sampleTable->setSampleToChunkParams( 1046 data_offset, chunk_data_size); 1047 1048 if (err != OK) { 1049 return err; 1050 } 1051 1052 *offset += chunk_size; 1053 break; 1054 } 1055 1056 case FOURCC('s', 't', 's', 'z'): 1057 case FOURCC('s', 't', 'z', '2'): 1058 { 1059 status_t err = 1060 mLastTrack->sampleTable->setSampleSizeParams( 1061 chunk_type, data_offset, chunk_data_size); 1062 1063 if (err != OK) { 1064 return err; 1065 } 1066 1067 size_t max_size; 1068 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 1069 1070 if (err != OK) { 1071 return err; 1072 } 1073 1074 // Assume that a given buffer only contains at most 10 fragments, 1075 // each fragment originally prefixed with a 2 byte length will 1076 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1077 // and thus will grow by 2 bytes per fragment. 1078 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1079 *offset += chunk_size; 1080 1081 // Calculate average frame rate. 1082 const char *mime; 1083 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1084 if (!strncasecmp("video/", mime, 6)) { 1085 size_t nSamples = mLastTrack->sampleTable->countSamples(); 1086 int64_t durationUs; 1087 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1088 if (durationUs > 0) { 1089 int32_t frameRate = (nSamples * 1000000LL + 1090 (durationUs >> 1)) / durationUs; 1091 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1092 } 1093 } 1094 } 1095 1096 break; 1097 } 1098 1099 case FOURCC('s', 't', 't', 's'): 1100 { 1101 status_t err = 1102 mLastTrack->sampleTable->setTimeToSampleParams( 1103 data_offset, chunk_data_size); 1104 1105 if (err != OK) { 1106 return err; 1107 } 1108 1109 *offset += chunk_size; 1110 break; 1111 } 1112 1113 case FOURCC('c', 't', 't', 's'): 1114 { 1115 status_t err = 1116 mLastTrack->sampleTable->setCompositionTimeToSampleParams( 1117 data_offset, chunk_data_size); 1118 1119 if (err != OK) { 1120 return err; 1121 } 1122 1123 *offset += chunk_size; 1124 break; 1125 } 1126 1127 case FOURCC('s', 't', 's', 's'): 1128 { 1129 status_t err = 1130 mLastTrack->sampleTable->setSyncSampleParams( 1131 data_offset, chunk_data_size); 1132 1133 if (err != OK) { 1134 return err; 1135 } 1136 1137 *offset += chunk_size; 1138 break; 1139 } 1140 1141 // @xyz 1142 case FOURCC('\xA9', 'x', 'y', 'z'): 1143 { 1144 // Best case the total data length inside "@xyz" box 1145 // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 1146 // where "\x00\x04" is the text string length with value = 4, 1147 // "\0x15\xc7" is the language code = en, and "0+0" is a 1148 // location (string) value with longitude = 0 and latitude = 0. 1149 if (chunk_data_size < 8) { 1150 return ERROR_MALFORMED; 1151 } 1152 1153 // Worst case the location string length would be 18, 1154 // for instance +90.0000-180.0000, without the trailing "/" and 1155 // the string length + language code. 1156 char buffer[18]; 1157 1158 // Substracting 5 from the data size is because the text string length + 1159 // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 1160 off64_t location_length = chunk_data_size - 5; 1161 if (location_length >= (off64_t) sizeof(buffer)) { 1162 return ERROR_MALFORMED; 1163 } 1164 1165 if (mDataSource->readAt( 1166 data_offset + 4, buffer, location_length) < location_length) { 1167 return ERROR_IO; 1168 } 1169 1170 buffer[location_length] = '\0'; 1171 mFileMetaData->setCString(kKeyLocation, buffer); 1172 *offset += chunk_size; 1173 break; 1174 } 1175 1176 case FOURCC('e', 's', 'd', 's'): 1177 { 1178 if (chunk_data_size < 4) { 1179 return ERROR_MALFORMED; 1180 } 1181 1182 uint8_t buffer[256]; 1183 if (chunk_data_size > (off64_t)sizeof(buffer)) { 1184 return ERROR_BUFFER_TOO_SMALL; 1185 } 1186 1187 if (mDataSource->readAt( 1188 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1189 return ERROR_IO; 1190 } 1191 1192 if (U32_AT(buffer) != 0) { 1193 // Should be version 0, flags 0. 1194 return ERROR_MALFORMED; 1195 } 1196 1197 mLastTrack->meta->setData( 1198 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 1199 1200 if (mPath.size() >= 2 1201 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1202 // Information from the ESDS must be relied on for proper 1203 // setup of sample rate and channel count for MPEG4 Audio. 1204 // The generic header appears to only contain generic 1205 // information... 1206 1207 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1208 &buffer[4], chunk_data_size - 4); 1209 1210 if (err != OK) { 1211 return err; 1212 } 1213 } 1214 1215 *offset += chunk_size; 1216 break; 1217 } 1218 1219 case FOURCC('a', 'v', 'c', 'C'): 1220 { 1221 char buffer[256]; 1222 if (chunk_data_size > (off64_t)sizeof(buffer)) { 1223 return ERROR_BUFFER_TOO_SMALL; 1224 } 1225 1226 if (mDataSource->readAt( 1227 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1228 return ERROR_IO; 1229 } 1230 1231 mLastTrack->meta->setData( 1232 kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 1233 1234 *offset += chunk_size; 1235 break; 1236 } 1237 1238 case FOURCC('d', '2', '6', '3'): 1239 { 1240 /* 1241 * d263 contains a fixed 7 bytes part: 1242 * vendor - 4 bytes 1243 * version - 1 byte 1244 * level - 1 byte 1245 * profile - 1 byte 1246 * optionally, "d263" box itself may contain a 16-byte 1247 * bit rate box (bitr) 1248 * average bit rate - 4 bytes 1249 * max bit rate - 4 bytes 1250 */ 1251 char buffer[23]; 1252 if (chunk_data_size != 7 && 1253 chunk_data_size != 23) { 1254 ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1255 return ERROR_MALFORMED; 1256 } 1257 1258 if (mDataSource->readAt( 1259 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1260 return ERROR_IO; 1261 } 1262 1263 mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1264 1265 *offset += chunk_size; 1266 break; 1267 } 1268 1269 case FOURCC('m', 'e', 't', 'a'): 1270 { 1271 uint8_t buffer[4]; 1272 if (chunk_data_size < (off64_t)sizeof(buffer)) { 1273 return ERROR_MALFORMED; 1274 } 1275 1276 if (mDataSource->readAt( 1277 data_offset, buffer, 4) < 4) { 1278 return ERROR_IO; 1279 } 1280 1281 if (U32_AT(buffer) != 0) { 1282 // Should be version 0, flags 0. 1283 1284 // If it's not, let's assume this is one of those 1285 // apparently malformed chunks that don't have flags 1286 // and completely different semantics than what's 1287 // in the MPEG4 specs and skip it. 1288 *offset += chunk_size; 1289 return OK; 1290 } 1291 1292 off64_t stop_offset = *offset + chunk_size; 1293 *offset = data_offset + sizeof(buffer); 1294 while (*offset < stop_offset) { 1295 status_t err = parseChunk(offset, depth + 1); 1296 if (err != OK) { 1297 return err; 1298 } 1299 } 1300 1301 if (*offset != stop_offset) { 1302 return ERROR_MALFORMED; 1303 } 1304 break; 1305 } 1306 1307 case FOURCC('m', 'e', 'a', 'n'): 1308 case FOURCC('n', 'a', 'm', 'e'): 1309 case FOURCC('d', 'a', 't', 'a'): 1310 { 1311 if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1312 status_t err = parseMetaData(data_offset, chunk_data_size); 1313 1314 if (err != OK) { 1315 return err; 1316 } 1317 } 1318 1319 *offset += chunk_size; 1320 break; 1321 } 1322 1323 case FOURCC('m', 'v', 'h', 'd'): 1324 { 1325 if (chunk_data_size < 12) { 1326 return ERROR_MALFORMED; 1327 } 1328 1329 uint8_t header[12]; 1330 if (mDataSource->readAt( 1331 data_offset, header, sizeof(header)) 1332 < (ssize_t)sizeof(header)) { 1333 return ERROR_IO; 1334 } 1335 1336 int64_t creationTime; 1337 if (header[0] == 1) { 1338 creationTime = U64_AT(&header[4]); 1339 } else if (header[0] != 0) { 1340 return ERROR_MALFORMED; 1341 } else { 1342 creationTime = U32_AT(&header[4]); 1343 } 1344 1345 String8 s; 1346 convertTimeToDate(creationTime, &s); 1347 1348 mFileMetaData->setCString(kKeyDate, s.string()); 1349 1350 *offset += chunk_size; 1351 break; 1352 } 1353 1354 case FOURCC('m', 'd', 'a', 't'): 1355 { 1356 if (!mIsDrm) { 1357 *offset += chunk_size; 1358 break; 1359 } 1360 1361 if (chunk_size < 8) { 1362 return ERROR_MALFORMED; 1363 } 1364 1365 return parseDrmSINF(offset, data_offset); 1366 } 1367 1368 case FOURCC('h', 'd', 'l', 'r'): 1369 { 1370 uint32_t buffer; 1371 if (mDataSource->readAt( 1372 data_offset + 8, &buffer, 4) < 4) { 1373 return ERROR_IO; 1374 } 1375 1376 uint32_t type = ntohl(buffer); 1377 // For the 3GPP file format, the handler-type within the 'hdlr' box 1378 // shall be 'text'. We also want to support 'sbtl' handler type 1379 // for a practical reason as various MPEG4 containers use it. 1380 if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 1381 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 1382 } 1383 1384 *offset += chunk_size; 1385 break; 1386 } 1387 1388 case FOURCC('t', 'x', '3', 'g'): 1389 { 1390 uint32_t type; 1391 const void *data; 1392 size_t size = 0; 1393 if (!mLastTrack->meta->findData( 1394 kKeyTextFormatData, &type, &data, &size)) { 1395 size = 0; 1396 } 1397 1398 uint8_t *buffer = new uint8_t[size + chunk_size]; 1399 1400 if (size > 0) { 1401 memcpy(buffer, data, size); 1402 } 1403 1404 if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 1405 < chunk_size) { 1406 delete[] buffer; 1407 buffer = NULL; 1408 1409 return ERROR_IO; 1410 } 1411 1412 mLastTrack->meta->setData( 1413 kKeyTextFormatData, 0, buffer, size + chunk_size); 1414 1415 delete[] buffer; 1416 1417 *offset += chunk_size; 1418 break; 1419 } 1420 1421 case FOURCC('c', 'o', 'v', 'r'): 1422 { 1423 if (mFileMetaData != NULL) { 1424 ALOGV("chunk_data_size = %lld and data_offset = %lld", 1425 chunk_data_size, data_offset); 1426 uint8_t *buffer = new uint8_t[chunk_data_size + 1]; 1427 if (mDataSource->readAt( 1428 data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) { 1429 delete[] buffer; 1430 buffer = NULL; 1431 1432 return ERROR_IO; 1433 } 1434 const int kSkipBytesOfDataBox = 16; 1435 mFileMetaData->setData( 1436 kKeyAlbumArt, MetaData::TYPE_NONE, 1437 buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1438 } 1439 1440 *offset += chunk_size; 1441 break; 1442 } 1443 1444 case FOURCC('-', '-', '-', '-'): 1445 { 1446 mLastCommentMean.clear(); 1447 mLastCommentName.clear(); 1448 mLastCommentData.clear(); 1449 *offset += chunk_size; 1450 break; 1451 } 1452 1453 default: 1454 { 1455 *offset += chunk_size; 1456 break; 1457 } 1458 } 1459 1460 return OK; 1461} 1462 1463status_t MPEG4Extractor::parseTrackHeader( 1464 off64_t data_offset, off64_t data_size) { 1465 if (data_size < 4) { 1466 return ERROR_MALFORMED; 1467 } 1468 1469 uint8_t version; 1470 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1471 return ERROR_IO; 1472 } 1473 1474 size_t dynSize = (version == 1) ? 36 : 24; 1475 1476 uint8_t buffer[36 + 60]; 1477 1478 if (data_size != (off64_t)dynSize + 60) { 1479 return ERROR_MALFORMED; 1480 } 1481 1482 if (mDataSource->readAt( 1483 data_offset, buffer, data_size) < (ssize_t)data_size) { 1484 return ERROR_IO; 1485 } 1486 1487 uint64_t ctime, mtime, duration; 1488 int32_t id; 1489 1490 if (version == 1) { 1491 ctime = U64_AT(&buffer[4]); 1492 mtime = U64_AT(&buffer[12]); 1493 id = U32_AT(&buffer[20]); 1494 duration = U64_AT(&buffer[28]); 1495 } else { 1496 CHECK_EQ((unsigned)version, 0u); 1497 1498 ctime = U32_AT(&buffer[4]); 1499 mtime = U32_AT(&buffer[8]); 1500 id = U32_AT(&buffer[12]); 1501 duration = U32_AT(&buffer[20]); 1502 } 1503 1504 mLastTrack->meta->setInt32(kKeyTrackID, id); 1505 1506 size_t matrixOffset = dynSize + 16; 1507 int32_t a00 = U32_AT(&buffer[matrixOffset]); 1508 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1509 int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1510 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1511 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1512 int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1513 1514#if 0 1515 ALOGI("x' = %.2f * x + %.2f * y + %.2f", 1516 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1517 ALOGI("y' = %.2f * x + %.2f * y + %.2f", 1518 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1519#endif 1520 1521 uint32_t rotationDegrees; 1522 1523 static const int32_t kFixedOne = 0x10000; 1524 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1525 // Identity, no rotation 1526 rotationDegrees = 0; 1527 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1528 rotationDegrees = 90; 1529 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1530 rotationDegrees = 270; 1531 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1532 rotationDegrees = 180; 1533 } else { 1534 ALOGW("We only support 0,90,180,270 degree rotation matrices"); 1535 rotationDegrees = 0; 1536 } 1537 1538 if (rotationDegrees != 0) { 1539 mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1540 } 1541 1542 // Handle presentation display size, which could be different 1543 // from the image size indicated by kKeyWidth and kKeyHeight. 1544 uint32_t width = U32_AT(&buffer[dynSize + 52]); 1545 uint32_t height = U32_AT(&buffer[dynSize + 56]); 1546 mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 1547 mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1548 1549 return OK; 1550} 1551 1552status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 1553 if (size < 4) { 1554 return ERROR_MALFORMED; 1555 } 1556 1557 uint8_t *buffer = new uint8_t[size + 1]; 1558 if (mDataSource->readAt( 1559 offset, buffer, size) != (ssize_t)size) { 1560 delete[] buffer; 1561 buffer = NULL; 1562 1563 return ERROR_IO; 1564 } 1565 1566 uint32_t flags = U32_AT(buffer); 1567 1568 uint32_t metadataKey = 0; 1569 char chunk[5]; 1570 MakeFourCCString(mPath[4], chunk); 1571 ALOGV("meta: %s @ %lld", chunk, offset); 1572 switch (mPath[4]) { 1573 case FOURCC(0xa9, 'a', 'l', 'b'): 1574 { 1575 metadataKey = kKeyAlbum; 1576 break; 1577 } 1578 case FOURCC(0xa9, 'A', 'R', 'T'): 1579 { 1580 metadataKey = kKeyArtist; 1581 break; 1582 } 1583 case FOURCC('a', 'A', 'R', 'T'): 1584 { 1585 metadataKey = kKeyAlbumArtist; 1586 break; 1587 } 1588 case FOURCC(0xa9, 'd', 'a', 'y'): 1589 { 1590 metadataKey = kKeyYear; 1591 break; 1592 } 1593 case FOURCC(0xa9, 'n', 'a', 'm'): 1594 { 1595 metadataKey = kKeyTitle; 1596 break; 1597 } 1598 case FOURCC(0xa9, 'w', 'r', 't'): 1599 { 1600 metadataKey = kKeyWriter; 1601 break; 1602 } 1603 case FOURCC('c', 'o', 'v', 'r'): 1604 { 1605 metadataKey = kKeyAlbumArt; 1606 break; 1607 } 1608 case FOURCC('g', 'n', 'r', 'e'): 1609 { 1610 metadataKey = kKeyGenre; 1611 break; 1612 } 1613 case FOURCC(0xa9, 'g', 'e', 'n'): 1614 { 1615 metadataKey = kKeyGenre; 1616 break; 1617 } 1618 case FOURCC('c', 'p', 'i', 'l'): 1619 { 1620 if (size == 9 && flags == 21) { 1621 char tmp[16]; 1622 sprintf(tmp, "%d", 1623 (int)buffer[size - 1]); 1624 1625 mFileMetaData->setCString(kKeyCompilation, tmp); 1626 } 1627 break; 1628 } 1629 case FOURCC('t', 'r', 'k', 'n'): 1630 { 1631 if (size == 16 && flags == 0) { 1632 char tmp[16]; 1633 sprintf(tmp, "%d/%d", 1634 (int)buffer[size - 5], (int)buffer[size - 3]); 1635 1636 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1637 } 1638 break; 1639 } 1640 case FOURCC('d', 'i', 's', 'k'): 1641 { 1642 if (size == 14 && flags == 0) { 1643 char tmp[16]; 1644 sprintf(tmp, "%d/%d", 1645 (int)buffer[size - 3], (int)buffer[size - 1]); 1646 1647 mFileMetaData->setCString(kKeyDiscNumber, tmp); 1648 } 1649 break; 1650 } 1651 case FOURCC('-', '-', '-', '-'): 1652 { 1653 buffer[size] = '\0'; 1654 switch (mPath[5]) { 1655 case FOURCC('m', 'e', 'a', 'n'): 1656 mLastCommentMean.setTo((const char *)buffer + 4); 1657 break; 1658 case FOURCC('n', 'a', 'm', 'e'): 1659 mLastCommentName.setTo((const char *)buffer + 4); 1660 break; 1661 case FOURCC('d', 'a', 't', 'a'): 1662 mLastCommentData.setTo((const char *)buffer + 8); 1663 break; 1664 } 1665 if (mLastCommentMean == "com.apple.iTunes" 1666 && mLastCommentName == "iTunSMPB" 1667 && mLastCommentData.length() != 0) { 1668 int32_t delay, padding; 1669 if (sscanf(mLastCommentData, 1670 " %*x %x %x %*x", &delay, &padding) == 2) { 1671 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 1672 mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 1673 } 1674 mLastCommentMean.clear(); 1675 mLastCommentName.clear(); 1676 mLastCommentData.clear(); 1677 } 1678 break; 1679 } 1680 1681 default: 1682 break; 1683 } 1684 1685 if (size >= 8 && metadataKey) { 1686 if (metadataKey == kKeyAlbumArt) { 1687 mFileMetaData->setData( 1688 kKeyAlbumArt, MetaData::TYPE_NONE, 1689 buffer + 8, size - 8); 1690 } else if (metadataKey == kKeyGenre) { 1691 if (flags == 0) { 1692 // uint8_t genre code, iTunes genre codes are 1693 // the standard id3 codes, except they start 1694 // at 1 instead of 0 (e.g. Pop is 14, not 13) 1695 // We use standard id3 numbering, so subtract 1. 1696 int genrecode = (int)buffer[size - 1]; 1697 genrecode--; 1698 if (genrecode < 0) { 1699 genrecode = 255; // reserved for 'unknown genre' 1700 } 1701 char genre[10]; 1702 sprintf(genre, "%d", genrecode); 1703 1704 mFileMetaData->setCString(metadataKey, genre); 1705 } else if (flags == 1) { 1706 // custom genre string 1707 buffer[size] = '\0'; 1708 1709 mFileMetaData->setCString( 1710 metadataKey, (const char *)buffer + 8); 1711 } 1712 } else { 1713 buffer[size] = '\0'; 1714 1715 mFileMetaData->setCString( 1716 metadataKey, (const char *)buffer + 8); 1717 } 1718 } 1719 1720 delete[] buffer; 1721 buffer = NULL; 1722 1723 return OK; 1724} 1725 1726sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1727 status_t err; 1728 if ((err = readMetaData()) != OK) { 1729 return NULL; 1730 } 1731 1732 Track *track = mFirstTrack; 1733 while (index > 0) { 1734 if (track == NULL) { 1735 return NULL; 1736 } 1737 1738 track = track->next; 1739 --index; 1740 } 1741 1742 if (track == NULL) { 1743 return NULL; 1744 } 1745 1746 return new MPEG4Source( 1747 track->meta, mDataSource, track->timescale, track->sampleTable); 1748} 1749 1750// static 1751status_t MPEG4Extractor::verifyTrack(Track *track) { 1752 const char *mime; 1753 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1754 1755 uint32_t type; 1756 const void *data; 1757 size_t size; 1758 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1759 if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1760 || type != kTypeAVCC) { 1761 return ERROR_MALFORMED; 1762 } 1763 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1764 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1765 if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1766 || type != kTypeESDS) { 1767 return ERROR_MALFORMED; 1768 } 1769 } 1770 1771 if (!track->sampleTable->isValid()) { 1772 // Make sure we have all the metadata we need. 1773 return ERROR_MALFORMED; 1774 } 1775 1776 return OK; 1777} 1778 1779status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1780 const void *esds_data, size_t esds_size) { 1781 ESDS esds(esds_data, esds_size); 1782 1783 uint8_t objectTypeIndication; 1784 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1785 return ERROR_MALFORMED; 1786 } 1787 1788 if (objectTypeIndication == 0xe1) { 1789 // This isn't MPEG4 audio at all, it's QCELP 14k... 1790 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 1791 return OK; 1792 } 1793 1794 if (objectTypeIndication == 0x6b) { 1795 // The media subtype is MP3 audio 1796 // Our software MP3 audio decoder may not be able to handle 1797 // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 1798 ALOGE("MP3 track in MP4/3GPP file is not supported"); 1799 return ERROR_UNSUPPORTED; 1800 } 1801 1802 const uint8_t *csd; 1803 size_t csd_size; 1804 if (esds.getCodecSpecificInfo( 1805 (const void **)&csd, &csd_size) != OK) { 1806 return ERROR_MALFORMED; 1807 } 1808 1809#if 0 1810 printf("ESD of size %d\n", csd_size); 1811 hexdump(csd, csd_size); 1812#endif 1813 1814 if (csd_size == 0) { 1815 // There's no further information, i.e. no codec specific data 1816 // Let's assume that the information provided in the mpeg4 headers 1817 // is accurate and hope for the best. 1818 1819 return OK; 1820 } 1821 1822 if (csd_size < 2) { 1823 return ERROR_MALFORMED; 1824 } 1825 1826 uint32_t objectType = csd[0] >> 3; 1827 1828 if (objectType == 31) { 1829 return ERROR_UNSUPPORTED; 1830 } 1831 1832 uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1833 int32_t sampleRate = 0; 1834 int32_t numChannels = 0; 1835 if (freqIndex == 15) { 1836 if (csd_size < 5) { 1837 return ERROR_MALFORMED; 1838 } 1839 1840 sampleRate = (csd[1] & 0x7f) << 17 1841 | csd[2] << 9 1842 | csd[3] << 1 1843 | (csd[4] >> 7); 1844 1845 numChannels = (csd[4] >> 3) & 15; 1846 } else { 1847 static uint32_t kSamplingRate[] = { 1848 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1849 16000, 12000, 11025, 8000, 7350 1850 }; 1851 1852 if (freqIndex == 13 || freqIndex == 14) { 1853 return ERROR_MALFORMED; 1854 } 1855 1856 sampleRate = kSamplingRate[freqIndex]; 1857 numChannels = (csd[1] >> 3) & 15; 1858 } 1859 1860 if (numChannels == 0) { 1861 return ERROR_UNSUPPORTED; 1862 } 1863 1864 int32_t prevSampleRate; 1865 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1866 1867 if (prevSampleRate != sampleRate) { 1868 ALOGV("mpeg4 audio sample rate different from previous setting. " 1869 "was: %d, now: %d", prevSampleRate, sampleRate); 1870 } 1871 1872 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1873 1874 int32_t prevChannelCount; 1875 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1876 1877 if (prevChannelCount != numChannels) { 1878 ALOGV("mpeg4 audio channel count different from previous setting. " 1879 "was: %d, now: %d", prevChannelCount, numChannels); 1880 } 1881 1882 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1883 1884 return OK; 1885} 1886 1887//////////////////////////////////////////////////////////////////////////////// 1888 1889MPEG4Source::MPEG4Source( 1890 const sp<MetaData> &format, 1891 const sp<DataSource> &dataSource, 1892 int32_t timeScale, 1893 const sp<SampleTable> &sampleTable) 1894 : mFormat(format), 1895 mDataSource(dataSource), 1896 mTimescale(timeScale), 1897 mSampleTable(sampleTable), 1898 mCurrentSampleIndex(0), 1899 mIsAVC(false), 1900 mNALLengthSize(0), 1901 mStarted(false), 1902 mGroup(NULL), 1903 mBuffer(NULL), 1904 mWantsNALFragments(false), 1905 mSrcBuffer(NULL) { 1906 const char *mime; 1907 bool success = mFormat->findCString(kKeyMIMEType, &mime); 1908 CHECK(success); 1909 1910 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1911 1912 if (mIsAVC) { 1913 uint32_t type; 1914 const void *data; 1915 size_t size; 1916 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1917 1918 const uint8_t *ptr = (const uint8_t *)data; 1919 1920 CHECK(size >= 7); 1921 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1922 1923 // The number of bytes used to encode the length of a NAL unit. 1924 mNALLengthSize = 1 + (ptr[4] & 3); 1925 } 1926} 1927 1928MPEG4Source::~MPEG4Source() { 1929 if (mStarted) { 1930 stop(); 1931 } 1932} 1933 1934status_t MPEG4Source::start(MetaData *params) { 1935 Mutex::Autolock autoLock(mLock); 1936 1937 CHECK(!mStarted); 1938 1939 int32_t val; 1940 if (params && params->findInt32(kKeyWantsNALFragments, &val) 1941 && val != 0) { 1942 mWantsNALFragments = true; 1943 } else { 1944 mWantsNALFragments = false; 1945 } 1946 1947 mGroup = new MediaBufferGroup; 1948 1949 int32_t max_size; 1950 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1951 1952 mGroup->add_buffer(new MediaBuffer(max_size)); 1953 1954 mSrcBuffer = new uint8_t[max_size]; 1955 1956 mStarted = true; 1957 1958 return OK; 1959} 1960 1961status_t MPEG4Source::stop() { 1962 Mutex::Autolock autoLock(mLock); 1963 1964 CHECK(mStarted); 1965 1966 if (mBuffer != NULL) { 1967 mBuffer->release(); 1968 mBuffer = NULL; 1969 } 1970 1971 delete[] mSrcBuffer; 1972 mSrcBuffer = NULL; 1973 1974 delete mGroup; 1975 mGroup = NULL; 1976 1977 mStarted = false; 1978 mCurrentSampleIndex = 0; 1979 1980 return OK; 1981} 1982 1983sp<MetaData> MPEG4Source::getFormat() { 1984 Mutex::Autolock autoLock(mLock); 1985 1986 return mFormat; 1987} 1988 1989size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1990 switch (mNALLengthSize) { 1991 case 1: 1992 return *data; 1993 case 2: 1994 return U16_AT(data); 1995 case 3: 1996 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1997 case 4: 1998 return U32_AT(data); 1999 } 2000 2001 // This cannot happen, mNALLengthSize springs to life by adding 1 to 2002 // a 2-bit integer. 2003 CHECK(!"Should not be here."); 2004 2005 return 0; 2006} 2007 2008status_t MPEG4Source::read( 2009 MediaBuffer **out, const ReadOptions *options) { 2010 Mutex::Autolock autoLock(mLock); 2011 2012 CHECK(mStarted); 2013 2014 *out = NULL; 2015 2016 int64_t targetSampleTimeUs = -1; 2017 2018 int64_t seekTimeUs; 2019 ReadOptions::SeekMode mode; 2020 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 2021 uint32_t findFlags = 0; 2022 switch (mode) { 2023 case ReadOptions::SEEK_PREVIOUS_SYNC: 2024 findFlags = SampleTable::kFlagBefore; 2025 break; 2026 case ReadOptions::SEEK_NEXT_SYNC: 2027 findFlags = SampleTable::kFlagAfter; 2028 break; 2029 case ReadOptions::SEEK_CLOSEST_SYNC: 2030 case ReadOptions::SEEK_CLOSEST: 2031 findFlags = SampleTable::kFlagClosest; 2032 break; 2033 default: 2034 CHECK(!"Should not be here."); 2035 break; 2036 } 2037 2038 uint32_t sampleIndex; 2039 status_t err = mSampleTable->findSampleAtTime( 2040 seekTimeUs * mTimescale / 1000000, 2041 &sampleIndex, findFlags); 2042 2043 if (mode == ReadOptions::SEEK_CLOSEST) { 2044 // We found the closest sample already, now we want the sync 2045 // sample preceding it (or the sample itself of course), even 2046 // if the subsequent sync sample is closer. 2047 findFlags = SampleTable::kFlagBefore; 2048 } 2049 2050 uint32_t syncSampleIndex; 2051 if (err == OK) { 2052 err = mSampleTable->findSyncSampleNear( 2053 sampleIndex, &syncSampleIndex, findFlags); 2054 } 2055 2056 uint32_t sampleTime; 2057 if (err == OK) { 2058 err = mSampleTable->getMetaDataForSample( 2059 sampleIndex, NULL, NULL, &sampleTime); 2060 } 2061 2062 if (err != OK) { 2063 if (err == ERROR_OUT_OF_RANGE) { 2064 // An attempt to seek past the end of the stream would 2065 // normally cause this ERROR_OUT_OF_RANGE error. Propagating 2066 // this all the way to the MediaPlayer would cause abnormal 2067 // termination. Legacy behaviour appears to be to behave as if 2068 // we had seeked to the end of stream, ending normally. 2069 err = ERROR_END_OF_STREAM; 2070 } 2071 return err; 2072 } 2073 2074 if (mode == ReadOptions::SEEK_CLOSEST) { 2075 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 2076 } 2077 2078#if 0 2079 uint32_t syncSampleTime; 2080 CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 2081 syncSampleIndex, NULL, NULL, &syncSampleTime)); 2082 2083 ALOGI("seek to time %lld us => sample at time %lld us, " 2084 "sync sample at time %lld us", 2085 seekTimeUs, 2086 sampleTime * 1000000ll / mTimescale, 2087 syncSampleTime * 1000000ll / mTimescale); 2088#endif 2089 2090 mCurrentSampleIndex = syncSampleIndex; 2091 if (mBuffer != NULL) { 2092 mBuffer->release(); 2093 mBuffer = NULL; 2094 } 2095 2096 // fall through 2097 } 2098 2099 off64_t offset; 2100 size_t size; 2101 uint32_t cts; 2102 bool isSyncSample; 2103 bool newBuffer = false; 2104 if (mBuffer == NULL) { 2105 newBuffer = true; 2106 2107 status_t err = 2108 mSampleTable->getMetaDataForSample( 2109 mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 2110 2111 if (err != OK) { 2112 return err; 2113 } 2114 2115 err = mGroup->acquire_buffer(&mBuffer); 2116 2117 if (err != OK) { 2118 CHECK(mBuffer == NULL); 2119 return err; 2120 } 2121 } 2122 2123 if (!mIsAVC || mWantsNALFragments) { 2124 if (newBuffer) { 2125 ssize_t num_bytes_read = 2126 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 2127 2128 if (num_bytes_read < (ssize_t)size) { 2129 mBuffer->release(); 2130 mBuffer = NULL; 2131 2132 return ERROR_IO; 2133 } 2134 2135 CHECK(mBuffer != NULL); 2136 mBuffer->set_range(0, size); 2137 mBuffer->meta_data()->clear(); 2138 mBuffer->meta_data()->setInt64( 2139 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2140 2141 if (targetSampleTimeUs >= 0) { 2142 mBuffer->meta_data()->setInt64( 2143 kKeyTargetTime, targetSampleTimeUs); 2144 } 2145 2146 if (isSyncSample) { 2147 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2148 } 2149 2150 ++mCurrentSampleIndex; 2151 } 2152 2153 if (!mIsAVC) { 2154 *out = mBuffer; 2155 mBuffer = NULL; 2156 2157 return OK; 2158 } 2159 2160 // Each NAL unit is split up into its constituent fragments and 2161 // each one of them returned in its own buffer. 2162 2163 CHECK(mBuffer->range_length() >= mNALLengthSize); 2164 2165 const uint8_t *src = 2166 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 2167 2168 size_t nal_size = parseNALSize(src); 2169 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 2170 ALOGE("incomplete NAL unit."); 2171 2172 mBuffer->release(); 2173 mBuffer = NULL; 2174 2175 return ERROR_MALFORMED; 2176 } 2177 2178 MediaBuffer *clone = mBuffer->clone(); 2179 CHECK(clone != NULL); 2180 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 2181 2182 CHECK(mBuffer != NULL); 2183 mBuffer->set_range( 2184 mBuffer->range_offset() + mNALLengthSize + nal_size, 2185 mBuffer->range_length() - mNALLengthSize - nal_size); 2186 2187 if (mBuffer->range_length() == 0) { 2188 mBuffer->release(); 2189 mBuffer = NULL; 2190 } 2191 2192 *out = clone; 2193 2194 return OK; 2195 } else { 2196 // Whole NAL units are returned but each fragment is prefixed by 2197 // the start code (0x00 00 00 01). 2198 ssize_t num_bytes_read = 0; 2199 int32_t drm = 0; 2200 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 2201 if (usesDRM) { 2202 num_bytes_read = 2203 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 2204 } else { 2205 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2206 } 2207 2208 if (num_bytes_read < (ssize_t)size) { 2209 mBuffer->release(); 2210 mBuffer = NULL; 2211 2212 return ERROR_IO; 2213 } 2214 2215 if (usesDRM) { 2216 CHECK(mBuffer != NULL); 2217 mBuffer->set_range(0, size); 2218 2219 } else { 2220 uint8_t *dstData = (uint8_t *)mBuffer->data(); 2221 size_t srcOffset = 0; 2222 size_t dstOffset = 0; 2223 2224 while (srcOffset < size) { 2225 bool isMalFormed = (srcOffset + mNALLengthSize > size); 2226 size_t nalLength = 0; 2227 if (!isMalFormed) { 2228 nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 2229 srcOffset += mNALLengthSize; 2230 isMalFormed = srcOffset + nalLength > size; 2231 } 2232 2233 if (isMalFormed) { 2234 ALOGE("Video is malformed"); 2235 mBuffer->release(); 2236 mBuffer = NULL; 2237 return ERROR_MALFORMED; 2238 } 2239 2240 if (nalLength == 0) { 2241 continue; 2242 } 2243 2244 CHECK(dstOffset + 4 <= mBuffer->size()); 2245 2246 dstData[dstOffset++] = 0; 2247 dstData[dstOffset++] = 0; 2248 dstData[dstOffset++] = 0; 2249 dstData[dstOffset++] = 1; 2250 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2251 srcOffset += nalLength; 2252 dstOffset += nalLength; 2253 } 2254 CHECK_EQ(srcOffset, size); 2255 CHECK(mBuffer != NULL); 2256 mBuffer->set_range(0, dstOffset); 2257 } 2258 2259 mBuffer->meta_data()->clear(); 2260 mBuffer->meta_data()->setInt64( 2261 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2262 2263 if (targetSampleTimeUs >= 0) { 2264 mBuffer->meta_data()->setInt64( 2265 kKeyTargetTime, targetSampleTimeUs); 2266 } 2267 2268 if (isSyncSample) { 2269 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2270 } 2271 2272 ++mCurrentSampleIndex; 2273 2274 *out = mBuffer; 2275 mBuffer = NULL; 2276 2277 return OK; 2278 } 2279} 2280 2281MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 2282 const char *mimePrefix) { 2283 for (Track *track = mFirstTrack; track != NULL; track = track->next) { 2284 const char *mime; 2285 if (track->meta != NULL 2286 && track->meta->findCString(kKeyMIMEType, &mime) 2287 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 2288 return track; 2289 } 2290 } 2291 2292 return NULL; 2293} 2294 2295static bool LegacySniffMPEG4( 2296 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 2297 uint8_t header[8]; 2298 2299 ssize_t n = source->readAt(4, header, sizeof(header)); 2300 if (n < (ssize_t)sizeof(header)) { 2301 return false; 2302 } 2303 2304 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2305 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2306 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 2307 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2308 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2309 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 2310 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2311 *confidence = 0.4; 2312 2313 return true; 2314 } 2315 2316 return false; 2317} 2318 2319static bool isCompatibleBrand(uint32_t fourcc) { 2320 static const uint32_t kCompatibleBrands[] = { 2321 FOURCC('i', 's', 'o', 'm'), 2322 FOURCC('i', 's', 'o', '2'), 2323 FOURCC('a', 'v', 'c', '1'), 2324 FOURCC('3', 'g', 'p', '4'), 2325 FOURCC('m', 'p', '4', '1'), 2326 FOURCC('m', 'p', '4', '2'), 2327 2328 // Won't promise that the following file types can be played. 2329 // Just give these file types a chance. 2330 FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 2331 FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 2332 2333 FOURCC('3', 'g', '2', 'a'), // 3GPP2 2334 FOURCC('3', 'g', '2', 'b'), 2335 }; 2336 2337 for (size_t i = 0; 2338 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 2339 ++i) { 2340 if (kCompatibleBrands[i] == fourcc) { 2341 return true; 2342 } 2343 } 2344 2345 return false; 2346} 2347 2348// Attempt to actually parse the 'ftyp' atom and determine if a suitable 2349// compatible brand is present. 2350// Also try to identify where this file's metadata ends 2351// (end of the 'moov' atom) and report it to the caller as part of 2352// the metadata. 2353static bool BetterSniffMPEG4( 2354 const sp<DataSource> &source, String8 *mimeType, float *confidence, 2355 sp<AMessage> *meta) { 2356 // We scan up to 128 bytes to identify this file as an MP4. 2357 static const off64_t kMaxScanOffset = 128ll; 2358 2359 off64_t offset = 0ll; 2360 bool foundGoodFileType = false; 2361 off64_t moovAtomEndOffset = -1ll; 2362 bool done = false; 2363 2364 while (!done && offset < kMaxScanOffset) { 2365 uint32_t hdr[2]; 2366 if (source->readAt(offset, hdr, 8) < 8) { 2367 return false; 2368 } 2369 2370 uint64_t chunkSize = ntohl(hdr[0]); 2371 uint32_t chunkType = ntohl(hdr[1]); 2372 off64_t chunkDataOffset = offset + 8; 2373 2374 if (chunkSize == 1) { 2375 if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 2376 return false; 2377 } 2378 2379 chunkSize = ntoh64(chunkSize); 2380 chunkDataOffset += 8; 2381 2382 if (chunkSize < 16) { 2383 // The smallest valid chunk is 16 bytes long in this case. 2384 return false; 2385 } 2386 } else if (chunkSize < 8) { 2387 // The smallest valid chunk is 8 bytes long. 2388 return false; 2389 } 2390 2391 off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 2392 2393 switch (chunkType) { 2394 case FOURCC('f', 't', 'y', 'p'): 2395 { 2396 if (chunkDataSize < 8) { 2397 return false; 2398 } 2399 2400 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 2401 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 2402 if (i == 1) { 2403 // Skip this index, it refers to the minorVersion, 2404 // not a brand. 2405 continue; 2406 } 2407 2408 uint32_t brand; 2409 if (source->readAt( 2410 chunkDataOffset + 4 * i, &brand, 4) < 4) { 2411 return false; 2412 } 2413 2414 brand = ntohl(brand); 2415 2416 if (isCompatibleBrand(brand)) { 2417 foundGoodFileType = true; 2418 break; 2419 } 2420 } 2421 2422 if (!foundGoodFileType) { 2423 return false; 2424 } 2425 2426 break; 2427 } 2428 2429 case FOURCC('m', 'o', 'o', 'v'): 2430 { 2431 moovAtomEndOffset = offset + chunkSize; 2432 2433 done = true; 2434 break; 2435 } 2436 2437 default: 2438 break; 2439 } 2440 2441 offset += chunkSize; 2442 } 2443 2444 if (!foundGoodFileType) { 2445 return false; 2446 } 2447 2448 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2449 *confidence = 0.4f; 2450 2451 if (moovAtomEndOffset >= 0) { 2452 *meta = new AMessage; 2453 (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 2454 2455 ALOGV("found metadata size: %lld", moovAtomEndOffset); 2456 } 2457 2458 return true; 2459} 2460 2461bool SniffMPEG4( 2462 const sp<DataSource> &source, String8 *mimeType, float *confidence, 2463 sp<AMessage> *meta) { 2464 if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 2465 return true; 2466 } 2467 2468 if (LegacySniffMPEG4(source, mimeType, confidence)) { 2469 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 2470 return true; 2471 } 2472 2473 return false; 2474} 2475 2476} // namespace android 2477