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