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