MPEG4Extractor.cpp revision 170056540e9ce65261b45efd15f67e72e2df1bed
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "MPEG4Extractor" 19#include <utils/Log.h> 20 21#include "include/MPEG4Extractor.h" 22#include "include/SampleTable.h" 23#include "include/ESDS.h" 24 25#include <ctype.h> 26#include <stdint.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include <media/stagefright/foundation/ABitReader.h> 31#include <media/stagefright/foundation/ABuffer.h> 32#include <media/stagefright/foundation/ADebug.h> 33#include <media/stagefright/foundation/AMessage.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 <utils/String8.h> 40 41#include <byteswap.h> 42#include "include/ID3.h" 43 44namespace android { 45 46class MPEG4Source : public MediaSource { 47public: 48 // Caller retains ownership of both "dataSource" and "sampleTable". 49 MPEG4Source(const sp<MetaData> &format, 50 const sp<DataSource> &dataSource, 51 int32_t timeScale, 52 const sp<SampleTable> &sampleTable, 53 Vector<SidxEntry> &sidx, 54 off64_t firstMoofOffset); 55 56 virtual status_t start(MetaData *params = NULL); 57 virtual status_t stop(); 58 59 virtual sp<MetaData> getFormat(); 60 61 virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); 62 virtual status_t fragmentedRead(MediaBuffer **buffer, const ReadOptions *options = NULL); 63 64protected: 65 virtual ~MPEG4Source(); 66 67private: 68 Mutex mLock; 69 70 sp<MetaData> mFormat; 71 sp<DataSource> mDataSource; 72 int32_t mTimescale; 73 sp<SampleTable> mSampleTable; 74 uint32_t mCurrentSampleIndex; 75 uint32_t mCurrentFragmentIndex; 76 Vector<SidxEntry> &mSegments; 77 off64_t mFirstMoofOffset; 78 off64_t mCurrentMoofOffset; 79 off64_t mNextMoofOffset; 80 uint32_t mCurrentTime; 81 int32_t mLastParsedTrackId; 82 int32_t mTrackId; 83 84 int32_t mCryptoMode; // passed in from extractor 85 int32_t mDefaultIVSize; // passed in from extractor 86 uint8_t mCryptoKey[16]; // passed in from extractor 87 uint32_t mCurrentAuxInfoType; 88 uint32_t mCurrentAuxInfoTypeParameter; 89 int32_t mCurrentDefaultSampleInfoSize; 90 uint32_t mCurrentSampleInfoCount; 91 uint32_t mCurrentSampleInfoAllocSize; 92 uint8_t* mCurrentSampleInfoSizes; 93 uint32_t mCurrentSampleInfoOffsetCount; 94 uint32_t mCurrentSampleInfoOffsetsAllocSize; 95 uint64_t* mCurrentSampleInfoOffsets; 96 97 bool mIsAVC; 98 size_t mNALLengthSize; 99 100 bool mStarted; 101 102 MediaBufferGroup *mGroup; 103 104 MediaBuffer *mBuffer; 105 106 bool mWantsNALFragments; 107 108 uint8_t *mSrcBuffer; 109 110 size_t parseNALSize(const uint8_t *data) const; 111 status_t parseChunk(off64_t *offset); 112 status_t parseTrackFragmentHeader(off64_t offset, off64_t size); 113 status_t parseTrackFragmentRun(off64_t offset, off64_t size); 114 status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size); 115 status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size); 116 117 struct TrackFragmentHeaderInfo { 118 enum Flags { 119 kBaseDataOffsetPresent = 0x01, 120 kSampleDescriptionIndexPresent = 0x02, 121 kDefaultSampleDurationPresent = 0x08, 122 kDefaultSampleSizePresent = 0x10, 123 kDefaultSampleFlagsPresent = 0x20, 124 kDurationIsEmpty = 0x10000, 125 }; 126 127 uint32_t mTrackID; 128 uint32_t mFlags; 129 uint64_t mBaseDataOffset; 130 uint32_t mSampleDescriptionIndex; 131 uint32_t mDefaultSampleDuration; 132 uint32_t mDefaultSampleSize; 133 uint32_t mDefaultSampleFlags; 134 135 uint64_t mDataOffset; 136 }; 137 TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; 138 139 struct Sample { 140 off64_t offset; 141 size_t size; 142 uint32_t duration; 143 uint8_t iv[16]; 144 Vector<size_t> clearsizes; 145 Vector<size_t> encryptedsizes; 146 }; 147 Vector<Sample> mCurrentSamples; 148 149 MPEG4Source(const MPEG4Source &); 150 MPEG4Source &operator=(const MPEG4Source &); 151}; 152 153// This custom data source wraps an existing one and satisfies requests 154// falling entirely within a cached range from the cache while forwarding 155// all remaining requests to the wrapped datasource. 156// This is used to cache the full sampletable metadata for a single track, 157// possibly wrapping multiple times to cover all tracks, i.e. 158// Each MPEG4DataSource caches the sampletable metadata for a single track. 159 160struct MPEG4DataSource : public DataSource { 161 MPEG4DataSource(const sp<DataSource> &source); 162 163 virtual status_t initCheck() const; 164 virtual ssize_t readAt(off64_t offset, void *data, size_t size); 165 virtual status_t getSize(off64_t *size); 166 virtual uint32_t flags(); 167 168 status_t setCachedRange(off64_t offset, size_t size); 169 170protected: 171 virtual ~MPEG4DataSource(); 172 173private: 174 Mutex mLock; 175 176 sp<DataSource> mSource; 177 off64_t mCachedOffset; 178 size_t mCachedSize; 179 uint8_t *mCache; 180 181 void clearCache(); 182 183 MPEG4DataSource(const MPEG4DataSource &); 184 MPEG4DataSource &operator=(const MPEG4DataSource &); 185}; 186 187MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 188 : mSource(source), 189 mCachedOffset(0), 190 mCachedSize(0), 191 mCache(NULL) { 192} 193 194MPEG4DataSource::~MPEG4DataSource() { 195 clearCache(); 196} 197 198void MPEG4DataSource::clearCache() { 199 if (mCache) { 200 free(mCache); 201 mCache = NULL; 202 } 203 204 mCachedOffset = 0; 205 mCachedSize = 0; 206} 207 208status_t MPEG4DataSource::initCheck() const { 209 return mSource->initCheck(); 210} 211 212ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 213 Mutex::Autolock autoLock(mLock); 214 215 if (offset >= mCachedOffset 216 && offset + size <= mCachedOffset + mCachedSize) { 217 memcpy(data, &mCache[offset - mCachedOffset], size); 218 return size; 219 } 220 221 return mSource->readAt(offset, data, size); 222} 223 224status_t MPEG4DataSource::getSize(off64_t *size) { 225 return mSource->getSize(size); 226} 227 228uint32_t MPEG4DataSource::flags() { 229 return mSource->flags(); 230} 231 232status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 233 Mutex::Autolock autoLock(mLock); 234 235 clearCache(); 236 237 mCache = (uint8_t *)malloc(size); 238 239 if (mCache == NULL) { 240 return -ENOMEM; 241 } 242 243 mCachedOffset = offset; 244 mCachedSize = size; 245 246 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 247 248 if (err < (ssize_t)size) { 249 clearCache(); 250 251 return ERROR_IO; 252 } 253 254 return OK; 255} 256 257//////////////////////////////////////////////////////////////////////////////// 258 259static void hexdump(const void *_data, size_t size) { 260 const uint8_t *data = (const uint8_t *)_data; 261 size_t offset = 0; 262 while (offset < size) { 263 printf("0x%04zx ", offset); 264 265 size_t n = size - offset; 266 if (n > 16) { 267 n = 16; 268 } 269 270 for (size_t i = 0; i < 16; ++i) { 271 if (i == 8) { 272 printf(" "); 273 } 274 275 if (offset + i < size) { 276 printf("%02x ", data[offset + i]); 277 } else { 278 printf(" "); 279 } 280 } 281 282 printf(" "); 283 284 for (size_t i = 0; i < n; ++i) { 285 if (isprint(data[offset + i])) { 286 printf("%c", data[offset + i]); 287 } else { 288 printf("."); 289 } 290 } 291 292 printf("\n"); 293 294 offset += 16; 295 } 296} 297 298static const char *FourCC2MIME(uint32_t fourcc) { 299 switch (fourcc) { 300 case FOURCC('m', 'p', '4', 'a'): 301 return MEDIA_MIMETYPE_AUDIO_AAC; 302 303 case FOURCC('s', 'a', 'm', 'r'): 304 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 305 306 case FOURCC('s', 'a', 'w', 'b'): 307 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 308 309 case FOURCC('m', 'p', '4', 'v'): 310 return MEDIA_MIMETYPE_VIDEO_MPEG4; 311 312 case FOURCC('s', '2', '6', '3'): 313 case FOURCC('h', '2', '6', '3'): 314 case FOURCC('H', '2', '6', '3'): 315 return MEDIA_MIMETYPE_VIDEO_H263; 316 317 case FOURCC('a', 'v', 'c', '1'): 318 return MEDIA_MIMETYPE_VIDEO_AVC; 319 320 default: 321 CHECK(!"should not be here."); 322 return NULL; 323 } 324} 325 326static bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) { 327 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) { 328 // AMR NB audio is always mono, 8kHz 329 *channels = 1; 330 *rate = 8000; 331 return true; 332 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) { 333 // AMR WB audio is always mono, 16kHz 334 *channels = 1; 335 *rate = 16000; 336 return true; 337 } 338 return false; 339} 340 341MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 342 : mSidxDuration(0), 343 mMoofOffset(0), 344 mDataSource(source), 345 mInitCheck(NO_INIT), 346 mHasVideo(false), 347 mHeaderTimescale(0), 348 mFirstTrack(NULL), 349 mLastTrack(NULL), 350 mFileMetaData(new MetaData), 351 mFirstSINF(NULL), 352 mIsDrm(false) { 353} 354 355MPEG4Extractor::~MPEG4Extractor() { 356 Track *track = mFirstTrack; 357 while (track) { 358 Track *next = track->next; 359 360 delete track; 361 track = next; 362 } 363 mFirstTrack = mLastTrack = NULL; 364 365 SINF *sinf = mFirstSINF; 366 while (sinf) { 367 SINF *next = sinf->next; 368 delete sinf->IPMPData; 369 delete sinf; 370 sinf = next; 371 } 372 mFirstSINF = NULL; 373 374 for (size_t i = 0; i < mPssh.size(); i++) { 375 delete [] mPssh[i].data; 376 } 377} 378 379uint32_t MPEG4Extractor::flags() const { 380 return CAN_PAUSE | 381 ((mMoofOffset == 0 || mSidxEntries.size() != 0) ? 382 (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0); 383} 384 385sp<MetaData> MPEG4Extractor::getMetaData() { 386 status_t err; 387 if ((err = readMetaData()) != OK) { 388 return new MetaData; 389 } 390 391 return mFileMetaData; 392} 393 394size_t MPEG4Extractor::countTracks() { 395 status_t err; 396 if ((err = readMetaData()) != OK) { 397 ALOGV("MPEG4Extractor::countTracks: no tracks"); 398 return 0; 399 } 400 401 size_t n = 0; 402 Track *track = mFirstTrack; 403 while (track) { 404 ++n; 405 track = track->next; 406 } 407 408 ALOGV("MPEG4Extractor::countTracks: %d tracks", n); 409 return n; 410} 411 412sp<MetaData> MPEG4Extractor::getTrackMetaData( 413 size_t index, uint32_t flags) { 414 status_t err; 415 if ((err = readMetaData()) != OK) { 416 return NULL; 417 } 418 419 Track *track = mFirstTrack; 420 while (index > 0) { 421 if (track == NULL) { 422 return NULL; 423 } 424 425 track = track->next; 426 --index; 427 } 428 429 if (track == NULL) { 430 return NULL; 431 } 432 433 if ((flags & kIncludeExtensiveMetaData) 434 && !track->includes_expensive_metadata) { 435 track->includes_expensive_metadata = true; 436 437 const char *mime; 438 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 439 if (!strncasecmp("video/", mime, 6)) { 440 if (mMoofOffset > 0) { 441 int64_t duration; 442 if (track->meta->findInt64(kKeyDuration, &duration)) { 443 // nothing fancy, just pick a frame near 1/4th of the duration 444 track->meta->setInt64( 445 kKeyThumbnailTime, duration / 4); 446 } 447 } else { 448 uint32_t sampleIndex; 449 uint32_t sampleTime; 450 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 451 && track->sampleTable->getMetaDataForSample( 452 sampleIndex, NULL /* offset */, NULL /* size */, 453 &sampleTime) == OK) { 454 track->meta->setInt64( 455 kKeyThumbnailTime, 456 ((int64_t)sampleTime * 1000000) / track->timescale); 457 } 458 } 459 } 460 } 461 462 return track->meta; 463} 464 465static void MakeFourCCString(uint32_t x, char *s) { 466 s[0] = x >> 24; 467 s[1] = (x >> 16) & 0xff; 468 s[2] = (x >> 8) & 0xff; 469 s[3] = x & 0xff; 470 s[4] = '\0'; 471} 472 473status_t MPEG4Extractor::readMetaData() { 474 if (mInitCheck != NO_INIT) { 475 return mInitCheck; 476 } 477 478 off64_t offset = 0; 479 status_t err; 480 while (true) { 481 err = parseChunk(&offset, 0); 482 if (err == OK) { 483 continue; 484 } 485 486 uint32_t hdr[2]; 487 if (mDataSource->readAt(offset, hdr, 8) < 8) { 488 break; 489 } 490 uint32_t chunk_type = ntohl(hdr[1]); 491 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 492 // store the offset of the first segment 493 mMoofOffset = offset; 494 } else if (chunk_type != FOURCC('m', 'd', 'a', 't')) { 495 // keep parsing until we get to the data 496 continue; 497 } 498 break; 499 } 500 501 if (mInitCheck == OK) { 502 if (mHasVideo) { 503 mFileMetaData->setCString( 504 kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4); 505 } else { 506 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 507 } 508 509 mInitCheck = OK; 510 } else { 511 mInitCheck = err; 512 } 513 514 CHECK_NE(err, (status_t)NO_INIT); 515 516 // copy pssh data into file metadata 517 int psshsize = 0; 518 for (size_t i = 0; i < mPssh.size(); i++) { 519 psshsize += 20 + mPssh[i].datalen; 520 } 521 if (psshsize) { 522 char *buf = (char*)malloc(psshsize); 523 char *ptr = buf; 524 for (size_t i = 0; i < mPssh.size(); i++) { 525 memcpy(ptr, mPssh[i].uuid, 20); // uuid + length 526 memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen); 527 ptr += (20 + mPssh[i].datalen); 528 } 529 mFileMetaData->setData(kKeyPssh, 'pssh', buf, psshsize); 530 free(buf); 531 } 532 return mInitCheck; 533} 534 535char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 536 if (mFirstSINF == NULL) { 537 return NULL; 538 } 539 540 SINF *sinf = mFirstSINF; 541 while (sinf && (trackID != sinf->trackID)) { 542 sinf = sinf->next; 543 } 544 545 if (sinf == NULL) { 546 return NULL; 547 } 548 549 *len = sinf->len; 550 return sinf->IPMPData; 551} 552 553// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 554static int32_t readSize(off64_t offset, 555 const sp<DataSource> DataSource, uint8_t *numOfBytes) { 556 uint32_t size = 0; 557 uint8_t data; 558 bool moreData = true; 559 *numOfBytes = 0; 560 561 while (moreData) { 562 if (DataSource->readAt(offset, &data, 1) < 1) { 563 return -1; 564 } 565 offset ++; 566 moreData = (data >= 128) ? true : false; 567 size = (size << 7) | (data & 0x7f); // Take last 7 bits 568 (*numOfBytes) ++; 569 } 570 571 return size; 572} 573 574status_t MPEG4Extractor::parseDrmSINF( 575 off64_t * /* offset */, off64_t data_offset) { 576 uint8_t updateIdTag; 577 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 578 return ERROR_IO; 579 } 580 data_offset ++; 581 582 if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 583 return ERROR_MALFORMED; 584 } 585 586 uint8_t numOfBytes; 587 int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 588 if (size < 0) { 589 return ERROR_IO; 590 } 591 int32_t classSize = size; 592 data_offset += numOfBytes; 593 594 while(size >= 11 ) { 595 uint8_t descriptorTag; 596 if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 597 return ERROR_IO; 598 } 599 data_offset ++; 600 601 if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 602 return ERROR_MALFORMED; 603 } 604 605 uint8_t buffer[8]; 606 //ObjectDescriptorID and ObjectDescriptor url flag 607 if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 608 return ERROR_IO; 609 } 610 data_offset += 2; 611 612 if ((buffer[1] >> 5) & 0x0001) { //url flag is set 613 return ERROR_MALFORMED; 614 } 615 616 if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 617 return ERROR_IO; 618 } 619 data_offset += 8; 620 621 if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 622 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 623 return ERROR_MALFORMED; 624 } 625 626 SINF *sinf = new SINF; 627 sinf->trackID = U16_AT(&buffer[3]); 628 sinf->IPMPDescriptorID = buffer[7]; 629 sinf->next = mFirstSINF; 630 mFirstSINF = sinf; 631 632 size -= (8 + 2 + 1); 633 } 634 635 if (size != 0) { 636 return ERROR_MALFORMED; 637 } 638 639 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 640 return ERROR_IO; 641 } 642 data_offset ++; 643 644 if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 645 return ERROR_MALFORMED; 646 } 647 648 size = readSize(data_offset, mDataSource, &numOfBytes); 649 if (size < 0) { 650 return ERROR_IO; 651 } 652 classSize = size; 653 data_offset += numOfBytes; 654 655 while (size > 0) { 656 uint8_t tag; 657 int32_t dataLen; 658 if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 659 return ERROR_IO; 660 } 661 data_offset ++; 662 663 if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 664 uint8_t id; 665 dataLen = readSize(data_offset, mDataSource, &numOfBytes); 666 if (dataLen < 0) { 667 return ERROR_IO; 668 } else if (dataLen < 4) { 669 return ERROR_MALFORMED; 670 } 671 data_offset += numOfBytes; 672 673 if (mDataSource->readAt(data_offset, &id, 1) < 1) { 674 return ERROR_IO; 675 } 676 data_offset ++; 677 678 SINF *sinf = mFirstSINF; 679 while (sinf && (sinf->IPMPDescriptorID != id)) { 680 sinf = sinf->next; 681 } 682 if (sinf == NULL) { 683 return ERROR_MALFORMED; 684 } 685 sinf->len = dataLen - 3; 686 sinf->IPMPData = new char[sinf->len]; 687 data_offset += 2; 688 689 if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { 690 return ERROR_IO; 691 } 692 data_offset += sinf->len; 693 694 size -= (dataLen + numOfBytes + 1); 695 } 696 } 697 698 if (size != 0) { 699 return ERROR_MALFORMED; 700 } 701 702 return UNKNOWN_ERROR; // Return a dummy error. 703} 704 705struct PathAdder { 706 PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 707 : mPath(path) { 708 mPath->push(chunkType); 709 } 710 711 ~PathAdder() { 712 mPath->pop(); 713 } 714 715private: 716 Vector<uint32_t> *mPath; 717 718 PathAdder(const PathAdder &); 719 PathAdder &operator=(const PathAdder &); 720}; 721 722static bool underMetaDataPath(const Vector<uint32_t> &path) { 723 return path.size() >= 5 724 && path[0] == FOURCC('m', 'o', 'o', 'v') 725 && path[1] == FOURCC('u', 'd', 't', 'a') 726 && path[2] == FOURCC('m', 'e', 't', 'a') 727 && path[3] == FOURCC('i', 'l', 's', 't'); 728} 729 730// Given a time in seconds since Jan 1 1904, produce a human-readable string. 731static void convertTimeToDate(int64_t time_1904, String8 *s) { 732 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 733 734 char tmp[32]; 735 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 736 737 s->setTo(tmp); 738} 739 740status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 741 ALOGV("entering parseChunk %lld/%d", *offset, depth); 742 uint32_t hdr[2]; 743 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 744 return ERROR_IO; 745 } 746 uint64_t chunk_size = ntohl(hdr[0]); 747 uint32_t chunk_type = ntohl(hdr[1]); 748 off64_t data_offset = *offset + 8; 749 750 if (chunk_size == 1) { 751 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 752 return ERROR_IO; 753 } 754 chunk_size = ntoh64(chunk_size); 755 data_offset += 8; 756 757 if (chunk_size < 16) { 758 // The smallest valid chunk is 16 bytes long in this case. 759 return ERROR_MALFORMED; 760 } 761 } else if (chunk_size < 8) { 762 // The smallest valid chunk is 8 bytes long. 763 return ERROR_MALFORMED; 764 } 765 766 char chunk[5]; 767 MakeFourCCString(chunk_type, chunk); 768 ALOGV("chunk: %s @ %lld, %d", chunk, *offset, depth); 769 770#if 0 771 static const char kWhitespace[] = " "; 772 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 773 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 774 775 char buffer[256]; 776 size_t n = chunk_size; 777 if (n > sizeof(buffer)) { 778 n = sizeof(buffer); 779 } 780 if (mDataSource->readAt(*offset, buffer, n) 781 < (ssize_t)n) { 782 return ERROR_IO; 783 } 784 785 hexdump(buffer, n); 786#endif 787 788 PathAdder autoAdder(&mPath, chunk_type); 789 790 off64_t chunk_data_size = *offset + chunk_size - data_offset; 791 792 if (chunk_type != FOURCC('c', 'p', 'r', 't') 793 && chunk_type != FOURCC('c', 'o', 'v', 'r') 794 && mPath.size() == 5 && underMetaDataPath(mPath)) { 795 off64_t stop_offset = *offset + chunk_size; 796 *offset = data_offset; 797 while (*offset < stop_offset) { 798 status_t err = parseChunk(offset, depth + 1); 799 if (err != OK) { 800 return err; 801 } 802 } 803 804 if (*offset != stop_offset) { 805 return ERROR_MALFORMED; 806 } 807 808 return OK; 809 } 810 811 switch(chunk_type) { 812 case FOURCC('m', 'o', 'o', 'v'): 813 case FOURCC('t', 'r', 'a', 'k'): 814 case FOURCC('m', 'd', 'i', 'a'): 815 case FOURCC('m', 'i', 'n', 'f'): 816 case FOURCC('d', 'i', 'n', 'f'): 817 case FOURCC('s', 't', 'b', 'l'): 818 case FOURCC('m', 'v', 'e', 'x'): 819 case FOURCC('m', 'o', 'o', 'f'): 820 case FOURCC('t', 'r', 'a', 'f'): 821 case FOURCC('m', 'f', 'r', 'a'): 822 case FOURCC('u', 'd', 't', 'a'): 823 case FOURCC('i', 'l', 's', 't'): 824 case FOURCC('s', 'i', 'n', 'f'): 825 case FOURCC('s', 'c', 'h', 'i'): 826 case FOURCC('e', 'd', 't', 's'): 827 { 828 if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 829 ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 830 831 if (mDataSource->flags() 832 & (DataSource::kWantsPrefetching 833 | DataSource::kIsCachingDataSource)) { 834 sp<MPEG4DataSource> cachedSource = 835 new MPEG4DataSource(mDataSource); 836 837 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 838 mDataSource = cachedSource; 839 } 840 } 841 842 mLastTrack->sampleTable = new SampleTable(mDataSource); 843 } 844 845 bool isTrack = false; 846 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 847 isTrack = true; 848 849 Track *track = new Track; 850 track->next = NULL; 851 if (mLastTrack) { 852 mLastTrack->next = track; 853 } else { 854 mFirstTrack = track; 855 } 856 mLastTrack = track; 857 858 track->meta = new MetaData; 859 track->includes_expensive_metadata = false; 860 track->skipTrack = false; 861 track->timescale = 0; 862 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 863 } 864 865 off64_t stop_offset = *offset + chunk_size; 866 *offset = data_offset; 867 while (*offset < stop_offset) { 868 status_t err = parseChunk(offset, depth + 1); 869 if (err != OK) { 870 return err; 871 } 872 } 873 874 if (*offset != stop_offset) { 875 return ERROR_MALFORMED; 876 } 877 878 if (isTrack) { 879 if (mLastTrack->skipTrack) { 880 Track *cur = mFirstTrack; 881 882 if (cur == mLastTrack) { 883 delete cur; 884 mFirstTrack = mLastTrack = NULL; 885 } else { 886 while (cur && cur->next != mLastTrack) { 887 cur = cur->next; 888 } 889 cur->next = NULL; 890 delete mLastTrack; 891 mLastTrack = cur; 892 } 893 894 return OK; 895 } 896 897 status_t err = verifyTrack(mLastTrack); 898 899 if (err != OK) { 900 return err; 901 } 902 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 903 mInitCheck = OK; 904 905 if (!mIsDrm) { 906 return UNKNOWN_ERROR; // Return a dummy error. 907 } else { 908 return OK; 909 } 910 } 911 break; 912 } 913 914 case FOURCC('e', 'l', 's', 't'): 915 { 916 *offset += chunk_size; 917 918 // See 14496-12 8.6.6 919 uint8_t version; 920 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 921 return ERROR_IO; 922 } 923 924 uint32_t entry_count; 925 if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) { 926 return ERROR_IO; 927 } 928 929 if (entry_count != 1) { 930 // we only support a single entry at the moment, for gapless playback 931 ALOGW("ignoring edit list with %d entries", entry_count); 932 } else if (mHeaderTimescale == 0) { 933 ALOGW("ignoring edit list because timescale is 0"); 934 } else { 935 off64_t entriesoffset = data_offset + 8; 936 uint64_t segment_duration; 937 int64_t media_time; 938 939 if (version == 1) { 940 if (!mDataSource->getUInt64(entriesoffset, &segment_duration) || 941 !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) { 942 return ERROR_IO; 943 } 944 } else if (version == 0) { 945 uint32_t sd; 946 int32_t mt; 947 if (!mDataSource->getUInt32(entriesoffset, &sd) || 948 !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) { 949 return ERROR_IO; 950 } 951 segment_duration = sd; 952 media_time = mt; 953 } else { 954 return ERROR_IO; 955 } 956 957 uint64_t halfscale = mHeaderTimescale / 2; 958 segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale; 959 media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale; 960 961 int64_t duration; 962 int32_t samplerate; 963 if (mLastTrack->meta->findInt64(kKeyDuration, &duration) && 964 mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) { 965 966 int64_t delay = (media_time * samplerate + 500000) / 1000000; 967 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 968 969 int64_t paddingus = duration - (segment_duration + media_time); 970 if (paddingus < 0) { 971 // track duration from media header (which is what kKeyDuration is) might 972 // be slightly shorter than the segment duration, which would make the 973 // padding negative. Clamp to zero. 974 paddingus = 0; 975 } 976 int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; 977 mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); 978 } 979 } 980 break; 981 } 982 983 case FOURCC('f', 'r', 'm', 'a'): 984 { 985 *offset += chunk_size; 986 987 uint32_t original_fourcc; 988 if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) { 989 return ERROR_IO; 990 } 991 original_fourcc = ntohl(original_fourcc); 992 ALOGV("read original format: %d", original_fourcc); 993 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(original_fourcc)); 994 uint32_t num_channels = 0; 995 uint32_t sample_rate = 0; 996 if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) { 997 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 998 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 999 } 1000 break; 1001 } 1002 1003 case FOURCC('t', 'e', 'n', 'c'): 1004 { 1005 *offset += chunk_size; 1006 1007 if (chunk_size < 32) { 1008 return ERROR_MALFORMED; 1009 } 1010 1011 // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte 1012 // default IV size, 16 bytes default KeyID 1013 // (ISO 23001-7) 1014 char buf[4]; 1015 memset(buf, 0, 4); 1016 if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) { 1017 return ERROR_IO; 1018 } 1019 uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf)); 1020 if (defaultAlgorithmId > 1) { 1021 // only 0 (clear) and 1 (AES-128) are valid 1022 return ERROR_MALFORMED; 1023 } 1024 1025 memset(buf, 0, 4); 1026 if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) { 1027 return ERROR_IO; 1028 } 1029 uint32_t defaultIVSize = ntohl(*((int32_t*)buf)); 1030 1031 if ((defaultAlgorithmId == 0 && defaultIVSize != 0) || 1032 (defaultAlgorithmId != 0 && defaultIVSize == 0)) { 1033 // only unencrypted data must have 0 IV size 1034 return ERROR_MALFORMED; 1035 } else if (defaultIVSize != 0 && 1036 defaultIVSize != 8 && 1037 defaultIVSize != 16) { 1038 // only supported sizes are 0, 8 and 16 1039 return ERROR_MALFORMED; 1040 } 1041 1042 uint8_t defaultKeyId[16]; 1043 1044 if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) { 1045 return ERROR_IO; 1046 } 1047 1048 mLastTrack->meta->setInt32(kKeyCryptoMode, defaultAlgorithmId); 1049 mLastTrack->meta->setInt32(kKeyCryptoDefaultIVSize, defaultIVSize); 1050 mLastTrack->meta->setData(kKeyCryptoKey, 'tenc', defaultKeyId, 16); 1051 break; 1052 } 1053 1054 case FOURCC('t', 'k', 'h', 'd'): 1055 { 1056 *offset += chunk_size; 1057 1058 status_t err; 1059 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 1060 return err; 1061 } 1062 1063 break; 1064 } 1065 1066 case FOURCC('p', 's', 's', 'h'): 1067 { 1068 *offset += chunk_size; 1069 1070 PsshInfo pssh; 1071 1072 if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) { 1073 return ERROR_IO; 1074 } 1075 1076 uint32_t psshdatalen = 0; 1077 if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) { 1078 return ERROR_IO; 1079 } 1080 pssh.datalen = ntohl(psshdatalen); 1081 ALOGV("pssh data size: %d", pssh.datalen); 1082 if (pssh.datalen + 20 > chunk_size) { 1083 // pssh data length exceeds size of containing box 1084 return ERROR_MALFORMED; 1085 } 1086 1087 pssh.data = new uint8_t[pssh.datalen]; 1088 ALOGV("allocated pssh @ %p", pssh.data); 1089 ssize_t requested = (ssize_t) pssh.datalen; 1090 if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) { 1091 return ERROR_IO; 1092 } 1093 mPssh.push_back(pssh); 1094 1095 break; 1096 } 1097 1098 case FOURCC('m', 'd', 'h', 'd'): 1099 { 1100 *offset += chunk_size; 1101 1102 if (chunk_data_size < 4) { 1103 return ERROR_MALFORMED; 1104 } 1105 1106 uint8_t version; 1107 if (mDataSource->readAt( 1108 data_offset, &version, sizeof(version)) 1109 < (ssize_t)sizeof(version)) { 1110 return ERROR_IO; 1111 } 1112 1113 off64_t timescale_offset; 1114 1115 if (version == 1) { 1116 timescale_offset = data_offset + 4 + 16; 1117 } else if (version == 0) { 1118 timescale_offset = data_offset + 4 + 8; 1119 } else { 1120 return ERROR_IO; 1121 } 1122 1123 uint32_t timescale; 1124 if (mDataSource->readAt( 1125 timescale_offset, ×cale, sizeof(timescale)) 1126 < (ssize_t)sizeof(timescale)) { 1127 return ERROR_IO; 1128 } 1129 1130 mLastTrack->timescale = ntohl(timescale); 1131 1132 int64_t duration = 0; 1133 if (version == 1) { 1134 if (mDataSource->readAt( 1135 timescale_offset + 4, &duration, sizeof(duration)) 1136 < (ssize_t)sizeof(duration)) { 1137 return ERROR_IO; 1138 } 1139 duration = ntoh64(duration); 1140 } else { 1141 uint32_t duration32; 1142 if (mDataSource->readAt( 1143 timescale_offset + 4, &duration32, sizeof(duration32)) 1144 < (ssize_t)sizeof(duration32)) { 1145 return ERROR_IO; 1146 } 1147 // ffmpeg sets duration to -1, which is incorrect. 1148 if (duration32 != 0xffffffff) { 1149 duration = ntohl(duration32); 1150 } 1151 } 1152 mLastTrack->meta->setInt64( 1153 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 1154 1155 uint8_t lang[2]; 1156 off64_t lang_offset; 1157 if (version == 1) { 1158 lang_offset = timescale_offset + 4 + 8; 1159 } else if (version == 0) { 1160 lang_offset = timescale_offset + 4 + 4; 1161 } else { 1162 return ERROR_IO; 1163 } 1164 1165 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 1166 < (ssize_t)sizeof(lang)) { 1167 return ERROR_IO; 1168 } 1169 1170 // To get the ISO-639-2/T three character language code 1171 // 1 bit pad followed by 3 5-bits characters. Each character 1172 // is packed as the difference between its ASCII value and 0x60. 1173 char lang_code[4]; 1174 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 1175 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 1176 lang_code[2] = (lang[1] & 0x1f) + 0x60; 1177 lang_code[3] = '\0'; 1178 1179 mLastTrack->meta->setCString( 1180 kKeyMediaLanguage, lang_code); 1181 1182 break; 1183 } 1184 1185 case FOURCC('s', 't', 's', 'd'): 1186 { 1187 if (chunk_data_size < 8) { 1188 return ERROR_MALFORMED; 1189 } 1190 1191 uint8_t buffer[8]; 1192 if (chunk_data_size < (off64_t)sizeof(buffer)) { 1193 return ERROR_MALFORMED; 1194 } 1195 1196 if (mDataSource->readAt( 1197 data_offset, buffer, 8) < 8) { 1198 return ERROR_IO; 1199 } 1200 1201 if (U32_AT(buffer) != 0) { 1202 // Should be version 0, flags 0. 1203 return ERROR_MALFORMED; 1204 } 1205 1206 uint32_t entry_count = U32_AT(&buffer[4]); 1207 1208 if (entry_count > 1) { 1209 // For 3GPP timed text, there could be multiple tx3g boxes contain 1210 // multiple text display formats. These formats will be used to 1211 // display the timed text. 1212 // For encrypted files, there may also be more than one entry. 1213 const char *mime; 1214 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1215 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) && 1216 strcasecmp(mime, "application/octet-stream")) { 1217 // For now we only support a single type of media per track. 1218 mLastTrack->skipTrack = true; 1219 *offset += chunk_size; 1220 break; 1221 } 1222 } 1223 off64_t stop_offset = *offset + chunk_size; 1224 *offset = data_offset + 8; 1225 for (uint32_t i = 0; i < entry_count; ++i) { 1226 status_t err = parseChunk(offset, depth + 1); 1227 if (err != OK) { 1228 return err; 1229 } 1230 } 1231 1232 if (*offset != stop_offset) { 1233 return ERROR_MALFORMED; 1234 } 1235 break; 1236 } 1237 1238 case FOURCC('m', 'p', '4', 'a'): 1239 case FOURCC('e', 'n', 'c', 'a'): 1240 case FOURCC('s', 'a', 'm', 'r'): 1241 case FOURCC('s', 'a', 'w', 'b'): 1242 { 1243 uint8_t buffer[8 + 20]; 1244 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 1245 // Basic AudioSampleEntry size. 1246 return ERROR_MALFORMED; 1247 } 1248 1249 if (mDataSource->readAt( 1250 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 1251 return ERROR_IO; 1252 } 1253 1254 uint16_t data_ref_index = U16_AT(&buffer[6]); 1255 uint32_t num_channels = U16_AT(&buffer[16]); 1256 1257 uint16_t sample_size = U16_AT(&buffer[18]); 1258 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 1259 1260 if (chunk_type != FOURCC('e', 'n', 'c', 'a')) { 1261 // if the chunk type is enca, we'll get the type from the sinf/frma box later 1262 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1263 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate); 1264 } 1265 ALOGV("*** coding='%s' %d channels, size %d, rate %d\n", 1266 chunk, num_channels, sample_size, sample_rate); 1267 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 1268 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 1269 1270 off64_t stop_offset = *offset + chunk_size; 1271 *offset = data_offset + sizeof(buffer); 1272 while (*offset < stop_offset) { 1273 status_t err = parseChunk(offset, depth + 1); 1274 if (err != OK) { 1275 return err; 1276 } 1277 } 1278 1279 if (*offset != stop_offset) { 1280 return ERROR_MALFORMED; 1281 } 1282 break; 1283 } 1284 1285 case FOURCC('m', 'p', '4', 'v'): 1286 case FOURCC('e', 'n', 'c', 'v'): 1287 case FOURCC('s', '2', '6', '3'): 1288 case FOURCC('H', '2', '6', '3'): 1289 case FOURCC('h', '2', '6', '3'): 1290 case FOURCC('a', 'v', 'c', '1'): 1291 { 1292 mHasVideo = true; 1293 1294 uint8_t buffer[78]; 1295 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 1296 // Basic VideoSampleEntry size. 1297 return ERROR_MALFORMED; 1298 } 1299 1300 if (mDataSource->readAt( 1301 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 1302 return ERROR_IO; 1303 } 1304 1305 uint16_t data_ref_index = U16_AT(&buffer[6]); 1306 uint16_t width = U16_AT(&buffer[6 + 18]); 1307 uint16_t height = U16_AT(&buffer[6 + 20]); 1308 1309 // The video sample is not standard-compliant if it has invalid dimension. 1310 // Use some default width and height value, and 1311 // let the decoder figure out the actual width and height (and thus 1312 // be prepared for INFO_FOMRAT_CHANGED event). 1313 if (width == 0) width = 352; 1314 if (height == 0) height = 288; 1315 1316 // printf("*** coding='%s' width=%d height=%d\n", 1317 // chunk, width, height); 1318 1319 if (chunk_type != FOURCC('e', 'n', 'c', 'v')) { 1320 // if the chunk type is encv, we'll get the type from the sinf/frma box later 1321 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1322 } 1323 mLastTrack->meta->setInt32(kKeyWidth, width); 1324 mLastTrack->meta->setInt32(kKeyHeight, height); 1325 1326 off64_t stop_offset = *offset + chunk_size; 1327 *offset = data_offset + sizeof(buffer); 1328 while (*offset < stop_offset) { 1329 status_t err = parseChunk(offset, depth + 1); 1330 if (err != OK) { 1331 return err; 1332 } 1333 } 1334 1335 if (*offset != stop_offset) { 1336 return ERROR_MALFORMED; 1337 } 1338 break; 1339 } 1340 1341 case FOURCC('s', 't', 'c', 'o'): 1342 case FOURCC('c', 'o', '6', '4'): 1343 { 1344 status_t err = 1345 mLastTrack->sampleTable->setChunkOffsetParams( 1346 chunk_type, data_offset, chunk_data_size); 1347 1348 *offset += chunk_size; 1349 1350 if (err != OK) { 1351 return err; 1352 } 1353 1354 break; 1355 } 1356 1357 case FOURCC('s', 't', 's', 'c'): 1358 { 1359 status_t err = 1360 mLastTrack->sampleTable->setSampleToChunkParams( 1361 data_offset, chunk_data_size); 1362 1363 *offset += chunk_size; 1364 1365 if (err != OK) { 1366 return err; 1367 } 1368 1369 break; 1370 } 1371 1372 case FOURCC('s', 't', 's', 'z'): 1373 case FOURCC('s', 't', 'z', '2'): 1374 { 1375 status_t err = 1376 mLastTrack->sampleTable->setSampleSizeParams( 1377 chunk_type, data_offset, chunk_data_size); 1378 1379 *offset += chunk_size; 1380 1381 if (err != OK) { 1382 return err; 1383 } 1384 1385 size_t max_size; 1386 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 1387 1388 if (err != OK) { 1389 return err; 1390 } 1391 1392 if (max_size != 0) { 1393 // Assume that a given buffer only contains at most 10 chunks, 1394 // each chunk originally prefixed with a 2 byte length will 1395 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1396 // and thus will grow by 2 bytes per chunk. 1397 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1398 } else { 1399 // No size was specified. Pick a conservatively large size. 1400 int32_t width, height; 1401 if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || 1402 !mLastTrack->meta->findInt32(kKeyHeight, &height)) { 1403 ALOGE("No width or height, assuming worst case 1080p"); 1404 width = 1920; 1405 height = 1080; 1406 } 1407 1408 const char *mime; 1409 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1410 if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1411 // AVC requires compression ratio of at least 2, and uses 1412 // macroblocks 1413 max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; 1414 } else { 1415 // For all other formats there is no minimum compression 1416 // ratio. Use compression ratio of 1. 1417 max_size = width * height * 3 / 2; 1418 } 1419 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); 1420 } 1421 1422 // NOTE: setting another piece of metadata invalidates any pointers (such as the 1423 // mimetype) previously obtained, so don't cache them. 1424 const char *mime; 1425 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1426 // Calculate average frame rate. 1427 if (!strncasecmp("video/", mime, 6)) { 1428 size_t nSamples = mLastTrack->sampleTable->countSamples(); 1429 int64_t durationUs; 1430 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1431 if (durationUs > 0) { 1432 int32_t frameRate = (nSamples * 1000000LL + 1433 (durationUs >> 1)) / durationUs; 1434 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1435 } 1436 } 1437 } 1438 1439 break; 1440 } 1441 1442 case FOURCC('s', 't', 't', 's'): 1443 { 1444 *offset += chunk_size; 1445 1446 status_t err = 1447 mLastTrack->sampleTable->setTimeToSampleParams( 1448 data_offset, chunk_data_size); 1449 1450 if (err != OK) { 1451 return err; 1452 } 1453 1454 break; 1455 } 1456 1457 case FOURCC('c', 't', 't', 's'): 1458 { 1459 *offset += chunk_size; 1460 1461 status_t err = 1462 mLastTrack->sampleTable->setCompositionTimeToSampleParams( 1463 data_offset, chunk_data_size); 1464 1465 if (err != OK) { 1466 return err; 1467 } 1468 1469 break; 1470 } 1471 1472 case FOURCC('s', 't', 's', 's'): 1473 { 1474 *offset += chunk_size; 1475 1476 status_t err = 1477 mLastTrack->sampleTable->setSyncSampleParams( 1478 data_offset, chunk_data_size); 1479 1480 if (err != OK) { 1481 return err; 1482 } 1483 1484 break; 1485 } 1486 1487 // @xyz 1488 case FOURCC('\xA9', 'x', 'y', 'z'): 1489 { 1490 *offset += chunk_size; 1491 1492 // Best case the total data length inside "@xyz" box 1493 // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 1494 // where "\x00\x04" is the text string length with value = 4, 1495 // "\0x15\xc7" is the language code = en, and "0+0" is a 1496 // location (string) value with longitude = 0 and latitude = 0. 1497 if (chunk_data_size < 8) { 1498 return ERROR_MALFORMED; 1499 } 1500 1501 // Worst case the location string length would be 18, 1502 // for instance +90.0000-180.0000, without the trailing "/" and 1503 // the string length + language code. 1504 char buffer[18]; 1505 1506 // Substracting 5 from the data size is because the text string length + 1507 // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 1508 off64_t location_length = chunk_data_size - 5; 1509 if (location_length >= (off64_t) sizeof(buffer)) { 1510 return ERROR_MALFORMED; 1511 } 1512 1513 if (mDataSource->readAt( 1514 data_offset + 4, buffer, location_length) < location_length) { 1515 return ERROR_IO; 1516 } 1517 1518 buffer[location_length] = '\0'; 1519 mFileMetaData->setCString(kKeyLocation, buffer); 1520 break; 1521 } 1522 1523 case FOURCC('e', 's', 'd', 's'): 1524 { 1525 *offset += chunk_size; 1526 1527 if (chunk_data_size < 4) { 1528 return ERROR_MALFORMED; 1529 } 1530 1531 uint8_t buffer[256]; 1532 if (chunk_data_size > (off64_t)sizeof(buffer)) { 1533 return ERROR_BUFFER_TOO_SMALL; 1534 } 1535 1536 if (mDataSource->readAt( 1537 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1538 return ERROR_IO; 1539 } 1540 1541 if (U32_AT(buffer) != 0) { 1542 // Should be version 0, flags 0. 1543 return ERROR_MALFORMED; 1544 } 1545 1546 mLastTrack->meta->setData( 1547 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 1548 1549 if (mPath.size() >= 2 1550 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1551 // Information from the ESDS must be relied on for proper 1552 // setup of sample rate and channel count for MPEG4 Audio. 1553 // The generic header appears to only contain generic 1554 // information... 1555 1556 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1557 &buffer[4], chunk_data_size - 4); 1558 1559 if (err != OK) { 1560 return err; 1561 } 1562 } 1563 1564 break; 1565 } 1566 1567 case FOURCC('a', 'v', 'c', 'C'): 1568 { 1569 *offset += chunk_size; 1570 1571 sp<ABuffer> buffer = new ABuffer(chunk_data_size); 1572 1573 if (mDataSource->readAt( 1574 data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { 1575 return ERROR_IO; 1576 } 1577 1578 mLastTrack->meta->setData( 1579 kKeyAVCC, kTypeAVCC, buffer->data(), chunk_data_size); 1580 1581 break; 1582 } 1583 1584 case FOURCC('d', '2', '6', '3'): 1585 { 1586 *offset += chunk_size; 1587 /* 1588 * d263 contains a fixed 7 bytes part: 1589 * vendor - 4 bytes 1590 * version - 1 byte 1591 * level - 1 byte 1592 * profile - 1 byte 1593 * optionally, "d263" box itself may contain a 16-byte 1594 * bit rate box (bitr) 1595 * average bit rate - 4 bytes 1596 * max bit rate - 4 bytes 1597 */ 1598 char buffer[23]; 1599 if (chunk_data_size != 7 && 1600 chunk_data_size != 23) { 1601 ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1602 return ERROR_MALFORMED; 1603 } 1604 1605 if (mDataSource->readAt( 1606 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1607 return ERROR_IO; 1608 } 1609 1610 mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1611 1612 break; 1613 } 1614 1615 case FOURCC('m', 'e', 't', 'a'): 1616 { 1617 uint8_t buffer[4]; 1618 if (chunk_data_size < (off64_t)sizeof(buffer)) { 1619 *offset += chunk_size; 1620 return ERROR_MALFORMED; 1621 } 1622 1623 if (mDataSource->readAt( 1624 data_offset, buffer, 4) < 4) { 1625 *offset += chunk_size; 1626 return ERROR_IO; 1627 } 1628 1629 if (U32_AT(buffer) != 0) { 1630 // Should be version 0, flags 0. 1631 1632 // If it's not, let's assume this is one of those 1633 // apparently malformed chunks that don't have flags 1634 // and completely different semantics than what's 1635 // in the MPEG4 specs and skip it. 1636 *offset += chunk_size; 1637 return OK; 1638 } 1639 1640 off64_t stop_offset = *offset + chunk_size; 1641 *offset = data_offset + sizeof(buffer); 1642 while (*offset < stop_offset) { 1643 status_t err = parseChunk(offset, depth + 1); 1644 if (err != OK) { 1645 return err; 1646 } 1647 } 1648 1649 if (*offset != stop_offset) { 1650 return ERROR_MALFORMED; 1651 } 1652 break; 1653 } 1654 1655 case FOURCC('m', 'e', 'a', 'n'): 1656 case FOURCC('n', 'a', 'm', 'e'): 1657 case FOURCC('d', 'a', 't', 'a'): 1658 { 1659 *offset += chunk_size; 1660 1661 if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1662 status_t err = parseITunesMetaData(data_offset, chunk_data_size); 1663 1664 if (err != OK) { 1665 return err; 1666 } 1667 } 1668 1669 break; 1670 } 1671 1672 case FOURCC('m', 'v', 'h', 'd'): 1673 { 1674 *offset += chunk_size; 1675 1676 if (chunk_data_size < 24) { 1677 return ERROR_MALFORMED; 1678 } 1679 1680 uint8_t header[24]; 1681 if (mDataSource->readAt( 1682 data_offset, header, sizeof(header)) 1683 < (ssize_t)sizeof(header)) { 1684 return ERROR_IO; 1685 } 1686 1687 uint64_t creationTime; 1688 if (header[0] == 1) { 1689 creationTime = U64_AT(&header[4]); 1690 mHeaderTimescale = U32_AT(&header[20]); 1691 } else if (header[0] != 0) { 1692 return ERROR_MALFORMED; 1693 } else { 1694 creationTime = U32_AT(&header[4]); 1695 mHeaderTimescale = U32_AT(&header[12]); 1696 } 1697 1698 String8 s; 1699 convertTimeToDate(creationTime, &s); 1700 1701 mFileMetaData->setCString(kKeyDate, s.string()); 1702 1703 break; 1704 } 1705 1706 case FOURCC('m', 'd', 'a', 't'): 1707 { 1708 ALOGV("mdat chunk, drm: %d", mIsDrm); 1709 if (!mIsDrm) { 1710 *offset += chunk_size; 1711 break; 1712 } 1713 1714 if (chunk_size < 8) { 1715 return ERROR_MALFORMED; 1716 } 1717 1718 return parseDrmSINF(offset, data_offset); 1719 } 1720 1721 case FOURCC('h', 'd', 'l', 'r'): 1722 { 1723 *offset += chunk_size; 1724 1725 uint32_t buffer; 1726 if (mDataSource->readAt( 1727 data_offset + 8, &buffer, 4) < 4) { 1728 return ERROR_IO; 1729 } 1730 1731 uint32_t type = ntohl(buffer); 1732 // For the 3GPP file format, the handler-type within the 'hdlr' box 1733 // shall be 'text'. We also want to support 'sbtl' handler type 1734 // for a practical reason as various MPEG4 containers use it. 1735 if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 1736 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 1737 } 1738 1739 break; 1740 } 1741 1742 case FOURCC('t', 'x', '3', 'g'): 1743 { 1744 uint32_t type; 1745 const void *data; 1746 size_t size = 0; 1747 if (!mLastTrack->meta->findData( 1748 kKeyTextFormatData, &type, &data, &size)) { 1749 size = 0; 1750 } 1751 1752 uint8_t *buffer = new uint8_t[size + chunk_size]; 1753 1754 if (size > 0) { 1755 memcpy(buffer, data, size); 1756 } 1757 1758 if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 1759 < chunk_size) { 1760 delete[] buffer; 1761 buffer = NULL; 1762 1763 // advance read pointer so we don't end up reading this again 1764 *offset += chunk_size; 1765 return ERROR_IO; 1766 } 1767 1768 mLastTrack->meta->setData( 1769 kKeyTextFormatData, 0, buffer, size + chunk_size); 1770 1771 delete[] buffer; 1772 1773 *offset += chunk_size; 1774 break; 1775 } 1776 1777 case FOURCC('c', 'o', 'v', 'r'): 1778 { 1779 *offset += chunk_size; 1780 1781 if (mFileMetaData != NULL) { 1782 ALOGV("chunk_data_size = %lld and data_offset = %lld", 1783 chunk_data_size, data_offset); 1784 sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); 1785 if (mDataSource->readAt( 1786 data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { 1787 return ERROR_IO; 1788 } 1789 const int kSkipBytesOfDataBox = 16; 1790 mFileMetaData->setData( 1791 kKeyAlbumArt, MetaData::TYPE_NONE, 1792 buffer->data() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1793 } 1794 1795 break; 1796 } 1797 1798 case FOURCC('t', 'i', 't', 'l'): 1799 case FOURCC('p', 'e', 'r', 'f'): 1800 case FOURCC('a', 'u', 't', 'h'): 1801 case FOURCC('g', 'n', 'r', 'e'): 1802 case FOURCC('a', 'l', 'b', 'm'): 1803 case FOURCC('y', 'r', 'r', 'c'): 1804 { 1805 *offset += chunk_size; 1806 1807 status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth); 1808 1809 if (err != OK) { 1810 return err; 1811 } 1812 1813 break; 1814 } 1815 1816 case FOURCC('I', 'D', '3', '2'): 1817 { 1818 *offset += chunk_size; 1819 1820 if (chunk_data_size < 6) { 1821 return ERROR_MALFORMED; 1822 } 1823 1824 parseID3v2MetaData(data_offset + 6); 1825 1826 break; 1827 } 1828 1829 case FOURCC('-', '-', '-', '-'): 1830 { 1831 mLastCommentMean.clear(); 1832 mLastCommentName.clear(); 1833 mLastCommentData.clear(); 1834 *offset += chunk_size; 1835 break; 1836 } 1837 1838 case FOURCC('s', 'i', 'd', 'x'): 1839 { 1840 parseSegmentIndex(data_offset, chunk_data_size); 1841 *offset += chunk_size; 1842 return UNKNOWN_ERROR; // stop parsing after sidx 1843 } 1844 1845 default: 1846 { 1847 *offset += chunk_size; 1848 break; 1849 } 1850 } 1851 1852 return OK; 1853} 1854 1855status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) { 1856 ALOGV("MPEG4Extractor::parseSegmentIndex"); 1857 1858 if (size < 12) { 1859 return -EINVAL; 1860 } 1861 1862 uint32_t flags; 1863 if (!mDataSource->getUInt32(offset, &flags)) { 1864 return ERROR_MALFORMED; 1865 } 1866 1867 uint32_t version = flags >> 24; 1868 flags &= 0xffffff; 1869 1870 ALOGV("sidx version %d", version); 1871 1872 uint32_t referenceId; 1873 if (!mDataSource->getUInt32(offset + 4, &referenceId)) { 1874 return ERROR_MALFORMED; 1875 } 1876 1877 uint32_t timeScale; 1878 if (!mDataSource->getUInt32(offset + 8, &timeScale)) { 1879 return ERROR_MALFORMED; 1880 } 1881 ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale); 1882 1883 uint64_t earliestPresentationTime; 1884 uint64_t firstOffset; 1885 1886 offset += 12; 1887 size -= 12; 1888 1889 if (version == 0) { 1890 if (size < 8) { 1891 return -EINVAL; 1892 } 1893 uint32_t tmp; 1894 if (!mDataSource->getUInt32(offset, &tmp)) { 1895 return ERROR_MALFORMED; 1896 } 1897 earliestPresentationTime = tmp; 1898 if (!mDataSource->getUInt32(offset + 4, &tmp)) { 1899 return ERROR_MALFORMED; 1900 } 1901 firstOffset = tmp; 1902 offset += 8; 1903 size -= 8; 1904 } else { 1905 if (size < 16) { 1906 return -EINVAL; 1907 } 1908 if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) { 1909 return ERROR_MALFORMED; 1910 } 1911 if (!mDataSource->getUInt64(offset + 8, &firstOffset)) { 1912 return ERROR_MALFORMED; 1913 } 1914 offset += 16; 1915 size -= 16; 1916 } 1917 ALOGV("sidx pres/off: %Ld/%Ld", earliestPresentationTime, firstOffset); 1918 1919 if (size < 4) { 1920 return -EINVAL; 1921 } 1922 1923 uint16_t referenceCount; 1924 if (!mDataSource->getUInt16(offset + 2, &referenceCount)) { 1925 return ERROR_MALFORMED; 1926 } 1927 offset += 4; 1928 size -= 4; 1929 ALOGV("refcount: %d", referenceCount); 1930 1931 if (size < referenceCount * 12) { 1932 return -EINVAL; 1933 } 1934 1935 uint64_t total_duration = 0; 1936 for (unsigned int i = 0; i < referenceCount; i++) { 1937 uint32_t d1, d2, d3; 1938 1939 if (!mDataSource->getUInt32(offset, &d1) || // size 1940 !mDataSource->getUInt32(offset + 4, &d2) || // duration 1941 !mDataSource->getUInt32(offset + 8, &d3)) { // flags 1942 return ERROR_MALFORMED; 1943 } 1944 1945 if (d1 & 0x80000000) { 1946 ALOGW("sub-sidx boxes not supported yet"); 1947 } 1948 bool sap = d3 & 0x80000000; 1949 uint32_t saptype = (d3 >> 28) & 7; 1950 if (!sap || (saptype != 1 && saptype != 2)) { 1951 // type 1 and 2 are sync samples 1952 ALOGW("not a stream access point, or unsupported type: %08x", d3); 1953 } 1954 total_duration += d2; 1955 offset += 12; 1956 ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3); 1957 SidxEntry se; 1958 se.mSize = d1 & 0x7fffffff; 1959 se.mDurationUs = 1000000LL * d2 / timeScale; 1960 mSidxEntries.add(se); 1961 } 1962 1963 mSidxDuration = total_duration * 1000000 / timeScale; 1964 ALOGV("duration: %lld", mSidxDuration); 1965 1966 int64_t metaDuration; 1967 if (!mLastTrack->meta->findInt64(kKeyDuration, &metaDuration) || metaDuration == 0) { 1968 mLastTrack->meta->setInt64(kKeyDuration, mSidxDuration); 1969 } 1970 return OK; 1971} 1972 1973 1974 1975status_t MPEG4Extractor::parseTrackHeader( 1976 off64_t data_offset, off64_t data_size) { 1977 if (data_size < 4) { 1978 return ERROR_MALFORMED; 1979 } 1980 1981 uint8_t version; 1982 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1983 return ERROR_IO; 1984 } 1985 1986 size_t dynSize = (version == 1) ? 36 : 24; 1987 1988 uint8_t buffer[36 + 60]; 1989 1990 if (data_size != (off64_t)dynSize + 60) { 1991 return ERROR_MALFORMED; 1992 } 1993 1994 if (mDataSource->readAt( 1995 data_offset, buffer, data_size) < (ssize_t)data_size) { 1996 return ERROR_IO; 1997 } 1998 1999 uint64_t ctime, mtime, duration; 2000 int32_t id; 2001 2002 if (version == 1) { 2003 ctime = U64_AT(&buffer[4]); 2004 mtime = U64_AT(&buffer[12]); 2005 id = U32_AT(&buffer[20]); 2006 duration = U64_AT(&buffer[28]); 2007 } else if (version == 0) { 2008 ctime = U32_AT(&buffer[4]); 2009 mtime = U32_AT(&buffer[8]); 2010 id = U32_AT(&buffer[12]); 2011 duration = U32_AT(&buffer[20]); 2012 } else { 2013 return ERROR_UNSUPPORTED; 2014 } 2015 2016 mLastTrack->meta->setInt32(kKeyTrackID, id); 2017 2018 size_t matrixOffset = dynSize + 16; 2019 int32_t a00 = U32_AT(&buffer[matrixOffset]); 2020 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 2021 int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 2022 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 2023 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 2024 int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 2025 2026#if 0 2027 ALOGI("x' = %.2f * x + %.2f * y + %.2f", 2028 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 2029 ALOGI("y' = %.2f * x + %.2f * y + %.2f", 2030 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 2031#endif 2032 2033 uint32_t rotationDegrees; 2034 2035 static const int32_t kFixedOne = 0x10000; 2036 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 2037 // Identity, no rotation 2038 rotationDegrees = 0; 2039 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 2040 rotationDegrees = 90; 2041 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 2042 rotationDegrees = 270; 2043 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 2044 rotationDegrees = 180; 2045 } else { 2046 ALOGW("We only support 0,90,180,270 degree rotation matrices"); 2047 rotationDegrees = 0; 2048 } 2049 2050 if (rotationDegrees != 0) { 2051 mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 2052 } 2053 2054 // Handle presentation display size, which could be different 2055 // from the image size indicated by kKeyWidth and kKeyHeight. 2056 uint32_t width = U32_AT(&buffer[dynSize + 52]); 2057 uint32_t height = U32_AT(&buffer[dynSize + 56]); 2058 mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 2059 mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 2060 2061 return OK; 2062} 2063 2064status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { 2065 if (size < 4) { 2066 return ERROR_MALFORMED; 2067 } 2068 2069 uint8_t *buffer = new uint8_t[size + 1]; 2070 if (mDataSource->readAt( 2071 offset, buffer, size) != (ssize_t)size) { 2072 delete[] buffer; 2073 buffer = NULL; 2074 2075 return ERROR_IO; 2076 } 2077 2078 uint32_t flags = U32_AT(buffer); 2079 2080 uint32_t metadataKey = 0; 2081 char chunk[5]; 2082 MakeFourCCString(mPath[4], chunk); 2083 ALOGV("meta: %s @ %lld", chunk, offset); 2084 switch (mPath[4]) { 2085 case FOURCC(0xa9, 'a', 'l', 'b'): 2086 { 2087 metadataKey = kKeyAlbum; 2088 break; 2089 } 2090 case FOURCC(0xa9, 'A', 'R', 'T'): 2091 { 2092 metadataKey = kKeyArtist; 2093 break; 2094 } 2095 case FOURCC('a', 'A', 'R', 'T'): 2096 { 2097 metadataKey = kKeyAlbumArtist; 2098 break; 2099 } 2100 case FOURCC(0xa9, 'd', 'a', 'y'): 2101 { 2102 metadataKey = kKeyYear; 2103 break; 2104 } 2105 case FOURCC(0xa9, 'n', 'a', 'm'): 2106 { 2107 metadataKey = kKeyTitle; 2108 break; 2109 } 2110 case FOURCC(0xa9, 'w', 'r', 't'): 2111 { 2112 metadataKey = kKeyWriter; 2113 break; 2114 } 2115 case FOURCC('c', 'o', 'v', 'r'): 2116 { 2117 metadataKey = kKeyAlbumArt; 2118 break; 2119 } 2120 case FOURCC('g', 'n', 'r', 'e'): 2121 { 2122 metadataKey = kKeyGenre; 2123 break; 2124 } 2125 case FOURCC(0xa9, 'g', 'e', 'n'): 2126 { 2127 metadataKey = kKeyGenre; 2128 break; 2129 } 2130 case FOURCC('c', 'p', 'i', 'l'): 2131 { 2132 if (size == 9 && flags == 21) { 2133 char tmp[16]; 2134 sprintf(tmp, "%d", 2135 (int)buffer[size - 1]); 2136 2137 mFileMetaData->setCString(kKeyCompilation, tmp); 2138 } 2139 break; 2140 } 2141 case FOURCC('t', 'r', 'k', 'n'): 2142 { 2143 if (size == 16 && flags == 0) { 2144 char tmp[16]; 2145 uint16_t* pTrack = (uint16_t*)&buffer[10]; 2146 uint16_t* pTotalTracks = (uint16_t*)&buffer[12]; 2147 sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks)); 2148 2149 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2150 } 2151 break; 2152 } 2153 case FOURCC('d', 'i', 's', 'k'): 2154 { 2155 if ((size == 14 || size == 16) && flags == 0) { 2156 char tmp[16]; 2157 uint16_t* pDisc = (uint16_t*)&buffer[10]; 2158 uint16_t* pTotalDiscs = (uint16_t*)&buffer[12]; 2159 sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs)); 2160 2161 mFileMetaData->setCString(kKeyDiscNumber, tmp); 2162 } 2163 break; 2164 } 2165 case FOURCC('-', '-', '-', '-'): 2166 { 2167 buffer[size] = '\0'; 2168 switch (mPath[5]) { 2169 case FOURCC('m', 'e', 'a', 'n'): 2170 mLastCommentMean.setTo((const char *)buffer + 4); 2171 break; 2172 case FOURCC('n', 'a', 'm', 'e'): 2173 mLastCommentName.setTo((const char *)buffer + 4); 2174 break; 2175 case FOURCC('d', 'a', 't', 'a'): 2176 mLastCommentData.setTo((const char *)buffer + 8); 2177 break; 2178 } 2179 2180 // Once we have a set of mean/name/data info, go ahead and process 2181 // it to see if its something we are interested in. Whether or not 2182 // were are interested in the specific tag, make sure to clear out 2183 // the set so we can be ready to process another tuple should one 2184 // show up later in the file. 2185 if ((mLastCommentMean.length() != 0) && 2186 (mLastCommentName.length() != 0) && 2187 (mLastCommentData.length() != 0)) { 2188 2189 if (mLastCommentMean == "com.apple.iTunes" 2190 && mLastCommentName == "iTunSMPB") { 2191 int32_t delay, padding; 2192 if (sscanf(mLastCommentData, 2193 " %*x %x %x %*x", &delay, &padding) == 2) { 2194 mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); 2195 mLastTrack->meta->setInt32(kKeyEncoderPadding, padding); 2196 } 2197 } 2198 2199 mLastCommentMean.clear(); 2200 mLastCommentName.clear(); 2201 mLastCommentData.clear(); 2202 } 2203 break; 2204 } 2205 2206 default: 2207 break; 2208 } 2209 2210 if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { 2211 if (metadataKey == kKeyAlbumArt) { 2212 mFileMetaData->setData( 2213 kKeyAlbumArt, MetaData::TYPE_NONE, 2214 buffer + 8, size - 8); 2215 } else if (metadataKey == kKeyGenre) { 2216 if (flags == 0) { 2217 // uint8_t genre code, iTunes genre codes are 2218 // the standard id3 codes, except they start 2219 // at 1 instead of 0 (e.g. Pop is 14, not 13) 2220 // We use standard id3 numbering, so subtract 1. 2221 int genrecode = (int)buffer[size - 1]; 2222 genrecode--; 2223 if (genrecode < 0) { 2224 genrecode = 255; // reserved for 'unknown genre' 2225 } 2226 char genre[10]; 2227 sprintf(genre, "%d", genrecode); 2228 2229 mFileMetaData->setCString(metadataKey, genre); 2230 } else if (flags == 1) { 2231 // custom genre string 2232 buffer[size] = '\0'; 2233 2234 mFileMetaData->setCString( 2235 metadataKey, (const char *)buffer + 8); 2236 } 2237 } else { 2238 buffer[size] = '\0'; 2239 2240 mFileMetaData->setCString( 2241 metadataKey, (const char *)buffer + 8); 2242 } 2243 } 2244 2245 delete[] buffer; 2246 buffer = NULL; 2247 2248 return OK; 2249} 2250 2251status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) { 2252 if (size < 4) { 2253 return ERROR_MALFORMED; 2254 } 2255 2256 uint8_t *buffer = new uint8_t[size]; 2257 if (mDataSource->readAt( 2258 offset, buffer, size) != (ssize_t)size) { 2259 delete[] buffer; 2260 buffer = NULL; 2261 2262 return ERROR_IO; 2263 } 2264 2265 uint32_t metadataKey = 0; 2266 switch (mPath[depth]) { 2267 case FOURCC('t', 'i', 't', 'l'): 2268 { 2269 metadataKey = kKeyTitle; 2270 break; 2271 } 2272 case FOURCC('p', 'e', 'r', 'f'): 2273 { 2274 metadataKey = kKeyArtist; 2275 break; 2276 } 2277 case FOURCC('a', 'u', 't', 'h'): 2278 { 2279 metadataKey = kKeyWriter; 2280 break; 2281 } 2282 case FOURCC('g', 'n', 'r', 'e'): 2283 { 2284 metadataKey = kKeyGenre; 2285 break; 2286 } 2287 case FOURCC('a', 'l', 'b', 'm'): 2288 { 2289 if (buffer[size - 1] != '\0') { 2290 char tmp[4]; 2291 sprintf(tmp, "%u", buffer[size - 1]); 2292 2293 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 2294 } 2295 2296 metadataKey = kKeyAlbum; 2297 break; 2298 } 2299 case FOURCC('y', 'r', 'r', 'c'): 2300 { 2301 char tmp[5]; 2302 uint16_t year = U16_AT(&buffer[4]); 2303 2304 if (year < 10000) { 2305 sprintf(tmp, "%u", year); 2306 2307 mFileMetaData->setCString(kKeyYear, tmp); 2308 } 2309 break; 2310 } 2311 2312 default: 2313 break; 2314 } 2315 2316 if (metadataKey > 0) { 2317 bool isUTF8 = true; // Common case 2318 char16_t *framedata = NULL; 2319 int len16 = 0; // Number of UTF-16 characters 2320 2321 // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00 2322 if (size - 6 >= 4) { 2323 len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator 2324 framedata = (char16_t *)(buffer + 6); 2325 if (0xfffe == *framedata) { 2326 // endianness marker (BOM) doesn't match host endianness 2327 for (int i = 0; i < len16; i++) { 2328 framedata[i] = bswap_16(framedata[i]); 2329 } 2330 // BOM is now swapped to 0xfeff, we will execute next block too 2331 } 2332 2333 if (0xfeff == *framedata) { 2334 // Remove the BOM 2335 framedata++; 2336 len16--; 2337 isUTF8 = false; 2338 } 2339 // else normal non-zero-length UTF-8 string 2340 // we can't handle UTF-16 without BOM as there is no other 2341 // indication of encoding. 2342 } 2343 2344 if (isUTF8) { 2345 mFileMetaData->setCString(metadataKey, (const char *)buffer + 6); 2346 } else { 2347 // Convert from UTF-16 string to UTF-8 string. 2348 String8 tmpUTF8str(framedata, len16); 2349 mFileMetaData->setCString(metadataKey, tmpUTF8str.string()); 2350 } 2351 } 2352 2353 delete[] buffer; 2354 buffer = NULL; 2355 2356 return OK; 2357} 2358 2359void MPEG4Extractor::parseID3v2MetaData(off64_t offset) { 2360 ID3 id3(mDataSource, true /* ignorev1 */, offset); 2361 2362 if (id3.isValid()) { 2363 struct Map { 2364 int key; 2365 const char *tag1; 2366 const char *tag2; 2367 }; 2368 static const Map kMap[] = { 2369 { kKeyAlbum, "TALB", "TAL" }, 2370 { kKeyArtist, "TPE1", "TP1" }, 2371 { kKeyAlbumArtist, "TPE2", "TP2" }, 2372 { kKeyComposer, "TCOM", "TCM" }, 2373 { kKeyGenre, "TCON", "TCO" }, 2374 { kKeyTitle, "TIT2", "TT2" }, 2375 { kKeyYear, "TYE", "TYER" }, 2376 { kKeyAuthor, "TXT", "TEXT" }, 2377 { kKeyCDTrackNumber, "TRK", "TRCK" }, 2378 { kKeyDiscNumber, "TPA", "TPOS" }, 2379 { kKeyCompilation, "TCP", "TCMP" }, 2380 }; 2381 static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); 2382 2383 for (size_t i = 0; i < kNumMapEntries; ++i) { 2384 if (!mFileMetaData->hasData(kMap[i].key)) { 2385 ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); 2386 if (it->done()) { 2387 delete it; 2388 it = new ID3::Iterator(id3, kMap[i].tag2); 2389 } 2390 2391 if (it->done()) { 2392 delete it; 2393 continue; 2394 } 2395 2396 String8 s; 2397 it->getString(&s); 2398 delete it; 2399 2400 mFileMetaData->setCString(kMap[i].key, s); 2401 } 2402 } 2403 2404 size_t dataSize; 2405 String8 mime; 2406 const void *data = id3.getAlbumArt(&dataSize, &mime); 2407 2408 if (data) { 2409 mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); 2410 mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); 2411 } 2412 } 2413} 2414 2415sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 2416 status_t err; 2417 if ((err = readMetaData()) != OK) { 2418 return NULL; 2419 } 2420 2421 Track *track = mFirstTrack; 2422 while (index > 0) { 2423 if (track == NULL) { 2424 return NULL; 2425 } 2426 2427 track = track->next; 2428 --index; 2429 } 2430 2431 if (track == NULL) { 2432 return NULL; 2433 } 2434 2435 ALOGV("getTrack called, pssh: %d", mPssh.size()); 2436 2437 return new MPEG4Source( 2438 track->meta, mDataSource, track->timescale, track->sampleTable, 2439 mSidxEntries, mMoofOffset); 2440} 2441 2442// static 2443status_t MPEG4Extractor::verifyTrack(Track *track) { 2444 const char *mime; 2445 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2446 2447 uint32_t type; 2448 const void *data; 2449 size_t size; 2450 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 2451 if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 2452 || type != kTypeAVCC) { 2453 return ERROR_MALFORMED; 2454 } 2455 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 2456 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 2457 if (!track->meta->findData(kKeyESDS, &type, &data, &size) 2458 || type != kTypeESDS) { 2459 return ERROR_MALFORMED; 2460 } 2461 } 2462 2463 if (!track->sampleTable->isValid()) { 2464 // Make sure we have all the metadata we need. 2465 return ERROR_MALFORMED; 2466 } 2467 2468 return OK; 2469} 2470 2471typedef enum { 2472 //AOT_NONE = -1, 2473 //AOT_NULL_OBJECT = 0, 2474 //AOT_AAC_MAIN = 1, /**< Main profile */ 2475 AOT_AAC_LC = 2, /**< Low Complexity object */ 2476 //AOT_AAC_SSR = 3, 2477 //AOT_AAC_LTP = 4, 2478 AOT_SBR = 5, 2479 //AOT_AAC_SCAL = 6, 2480 //AOT_TWIN_VQ = 7, 2481 //AOT_CELP = 8, 2482 //AOT_HVXC = 9, 2483 //AOT_RSVD_10 = 10, /**< (reserved) */ 2484 //AOT_RSVD_11 = 11, /**< (reserved) */ 2485 //AOT_TTSI = 12, /**< TTSI Object */ 2486 //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */ 2487 //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */ 2488 //AOT_GEN_MIDI = 15, /**< General MIDI object */ 2489 //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */ 2490 AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */ 2491 //AOT_RSVD_18 = 18, /**< (reserved) */ 2492 //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */ 2493 AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */ 2494 //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */ 2495 AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */ 2496 AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */ 2497 //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */ 2498 //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */ 2499 //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */ 2500 //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */ 2501 //AOT_RSVD_28 = 28, /**< might become SSC */ 2502 AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */ 2503 //AOT_MPEGS = 30, /**< MPEG Surround */ 2504 2505 AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */ 2506 2507 //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */ 2508 //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */ 2509 //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */ 2510 //AOT_RSVD_35 = 35, /**< might become DST */ 2511 //AOT_RSVD_36 = 36, /**< might become ALS */ 2512 //AOT_AAC_SLS = 37, /**< AAC + SLS */ 2513 //AOT_SLS = 38, /**< SLS */ 2514 //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */ 2515 2516 //AOT_USAC = 42, /**< USAC */ 2517 //AOT_SAOC = 43, /**< SAOC */ 2518 //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ 2519 2520 //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ 2521} AUDIO_OBJECT_TYPE; 2522 2523status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 2524 const void *esds_data, size_t esds_size) { 2525 ESDS esds(esds_data, esds_size); 2526 2527 uint8_t objectTypeIndication; 2528 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 2529 return ERROR_MALFORMED; 2530 } 2531 2532 if (objectTypeIndication == 0xe1) { 2533 // This isn't MPEG4 audio at all, it's QCELP 14k... 2534 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 2535 return OK; 2536 } 2537 2538 if (objectTypeIndication == 0x6b) { 2539 // The media subtype is MP3 audio 2540 // Our software MP3 audio decoder may not be able to handle 2541 // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 2542 ALOGE("MP3 track in MP4/3GPP file is not supported"); 2543 return ERROR_UNSUPPORTED; 2544 } 2545 2546 const uint8_t *csd; 2547 size_t csd_size; 2548 if (esds.getCodecSpecificInfo( 2549 (const void **)&csd, &csd_size) != OK) { 2550 return ERROR_MALFORMED; 2551 } 2552 2553#if 0 2554 printf("ESD of size %d\n", csd_size); 2555 hexdump(csd, csd_size); 2556#endif 2557 2558 if (csd_size == 0) { 2559 // There's no further information, i.e. no codec specific data 2560 // Let's assume that the information provided in the mpeg4 headers 2561 // is accurate and hope for the best. 2562 2563 return OK; 2564 } 2565 2566 if (csd_size < 2) { 2567 return ERROR_MALFORMED; 2568 } 2569 2570 static uint32_t kSamplingRate[] = { 2571 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 2572 16000, 12000, 11025, 8000, 7350 2573 }; 2574 2575 ABitReader br(csd, csd_size); 2576 uint32_t objectType = br.getBits(5); 2577 2578 if (objectType == 31) { // AAC-ELD => additional 6 bits 2579 objectType = 32 + br.getBits(6); 2580 } 2581 2582 //keep AOT type 2583 mLastTrack->meta->setInt32(kKeyAACAOT, objectType); 2584 2585 uint32_t freqIndex = br.getBits(4); 2586 2587 int32_t sampleRate = 0; 2588 int32_t numChannels = 0; 2589 if (freqIndex == 15) { 2590 if (csd_size < 5) { 2591 return ERROR_MALFORMED; 2592 } 2593 sampleRate = br.getBits(24); 2594 numChannels = br.getBits(4); 2595 } else { 2596 numChannels = br.getBits(4); 2597 2598 if (freqIndex == 13 || freqIndex == 14) { 2599 return ERROR_MALFORMED; 2600 } 2601 2602 sampleRate = kSamplingRate[freqIndex]; 2603 } 2604 2605 if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13 2606 uint32_t extFreqIndex = br.getBits(4); 2607 int32_t extSampleRate; 2608 if (extFreqIndex == 15) { 2609 if (csd_size < 8) { 2610 return ERROR_MALFORMED; 2611 } 2612 extSampleRate = br.getBits(24); 2613 } else { 2614 if (extFreqIndex == 13 || extFreqIndex == 14) { 2615 return ERROR_MALFORMED; 2616 } 2617 extSampleRate = kSamplingRate[extFreqIndex]; 2618 } 2619 //TODO: save the extension sampling rate value in meta data => 2620 // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); 2621 } 2622 2623 switch (numChannels) { 2624 // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration 2625 case 0: 2626 case 1:// FC 2627 case 2:// FL FR 2628 case 3:// FC, FL FR 2629 case 4:// FC, FL FR, RC 2630 case 5:// FC, FL FR, SL SR 2631 case 6:// FC, FL FR, SL SR, LFE 2632 //numChannels already contains the right value 2633 break; 2634 case 11:// FC, FL FR, SL SR, RC, LFE 2635 numChannels = 7; 2636 break; 2637 case 7: // FC, FCL FCR, FL FR, SL SR, LFE 2638 case 12:// FC, FL FR, SL SR, RL RR, LFE 2639 case 14:// FC, FL FR, SL SR, LFE, FHL FHR 2640 numChannels = 8; 2641 break; 2642 default: 2643 return ERROR_UNSUPPORTED; 2644 } 2645 2646 { 2647 if (objectType == AOT_SBR || objectType == AOT_PS) { 2648 const int32_t extensionSamplingFrequency = br.getBits(4); 2649 objectType = br.getBits(5); 2650 2651 if (objectType == AOT_ESCAPE) { 2652 objectType = 32 + br.getBits(6); 2653 } 2654 } 2655 if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC || 2656 objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL || 2657 objectType == AOT_ER_BSAC) { 2658 const int32_t frameLengthFlag = br.getBits(1); 2659 2660 const int32_t dependsOnCoreCoder = br.getBits(1); 2661 2662 if (dependsOnCoreCoder ) { 2663 const int32_t coreCoderDelay = br.getBits(14); 2664 } 2665 2666 const int32_t extensionFlag = br.getBits(1); 2667 2668 if (numChannels == 0 ) { 2669 int32_t channelsEffectiveNum = 0; 2670 int32_t channelsNum = 0; 2671 const int32_t ElementInstanceTag = br.getBits(4); 2672 const int32_t Profile = br.getBits(2); 2673 const int32_t SamplingFrequencyIndex = br.getBits(4); 2674 const int32_t NumFrontChannelElements = br.getBits(4); 2675 const int32_t NumSideChannelElements = br.getBits(4); 2676 const int32_t NumBackChannelElements = br.getBits(4); 2677 const int32_t NumLfeChannelElements = br.getBits(2); 2678 const int32_t NumAssocDataElements = br.getBits(3); 2679 const int32_t NumValidCcElements = br.getBits(4); 2680 2681 const int32_t MonoMixdownPresent = br.getBits(1); 2682 if (MonoMixdownPresent != 0) { 2683 const int32_t MonoMixdownElementNumber = br.getBits(4); 2684 } 2685 2686 const int32_t StereoMixdownPresent = br.getBits(1); 2687 if (StereoMixdownPresent != 0) { 2688 const int32_t StereoMixdownElementNumber = br.getBits(4); 2689 } 2690 2691 const int32_t MatrixMixdownIndexPresent = br.getBits(1); 2692 if (MatrixMixdownIndexPresent != 0) { 2693 const int32_t MatrixMixdownIndex = br.getBits(2); 2694 const int32_t PseudoSurroundEnable = br.getBits(1); 2695 } 2696 2697 int i; 2698 for (i=0; i < NumFrontChannelElements; i++) { 2699 const int32_t FrontElementIsCpe = br.getBits(1); 2700 const int32_t FrontElementTagSelect = br.getBits(4); 2701 channelsNum += FrontElementIsCpe ? 2 : 1; 2702 } 2703 2704 for (i=0; i < NumSideChannelElements; i++) { 2705 const int32_t SideElementIsCpe = br.getBits(1); 2706 const int32_t SideElementTagSelect = br.getBits(4); 2707 channelsNum += SideElementIsCpe ? 2 : 1; 2708 } 2709 2710 for (i=0; i < NumBackChannelElements; i++) { 2711 const int32_t BackElementIsCpe = br.getBits(1); 2712 const int32_t BackElementTagSelect = br.getBits(4); 2713 channelsNum += BackElementIsCpe ? 2 : 1; 2714 } 2715 channelsEffectiveNum = channelsNum; 2716 2717 for (i=0; i < NumLfeChannelElements; i++) { 2718 const int32_t LfeElementTagSelect = br.getBits(4); 2719 channelsNum += 1; 2720 } 2721 ALOGV("mpeg4 audio channelsNum = %d", channelsNum); 2722 ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum); 2723 numChannels = channelsNum; 2724 } 2725 } 2726 } 2727 2728 if (numChannels == 0) { 2729 return ERROR_UNSUPPORTED; 2730 } 2731 2732 int32_t prevSampleRate; 2733 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 2734 2735 if (prevSampleRate != sampleRate) { 2736 ALOGV("mpeg4 audio sample rate different from previous setting. " 2737 "was: %d, now: %d", prevSampleRate, sampleRate); 2738 } 2739 2740 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 2741 2742 int32_t prevChannelCount; 2743 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 2744 2745 if (prevChannelCount != numChannels) { 2746 ALOGV("mpeg4 audio channel count different from previous setting. " 2747 "was: %d, now: %d", prevChannelCount, numChannels); 2748 } 2749 2750 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 2751 2752 return OK; 2753} 2754 2755//////////////////////////////////////////////////////////////////////////////// 2756 2757MPEG4Source::MPEG4Source( 2758 const sp<MetaData> &format, 2759 const sp<DataSource> &dataSource, 2760 int32_t timeScale, 2761 const sp<SampleTable> &sampleTable, 2762 Vector<SidxEntry> &sidx, 2763 off64_t firstMoofOffset) 2764 : mFormat(format), 2765 mDataSource(dataSource), 2766 mTimescale(timeScale), 2767 mSampleTable(sampleTable), 2768 mCurrentSampleIndex(0), 2769 mCurrentFragmentIndex(0), 2770 mSegments(sidx), 2771 mFirstMoofOffset(firstMoofOffset), 2772 mCurrentMoofOffset(firstMoofOffset), 2773 mCurrentTime(0), 2774 mCurrentSampleInfoAllocSize(0), 2775 mCurrentSampleInfoSizes(NULL), 2776 mCurrentSampleInfoOffsetsAllocSize(0), 2777 mCurrentSampleInfoOffsets(NULL), 2778 mIsAVC(false), 2779 mNALLengthSize(0), 2780 mStarted(false), 2781 mGroup(NULL), 2782 mBuffer(NULL), 2783 mWantsNALFragments(false), 2784 mSrcBuffer(NULL) { 2785 2786 mFormat->findInt32(kKeyCryptoMode, &mCryptoMode); 2787 mDefaultIVSize = 0; 2788 mFormat->findInt32(kKeyCryptoDefaultIVSize, &mDefaultIVSize); 2789 uint32_t keytype; 2790 const void *key; 2791 size_t keysize; 2792 if (mFormat->findData(kKeyCryptoKey, &keytype, &key, &keysize)) { 2793 CHECK(keysize <= 16); 2794 memset(mCryptoKey, 0, 16); 2795 memcpy(mCryptoKey, key, keysize); 2796 } 2797 2798 const char *mime; 2799 bool success = mFormat->findCString(kKeyMIMEType, &mime); 2800 CHECK(success); 2801 2802 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 2803 2804 if (mIsAVC) { 2805 uint32_t type; 2806 const void *data; 2807 size_t size; 2808 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 2809 2810 const uint8_t *ptr = (const uint8_t *)data; 2811 2812 CHECK(size >= 7); 2813 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 2814 2815 // The number of bytes used to encode the length of a NAL unit. 2816 mNALLengthSize = 1 + (ptr[4] & 3); 2817 } 2818 2819 CHECK(format->findInt32(kKeyTrackID, &mTrackId)); 2820 2821 if (mFirstMoofOffset != 0) { 2822 off64_t offset = mFirstMoofOffset; 2823 parseChunk(&offset); 2824 } 2825} 2826 2827MPEG4Source::~MPEG4Source() { 2828 if (mStarted) { 2829 stop(); 2830 } 2831 free(mCurrentSampleInfoSizes); 2832 free(mCurrentSampleInfoOffsets); 2833} 2834 2835status_t MPEG4Source::start(MetaData *params) { 2836 Mutex::Autolock autoLock(mLock); 2837 2838 CHECK(!mStarted); 2839 2840 int32_t val; 2841 if (params && params->findInt32(kKeyWantsNALFragments, &val) 2842 && val != 0) { 2843 mWantsNALFragments = true; 2844 } else { 2845 mWantsNALFragments = false; 2846 } 2847 2848 mGroup = new MediaBufferGroup; 2849 2850 int32_t max_size; 2851 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 2852 2853 mGroup->add_buffer(new MediaBuffer(max_size)); 2854 2855 mSrcBuffer = new uint8_t[max_size]; 2856 2857 mStarted = true; 2858 2859 return OK; 2860} 2861 2862status_t MPEG4Source::stop() { 2863 Mutex::Autolock autoLock(mLock); 2864 2865 CHECK(mStarted); 2866 2867 if (mBuffer != NULL) { 2868 mBuffer->release(); 2869 mBuffer = NULL; 2870 } 2871 2872 delete[] mSrcBuffer; 2873 mSrcBuffer = NULL; 2874 2875 delete mGroup; 2876 mGroup = NULL; 2877 2878 mStarted = false; 2879 mCurrentSampleIndex = 0; 2880 2881 return OK; 2882} 2883 2884status_t MPEG4Source::parseChunk(off64_t *offset) { 2885 uint32_t hdr[2]; 2886 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 2887 return ERROR_IO; 2888 } 2889 uint64_t chunk_size = ntohl(hdr[0]); 2890 uint32_t chunk_type = ntohl(hdr[1]); 2891 off64_t data_offset = *offset + 8; 2892 2893 if (chunk_size == 1) { 2894 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 2895 return ERROR_IO; 2896 } 2897 chunk_size = ntoh64(chunk_size); 2898 data_offset += 8; 2899 2900 if (chunk_size < 16) { 2901 // The smallest valid chunk is 16 bytes long in this case. 2902 return ERROR_MALFORMED; 2903 } 2904 } else if (chunk_size < 8) { 2905 // The smallest valid chunk is 8 bytes long. 2906 return ERROR_MALFORMED; 2907 } 2908 2909 char chunk[5]; 2910 MakeFourCCString(chunk_type, chunk); 2911 ALOGV("MPEG4Source chunk %s @ %llx", chunk, *offset); 2912 2913 off64_t chunk_data_size = *offset + chunk_size - data_offset; 2914 2915 switch(chunk_type) { 2916 2917 case FOURCC('t', 'r', 'a', 'f'): 2918 case FOURCC('m', 'o', 'o', 'f'): { 2919 off64_t stop_offset = *offset + chunk_size; 2920 *offset = data_offset; 2921 while (*offset < stop_offset) { 2922 status_t err = parseChunk(offset); 2923 if (err != OK) { 2924 return err; 2925 } 2926 } 2927 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 2928 // *offset points to the box following this moof. Find the next moof from there. 2929 2930 while (true) { 2931 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 2932 return ERROR_END_OF_STREAM; 2933 } 2934 chunk_size = ntohl(hdr[0]); 2935 chunk_type = ntohl(hdr[1]); 2936 if (chunk_type == FOURCC('m', 'o', 'o', 'f')) { 2937 mNextMoofOffset = *offset; 2938 break; 2939 } 2940 *offset += chunk_size; 2941 } 2942 } 2943 break; 2944 } 2945 2946 case FOURCC('t', 'f', 'h', 'd'): { 2947 status_t err; 2948 if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) { 2949 return err; 2950 } 2951 *offset += chunk_size; 2952 break; 2953 } 2954 2955 case FOURCC('t', 'r', 'u', 'n'): { 2956 status_t err; 2957 if (mLastParsedTrackId == mTrackId) { 2958 if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) { 2959 return err; 2960 } 2961 } 2962 2963 *offset += chunk_size; 2964 break; 2965 } 2966 2967 case FOURCC('s', 'a', 'i', 'z'): { 2968 status_t err; 2969 if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) { 2970 return err; 2971 } 2972 *offset += chunk_size; 2973 break; 2974 } 2975 case FOURCC('s', 'a', 'i', 'o'): { 2976 status_t err; 2977 if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size)) != OK) { 2978 return err; 2979 } 2980 *offset += chunk_size; 2981 break; 2982 } 2983 2984 case FOURCC('m', 'd', 'a', 't'): { 2985 // parse DRM info if present 2986 ALOGV("MPEG4Source::parseChunk mdat"); 2987 // if saiz/saoi was previously observed, do something with the sampleinfos 2988 *offset += chunk_size; 2989 break; 2990 } 2991 2992 default: { 2993 *offset += chunk_size; 2994 break; 2995 } 2996 } 2997 return OK; 2998} 2999 3000status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( 3001 off64_t offset, off64_t /* size */) { 3002 ALOGV("parseSampleAuxiliaryInformationSizes"); 3003 // 14496-12 8.7.12 3004 uint8_t version; 3005 if (mDataSource->readAt( 3006 offset, &version, sizeof(version)) 3007 < (ssize_t)sizeof(version)) { 3008 return ERROR_IO; 3009 } 3010 3011 if (version != 0) { 3012 return ERROR_UNSUPPORTED; 3013 } 3014 offset++; 3015 3016 uint32_t flags; 3017 if (!mDataSource->getUInt24(offset, &flags)) { 3018 return ERROR_IO; 3019 } 3020 offset += 3; 3021 3022 if (flags & 1) { 3023 uint32_t tmp; 3024 if (!mDataSource->getUInt32(offset, &tmp)) { 3025 return ERROR_MALFORMED; 3026 } 3027 mCurrentAuxInfoType = tmp; 3028 offset += 4; 3029 if (!mDataSource->getUInt32(offset, &tmp)) { 3030 return ERROR_MALFORMED; 3031 } 3032 mCurrentAuxInfoTypeParameter = tmp; 3033 offset += 4; 3034 } 3035 3036 uint8_t defsize; 3037 if (mDataSource->readAt(offset, &defsize, 1) != 1) { 3038 return ERROR_MALFORMED; 3039 } 3040 mCurrentDefaultSampleInfoSize = defsize; 3041 offset++; 3042 3043 uint32_t smplcnt; 3044 if (!mDataSource->getUInt32(offset, &smplcnt)) { 3045 return ERROR_MALFORMED; 3046 } 3047 mCurrentSampleInfoCount = smplcnt; 3048 offset += 4; 3049 3050 if (mCurrentDefaultSampleInfoSize != 0) { 3051 ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); 3052 return OK; 3053 } 3054 if (smplcnt > mCurrentSampleInfoAllocSize) { 3055 mCurrentSampleInfoSizes = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); 3056 mCurrentSampleInfoAllocSize = smplcnt; 3057 } 3058 3059 mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt); 3060 return OK; 3061} 3062 3063status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( 3064 off64_t offset, off64_t /* size */) { 3065 ALOGV("parseSampleAuxiliaryInformationOffsets"); 3066 // 14496-12 8.7.13 3067 uint8_t version; 3068 if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { 3069 return ERROR_IO; 3070 } 3071 offset++; 3072 3073 uint32_t flags; 3074 if (!mDataSource->getUInt24(offset, &flags)) { 3075 return ERROR_IO; 3076 } 3077 offset += 3; 3078 3079 uint32_t entrycount; 3080 if (!mDataSource->getUInt32(offset, &entrycount)) { 3081 return ERROR_IO; 3082 } 3083 offset += 4; 3084 3085 if (entrycount > mCurrentSampleInfoOffsetsAllocSize) { 3086 mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8); 3087 mCurrentSampleInfoOffsetsAllocSize = entrycount; 3088 } 3089 mCurrentSampleInfoOffsetCount = entrycount; 3090 3091 for (size_t i = 0; i < entrycount; i++) { 3092 if (version == 0) { 3093 uint32_t tmp; 3094 if (!mDataSource->getUInt32(offset, &tmp)) { 3095 return ERROR_IO; 3096 } 3097 mCurrentSampleInfoOffsets[i] = tmp; 3098 offset += 4; 3099 } else { 3100 uint64_t tmp; 3101 if (!mDataSource->getUInt64(offset, &tmp)) { 3102 return ERROR_IO; 3103 } 3104 mCurrentSampleInfoOffsets[i] = tmp; 3105 offset += 8; 3106 } 3107 } 3108 3109 // parse clear/encrypted data 3110 3111 off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof 3112 3113 drmoffset += mCurrentMoofOffset; 3114 int ivlength; 3115 CHECK(mFormat->findInt32(kKeyCryptoDefaultIVSize, &ivlength)); 3116 3117 // read CencSampleAuxiliaryDataFormats 3118 for (size_t i = 0; i < mCurrentSampleInfoCount; i++) { 3119 Sample *smpl = &mCurrentSamples.editItemAt(i); 3120 3121 memset(smpl->iv, 0, 16); 3122 if (mDataSource->readAt(drmoffset, smpl->iv, ivlength) != ivlength) { 3123 return ERROR_IO; 3124 } 3125 3126 drmoffset += ivlength; 3127 3128 int32_t smplinfosize = mCurrentDefaultSampleInfoSize; 3129 if (smplinfosize == 0) { 3130 smplinfosize = mCurrentSampleInfoSizes[i]; 3131 } 3132 if (smplinfosize > ivlength) { 3133 uint16_t numsubsamples; 3134 if (!mDataSource->getUInt16(drmoffset, &numsubsamples)) { 3135 return ERROR_IO; 3136 } 3137 drmoffset += 2; 3138 for (size_t j = 0; j < numsubsamples; j++) { 3139 uint16_t numclear; 3140 uint32_t numencrypted; 3141 if (!mDataSource->getUInt16(drmoffset, &numclear)) { 3142 return ERROR_IO; 3143 } 3144 drmoffset += 2; 3145 if (!mDataSource->getUInt32(drmoffset, &numencrypted)) { 3146 return ERROR_IO; 3147 } 3148 drmoffset += 4; 3149 smpl->clearsizes.add(numclear); 3150 smpl->encryptedsizes.add(numencrypted); 3151 } 3152 } else { 3153 smpl->clearsizes.add(0); 3154 smpl->encryptedsizes.add(smpl->size); 3155 } 3156 } 3157 3158 3159 return OK; 3160} 3161 3162status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) { 3163 3164 if (size < 8) { 3165 return -EINVAL; 3166 } 3167 3168 uint32_t flags; 3169 if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags 3170 return ERROR_MALFORMED; 3171 } 3172 3173 if (flags & 0xff000000) { 3174 return -EINVAL; 3175 } 3176 3177 if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) { 3178 return ERROR_MALFORMED; 3179 } 3180 3181 if (mLastParsedTrackId != mTrackId) { 3182 // this is not the right track, skip it 3183 return OK; 3184 } 3185 3186 mTrackFragmentHeaderInfo.mFlags = flags; 3187 mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId; 3188 offset += 8; 3189 size -= 8; 3190 3191 ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID); 3192 3193 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) { 3194 if (size < 8) { 3195 return -EINVAL; 3196 } 3197 3198 if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) { 3199 return ERROR_MALFORMED; 3200 } 3201 offset += 8; 3202 size -= 8; 3203 } 3204 3205 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) { 3206 if (size < 4) { 3207 return -EINVAL; 3208 } 3209 3210 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) { 3211 return ERROR_MALFORMED; 3212 } 3213 offset += 4; 3214 size -= 4; 3215 } 3216 3217 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 3218 if (size < 4) { 3219 return -EINVAL; 3220 } 3221 3222 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) { 3223 return ERROR_MALFORMED; 3224 } 3225 offset += 4; 3226 size -= 4; 3227 } 3228 3229 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 3230 if (size < 4) { 3231 return -EINVAL; 3232 } 3233 3234 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) { 3235 return ERROR_MALFORMED; 3236 } 3237 offset += 4; 3238 size -= 4; 3239 } 3240 3241 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 3242 if (size < 4) { 3243 return -EINVAL; 3244 } 3245 3246 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) { 3247 return ERROR_MALFORMED; 3248 } 3249 offset += 4; 3250 size -= 4; 3251 } 3252 3253 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) { 3254 mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset; 3255 } 3256 3257 mTrackFragmentHeaderInfo.mDataOffset = 0; 3258 return OK; 3259} 3260 3261status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { 3262 3263 ALOGV("MPEG4Extractor::parseTrackFragmentRun"); 3264 if (size < 8) { 3265 return -EINVAL; 3266 } 3267 3268 enum { 3269 kDataOffsetPresent = 0x01, 3270 kFirstSampleFlagsPresent = 0x04, 3271 kSampleDurationPresent = 0x100, 3272 kSampleSizePresent = 0x200, 3273 kSampleFlagsPresent = 0x400, 3274 kSampleCompositionTimeOffsetPresent = 0x800, 3275 }; 3276 3277 uint32_t flags; 3278 if (!mDataSource->getUInt32(offset, &flags)) { 3279 return ERROR_MALFORMED; 3280 } 3281 ALOGV("fragment run flags: %08x", flags); 3282 3283 if (flags & 0xff000000) { 3284 return -EINVAL; 3285 } 3286 3287 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) { 3288 // These two shall not be used together. 3289 return -EINVAL; 3290 } 3291 3292 uint32_t sampleCount; 3293 if (!mDataSource->getUInt32(offset + 4, &sampleCount)) { 3294 return ERROR_MALFORMED; 3295 } 3296 offset += 8; 3297 size -= 8; 3298 3299 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset; 3300 3301 uint32_t firstSampleFlags = 0; 3302 3303 if (flags & kDataOffsetPresent) { 3304 if (size < 4) { 3305 return -EINVAL; 3306 } 3307 3308 int32_t dataOffsetDelta; 3309 if (!mDataSource->getUInt32(offset, (uint32_t*)&dataOffsetDelta)) { 3310 return ERROR_MALFORMED; 3311 } 3312 3313 dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta; 3314 3315 offset += 4; 3316 size -= 4; 3317 } 3318 3319 if (flags & kFirstSampleFlagsPresent) { 3320 if (size < 4) { 3321 return -EINVAL; 3322 } 3323 3324 if (!mDataSource->getUInt32(offset, &firstSampleFlags)) { 3325 return ERROR_MALFORMED; 3326 } 3327 offset += 4; 3328 size -= 4; 3329 } 3330 3331 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0, 3332 sampleCtsOffset = 0; 3333 3334 size_t bytesPerSample = 0; 3335 if (flags & kSampleDurationPresent) { 3336 bytesPerSample += 4; 3337 } else if (mTrackFragmentHeaderInfo.mFlags 3338 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) { 3339 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3340 } else { 3341 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration; 3342 } 3343 3344 if (flags & kSampleSizePresent) { 3345 bytesPerSample += 4; 3346 } else if (mTrackFragmentHeaderInfo.mFlags 3347 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) { 3348 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 3349 } else { 3350 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize; 3351 } 3352 3353 if (flags & kSampleFlagsPresent) { 3354 bytesPerSample += 4; 3355 } else if (mTrackFragmentHeaderInfo.mFlags 3356 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) { 3357 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 3358 } else { 3359 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags; 3360 } 3361 3362 if (flags & kSampleCompositionTimeOffsetPresent) { 3363 bytesPerSample += 4; 3364 } else { 3365 sampleCtsOffset = 0; 3366 } 3367 3368 if (size < sampleCount * bytesPerSample) { 3369 return -EINVAL; 3370 } 3371 3372 Sample tmp; 3373 for (uint32_t i = 0; i < sampleCount; ++i) { 3374 if (flags & kSampleDurationPresent) { 3375 if (!mDataSource->getUInt32(offset, &sampleDuration)) { 3376 return ERROR_MALFORMED; 3377 } 3378 offset += 4; 3379 } 3380 3381 if (flags & kSampleSizePresent) { 3382 if (!mDataSource->getUInt32(offset, &sampleSize)) { 3383 return ERROR_MALFORMED; 3384 } 3385 offset += 4; 3386 } 3387 3388 if (flags & kSampleFlagsPresent) { 3389 if (!mDataSource->getUInt32(offset, &sampleFlags)) { 3390 return ERROR_MALFORMED; 3391 } 3392 offset += 4; 3393 } 3394 3395 if (flags & kSampleCompositionTimeOffsetPresent) { 3396 if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) { 3397 return ERROR_MALFORMED; 3398 } 3399 offset += 4; 3400 } 3401 3402 ALOGV("adding sample %d at offset 0x%08llx, size %u, duration %u, " 3403 " flags 0x%08x", i + 1, 3404 dataOffset, sampleSize, sampleDuration, 3405 (flags & kFirstSampleFlagsPresent) && i == 0 3406 ? firstSampleFlags : sampleFlags); 3407 tmp.offset = dataOffset; 3408 tmp.size = sampleSize; 3409 tmp.duration = sampleDuration; 3410 mCurrentSamples.add(tmp); 3411 3412 dataOffset += sampleSize; 3413 } 3414 3415 mTrackFragmentHeaderInfo.mDataOffset = dataOffset; 3416 3417 return OK; 3418} 3419 3420sp<MetaData> MPEG4Source::getFormat() { 3421 Mutex::Autolock autoLock(mLock); 3422 3423 return mFormat; 3424} 3425 3426size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 3427 switch (mNALLengthSize) { 3428 case 1: 3429 return *data; 3430 case 2: 3431 return U16_AT(data); 3432 case 3: 3433 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 3434 case 4: 3435 return U32_AT(data); 3436 } 3437 3438 // This cannot happen, mNALLengthSize springs to life by adding 1 to 3439 // a 2-bit integer. 3440 CHECK(!"Should not be here."); 3441 3442 return 0; 3443} 3444 3445status_t MPEG4Source::read( 3446 MediaBuffer **out, const ReadOptions *options) { 3447 Mutex::Autolock autoLock(mLock); 3448 3449 CHECK(mStarted); 3450 3451 if (mFirstMoofOffset > 0) { 3452 return fragmentedRead(out, options); 3453 } 3454 3455 *out = NULL; 3456 3457 int64_t targetSampleTimeUs = -1; 3458 3459 int64_t seekTimeUs; 3460 ReadOptions::SeekMode mode; 3461 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3462 uint32_t findFlags = 0; 3463 switch (mode) { 3464 case ReadOptions::SEEK_PREVIOUS_SYNC: 3465 findFlags = SampleTable::kFlagBefore; 3466 break; 3467 case ReadOptions::SEEK_NEXT_SYNC: 3468 findFlags = SampleTable::kFlagAfter; 3469 break; 3470 case ReadOptions::SEEK_CLOSEST_SYNC: 3471 case ReadOptions::SEEK_CLOSEST: 3472 findFlags = SampleTable::kFlagClosest; 3473 break; 3474 default: 3475 CHECK(!"Should not be here."); 3476 break; 3477 } 3478 3479 uint32_t sampleIndex; 3480 status_t err = mSampleTable->findSampleAtTime( 3481 seekTimeUs * mTimescale / 1000000, 3482 &sampleIndex, findFlags); 3483 3484 if (mode == ReadOptions::SEEK_CLOSEST) { 3485 // We found the closest sample already, now we want the sync 3486 // sample preceding it (or the sample itself of course), even 3487 // if the subsequent sync sample is closer. 3488 findFlags = SampleTable::kFlagBefore; 3489 } 3490 3491 uint32_t syncSampleIndex; 3492 if (err == OK) { 3493 err = mSampleTable->findSyncSampleNear( 3494 sampleIndex, &syncSampleIndex, findFlags); 3495 } 3496 3497 uint32_t sampleTime; 3498 if (err == OK) { 3499 err = mSampleTable->getMetaDataForSample( 3500 sampleIndex, NULL, NULL, &sampleTime); 3501 } 3502 3503 if (err != OK) { 3504 if (err == ERROR_OUT_OF_RANGE) { 3505 // An attempt to seek past the end of the stream would 3506 // normally cause this ERROR_OUT_OF_RANGE error. Propagating 3507 // this all the way to the MediaPlayer would cause abnormal 3508 // termination. Legacy behaviour appears to be to behave as if 3509 // we had seeked to the end of stream, ending normally. 3510 err = ERROR_END_OF_STREAM; 3511 } 3512 ALOGV("end of stream"); 3513 return err; 3514 } 3515 3516 if (mode == ReadOptions::SEEK_CLOSEST) { 3517 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 3518 } 3519 3520#if 0 3521 uint32_t syncSampleTime; 3522 CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 3523 syncSampleIndex, NULL, NULL, &syncSampleTime)); 3524 3525 ALOGI("seek to time %lld us => sample at time %lld us, " 3526 "sync sample at time %lld us", 3527 seekTimeUs, 3528 sampleTime * 1000000ll / mTimescale, 3529 syncSampleTime * 1000000ll / mTimescale); 3530#endif 3531 3532 mCurrentSampleIndex = syncSampleIndex; 3533 if (mBuffer != NULL) { 3534 mBuffer->release(); 3535 mBuffer = NULL; 3536 } 3537 3538 // fall through 3539 } 3540 3541 off64_t offset; 3542 size_t size; 3543 uint32_t cts, stts; 3544 bool isSyncSample; 3545 bool newBuffer = false; 3546 if (mBuffer == NULL) { 3547 newBuffer = true; 3548 3549 status_t err = 3550 mSampleTable->getMetaDataForSample( 3551 mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample, &stts); 3552 3553 if (err != OK) { 3554 return err; 3555 } 3556 3557 err = mGroup->acquire_buffer(&mBuffer); 3558 3559 if (err != OK) { 3560 CHECK(mBuffer == NULL); 3561 return err; 3562 } 3563 } 3564 3565 if (!mIsAVC || mWantsNALFragments) { 3566 if (newBuffer) { 3567 ssize_t num_bytes_read = 3568 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3569 3570 if (num_bytes_read < (ssize_t)size) { 3571 mBuffer->release(); 3572 mBuffer = NULL; 3573 3574 return ERROR_IO; 3575 } 3576 3577 CHECK(mBuffer != NULL); 3578 mBuffer->set_range(0, size); 3579 mBuffer->meta_data()->clear(); 3580 mBuffer->meta_data()->setInt64( 3581 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3582 mBuffer->meta_data()->setInt64( 3583 kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3584 3585 if (targetSampleTimeUs >= 0) { 3586 mBuffer->meta_data()->setInt64( 3587 kKeyTargetTime, targetSampleTimeUs); 3588 } 3589 3590 if (isSyncSample) { 3591 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 3592 } 3593 3594 ++mCurrentSampleIndex; 3595 } 3596 3597 if (!mIsAVC) { 3598 *out = mBuffer; 3599 mBuffer = NULL; 3600 3601 return OK; 3602 } 3603 3604 // Each NAL unit is split up into its constituent fragments and 3605 // each one of them returned in its own buffer. 3606 3607 CHECK(mBuffer->range_length() >= mNALLengthSize); 3608 3609 const uint8_t *src = 3610 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3611 3612 size_t nal_size = parseNALSize(src); 3613 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 3614 ALOGE("incomplete NAL unit."); 3615 3616 mBuffer->release(); 3617 mBuffer = NULL; 3618 3619 return ERROR_MALFORMED; 3620 } 3621 3622 MediaBuffer *clone = mBuffer->clone(); 3623 CHECK(clone != NULL); 3624 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3625 3626 CHECK(mBuffer != NULL); 3627 mBuffer->set_range( 3628 mBuffer->range_offset() + mNALLengthSize + nal_size, 3629 mBuffer->range_length() - mNALLengthSize - nal_size); 3630 3631 if (mBuffer->range_length() == 0) { 3632 mBuffer->release(); 3633 mBuffer = NULL; 3634 } 3635 3636 *out = clone; 3637 3638 return OK; 3639 } else { 3640 // Whole NAL units are returned but each fragment is prefixed by 3641 // the start code (0x00 00 00 01). 3642 ssize_t num_bytes_read = 0; 3643 int32_t drm = 0; 3644 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3645 if (usesDRM) { 3646 num_bytes_read = 3647 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3648 } else { 3649 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3650 } 3651 3652 if (num_bytes_read < (ssize_t)size) { 3653 mBuffer->release(); 3654 mBuffer = NULL; 3655 3656 return ERROR_IO; 3657 } 3658 3659 if (usesDRM) { 3660 CHECK(mBuffer != NULL); 3661 mBuffer->set_range(0, size); 3662 3663 } else { 3664 uint8_t *dstData = (uint8_t *)mBuffer->data(); 3665 size_t srcOffset = 0; 3666 size_t dstOffset = 0; 3667 3668 while (srcOffset < size) { 3669 bool isMalFormed = (srcOffset + mNALLengthSize > size); 3670 size_t nalLength = 0; 3671 if (!isMalFormed) { 3672 nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 3673 srcOffset += mNALLengthSize; 3674 isMalFormed = srcOffset + nalLength > size; 3675 } 3676 3677 if (isMalFormed) { 3678 ALOGE("Video is malformed"); 3679 mBuffer->release(); 3680 mBuffer = NULL; 3681 return ERROR_MALFORMED; 3682 } 3683 3684 if (nalLength == 0) { 3685 continue; 3686 } 3687 3688 CHECK(dstOffset + 4 <= mBuffer->size()); 3689 3690 dstData[dstOffset++] = 0; 3691 dstData[dstOffset++] = 0; 3692 dstData[dstOffset++] = 0; 3693 dstData[dstOffset++] = 1; 3694 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3695 srcOffset += nalLength; 3696 dstOffset += nalLength; 3697 } 3698 CHECK_EQ(srcOffset, size); 3699 CHECK(mBuffer != NULL); 3700 mBuffer->set_range(0, dstOffset); 3701 } 3702 3703 mBuffer->meta_data()->clear(); 3704 mBuffer->meta_data()->setInt64( 3705 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3706 mBuffer->meta_data()->setInt64( 3707 kKeyDuration, ((int64_t)stts * 1000000) / mTimescale); 3708 3709 if (targetSampleTimeUs >= 0) { 3710 mBuffer->meta_data()->setInt64( 3711 kKeyTargetTime, targetSampleTimeUs); 3712 } 3713 3714 if (isSyncSample) { 3715 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 3716 } 3717 3718 ++mCurrentSampleIndex; 3719 3720 *out = mBuffer; 3721 mBuffer = NULL; 3722 3723 return OK; 3724 } 3725} 3726 3727status_t MPEG4Source::fragmentedRead( 3728 MediaBuffer **out, const ReadOptions *options) { 3729 3730 ALOGV("MPEG4Source::fragmentedRead"); 3731 3732 CHECK(mStarted); 3733 3734 *out = NULL; 3735 3736 int64_t targetSampleTimeUs = -1; 3737 3738 int64_t seekTimeUs; 3739 ReadOptions::SeekMode mode; 3740 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 3741 3742 int numSidxEntries = mSegments.size(); 3743 if (numSidxEntries != 0) { 3744 int64_t totalTime = 0; 3745 off64_t totalOffset = mFirstMoofOffset; 3746 for (int i = 0; i < numSidxEntries; i++) { 3747 const SidxEntry *se = &mSegments[i]; 3748 if (totalTime + se->mDurationUs > seekTimeUs) { 3749 // The requested time is somewhere in this segment 3750 if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) || 3751 (mode == ReadOptions::SEEK_CLOSEST_SYNC && 3752 (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) { 3753 // requested next sync, or closest sync and it was closer to the end of 3754 // this segment 3755 totalTime += se->mDurationUs; 3756 totalOffset += se->mSize; 3757 } 3758 break; 3759 } 3760 totalTime += se->mDurationUs; 3761 totalOffset += se->mSize; 3762 } 3763 mCurrentMoofOffset = totalOffset; 3764 mCurrentSamples.clear(); 3765 mCurrentSampleIndex = 0; 3766 parseChunk(&totalOffset); 3767 mCurrentTime = totalTime * mTimescale / 1000000ll; 3768 } else { 3769 // without sidx boxes, we can only seek to 0 3770 mCurrentMoofOffset = mFirstMoofOffset; 3771 mCurrentSamples.clear(); 3772 mCurrentSampleIndex = 0; 3773 off64_t tmp = mCurrentMoofOffset; 3774 parseChunk(&tmp); 3775 mCurrentTime = 0; 3776 } 3777 3778 if (mBuffer != NULL) { 3779 mBuffer->release(); 3780 mBuffer = NULL; 3781 } 3782 3783 // fall through 3784 } 3785 3786 off64_t offset = 0; 3787 size_t size = 0; 3788 uint32_t cts = 0; 3789 bool isSyncSample = false; 3790 bool newBuffer = false; 3791 if (mBuffer == NULL) { 3792 newBuffer = true; 3793 3794 if (mCurrentSampleIndex >= mCurrentSamples.size()) { 3795 // move to next fragment if there is one 3796 if (mNextMoofOffset <= mCurrentMoofOffset) { 3797 return ERROR_END_OF_STREAM; 3798 } 3799 off64_t nextMoof = mNextMoofOffset; 3800 mCurrentMoofOffset = nextMoof; 3801 mCurrentSamples.clear(); 3802 mCurrentSampleIndex = 0; 3803 parseChunk(&nextMoof); 3804 if (mCurrentSampleIndex >= mCurrentSamples.size()) { 3805 return ERROR_END_OF_STREAM; 3806 } 3807 } 3808 3809 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 3810 offset = smpl->offset; 3811 size = smpl->size; 3812 cts = mCurrentTime; 3813 mCurrentTime += smpl->duration; 3814 isSyncSample = (mCurrentSampleIndex == 0); // XXX 3815 3816 status_t err = mGroup->acquire_buffer(&mBuffer); 3817 3818 if (err != OK) { 3819 CHECK(mBuffer == NULL); 3820 ALOGV("acquire_buffer returned %d", err); 3821 return err; 3822 } 3823 } 3824 3825 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex]; 3826 const sp<MetaData> bufmeta = mBuffer->meta_data(); 3827 bufmeta->clear(); 3828 if (smpl->encryptedsizes.size()) { 3829 // store clear/encrypted lengths in metadata 3830 bufmeta->setData(kKeyPlainSizes, 0, 3831 smpl->clearsizes.array(), smpl->clearsizes.size() * 4); 3832 bufmeta->setData(kKeyEncryptedSizes, 0, 3833 smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4); 3834 bufmeta->setData(kKeyCryptoIV, 0, smpl->iv, 16); // use 16 or the actual size? 3835 bufmeta->setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize); 3836 bufmeta->setInt32(kKeyCryptoMode, mCryptoMode); 3837 bufmeta->setData(kKeyCryptoKey, 0, mCryptoKey, 16); 3838 } 3839 3840 if (!mIsAVC || mWantsNALFragments) { 3841 if (newBuffer) { 3842 ssize_t num_bytes_read = 3843 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 3844 3845 if (num_bytes_read < (ssize_t)size) { 3846 mBuffer->release(); 3847 mBuffer = NULL; 3848 3849 ALOGV("i/o error"); 3850 return ERROR_IO; 3851 } 3852 3853 CHECK(mBuffer != NULL); 3854 mBuffer->set_range(0, size); 3855 mBuffer->meta_data()->setInt64( 3856 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3857 mBuffer->meta_data()->setInt64( 3858 kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 3859 3860 if (targetSampleTimeUs >= 0) { 3861 mBuffer->meta_data()->setInt64( 3862 kKeyTargetTime, targetSampleTimeUs); 3863 } 3864 3865 if (isSyncSample) { 3866 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 3867 } 3868 3869 ++mCurrentSampleIndex; 3870 } 3871 3872 if (!mIsAVC) { 3873 *out = mBuffer; 3874 mBuffer = NULL; 3875 3876 return OK; 3877 } 3878 3879 // Each NAL unit is split up into its constituent fragments and 3880 // each one of them returned in its own buffer. 3881 3882 CHECK(mBuffer->range_length() >= mNALLengthSize); 3883 3884 const uint8_t *src = 3885 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 3886 3887 size_t nal_size = parseNALSize(src); 3888 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 3889 ALOGE("incomplete NAL unit."); 3890 3891 mBuffer->release(); 3892 mBuffer = NULL; 3893 3894 return ERROR_MALFORMED; 3895 } 3896 3897 MediaBuffer *clone = mBuffer->clone(); 3898 CHECK(clone != NULL); 3899 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 3900 3901 CHECK(mBuffer != NULL); 3902 mBuffer->set_range( 3903 mBuffer->range_offset() + mNALLengthSize + nal_size, 3904 mBuffer->range_length() - mNALLengthSize - nal_size); 3905 3906 if (mBuffer->range_length() == 0) { 3907 mBuffer->release(); 3908 mBuffer = NULL; 3909 } 3910 3911 *out = clone; 3912 3913 return OK; 3914 } else { 3915 ALOGV("whole NAL"); 3916 // Whole NAL units are returned but each fragment is prefixed by 3917 // the start code (0x00 00 00 01). 3918 ssize_t num_bytes_read = 0; 3919 int32_t drm = 0; 3920 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 3921 if (usesDRM) { 3922 num_bytes_read = 3923 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 3924 } else { 3925 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 3926 } 3927 3928 if (num_bytes_read < (ssize_t)size) { 3929 mBuffer->release(); 3930 mBuffer = NULL; 3931 3932 ALOGV("i/o error"); 3933 return ERROR_IO; 3934 } 3935 3936 if (usesDRM) { 3937 CHECK(mBuffer != NULL); 3938 mBuffer->set_range(0, size); 3939 3940 } else { 3941 uint8_t *dstData = (uint8_t *)mBuffer->data(); 3942 size_t srcOffset = 0; 3943 size_t dstOffset = 0; 3944 3945 while (srcOffset < size) { 3946 bool isMalFormed = (srcOffset + mNALLengthSize > size); 3947 size_t nalLength = 0; 3948 if (!isMalFormed) { 3949 nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 3950 srcOffset += mNALLengthSize; 3951 isMalFormed = srcOffset + nalLength > size; 3952 } 3953 3954 if (isMalFormed) { 3955 ALOGE("Video is malformed"); 3956 mBuffer->release(); 3957 mBuffer = NULL; 3958 return ERROR_MALFORMED; 3959 } 3960 3961 if (nalLength == 0) { 3962 continue; 3963 } 3964 3965 CHECK(dstOffset + 4 <= mBuffer->size()); 3966 3967 dstData[dstOffset++] = 0; 3968 dstData[dstOffset++] = 0; 3969 dstData[dstOffset++] = 0; 3970 dstData[dstOffset++] = 1; 3971 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 3972 srcOffset += nalLength; 3973 dstOffset += nalLength; 3974 } 3975 CHECK_EQ(srcOffset, size); 3976 CHECK(mBuffer != NULL); 3977 mBuffer->set_range(0, dstOffset); 3978 } 3979 3980 mBuffer->meta_data()->setInt64( 3981 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 3982 mBuffer->meta_data()->setInt64( 3983 kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale); 3984 3985 if (targetSampleTimeUs >= 0) { 3986 mBuffer->meta_data()->setInt64( 3987 kKeyTargetTime, targetSampleTimeUs); 3988 } 3989 3990 if (isSyncSample) { 3991 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 3992 } 3993 3994 ++mCurrentSampleIndex; 3995 3996 *out = mBuffer; 3997 mBuffer = NULL; 3998 3999 return OK; 4000 } 4001} 4002 4003MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 4004 const char *mimePrefix) { 4005 for (Track *track = mFirstTrack; track != NULL; track = track->next) { 4006 const char *mime; 4007 if (track->meta != NULL 4008 && track->meta->findCString(kKeyMIMEType, &mime) 4009 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 4010 return track; 4011 } 4012 } 4013 4014 return NULL; 4015} 4016 4017static bool LegacySniffMPEG4( 4018 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 4019 uint8_t header[8]; 4020 4021 ssize_t n = source->readAt(4, header, sizeof(header)); 4022 if (n < (ssize_t)sizeof(header)) { 4023 return false; 4024 } 4025 4026 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 4027 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 4028 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 4029 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 4030 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 4031 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 4032 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 4033 *confidence = 0.4; 4034 4035 return true; 4036 } 4037 4038 return false; 4039} 4040 4041static bool isCompatibleBrand(uint32_t fourcc) { 4042 static const uint32_t kCompatibleBrands[] = { 4043 FOURCC('i', 's', 'o', 'm'), 4044 FOURCC('i', 's', 'o', '2'), 4045 FOURCC('a', 'v', 'c', '1'), 4046 FOURCC('3', 'g', 'p', '4'), 4047 FOURCC('m', 'p', '4', '1'), 4048 FOURCC('m', 'p', '4', '2'), 4049 4050 // Won't promise that the following file types can be played. 4051 // Just give these file types a chance. 4052 FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 4053 FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 4054 4055 FOURCC('3', 'g', '2', 'a'), // 3GPP2 4056 FOURCC('3', 'g', '2', 'b'), 4057 }; 4058 4059 for (size_t i = 0; 4060 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 4061 ++i) { 4062 if (kCompatibleBrands[i] == fourcc) { 4063 return true; 4064 } 4065 } 4066 4067 return false; 4068} 4069 4070// Attempt to actually parse the 'ftyp' atom and determine if a suitable 4071// compatible brand is present. 4072// Also try to identify where this file's metadata ends 4073// (end of the 'moov' atom) and report it to the caller as part of 4074// the metadata. 4075static bool BetterSniffMPEG4( 4076 const sp<DataSource> &source, String8 *mimeType, float *confidence, 4077 sp<AMessage> *meta) { 4078 // We scan up to 128 bytes to identify this file as an MP4. 4079 static const off64_t kMaxScanOffset = 128ll; 4080 4081 off64_t offset = 0ll; 4082 bool foundGoodFileType = false; 4083 off64_t moovAtomEndOffset = -1ll; 4084 bool done = false; 4085 4086 while (!done && offset < kMaxScanOffset) { 4087 uint32_t hdr[2]; 4088 if (source->readAt(offset, hdr, 8) < 8) { 4089 return false; 4090 } 4091 4092 uint64_t chunkSize = ntohl(hdr[0]); 4093 uint32_t chunkType = ntohl(hdr[1]); 4094 off64_t chunkDataOffset = offset + 8; 4095 4096 if (chunkSize == 1) { 4097 if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 4098 return false; 4099 } 4100 4101 chunkSize = ntoh64(chunkSize); 4102 chunkDataOffset += 8; 4103 4104 if (chunkSize < 16) { 4105 // The smallest valid chunk is 16 bytes long in this case. 4106 return false; 4107 } 4108 } else if (chunkSize < 8) { 4109 // The smallest valid chunk is 8 bytes long. 4110 return false; 4111 } 4112 4113 off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 4114 4115 char chunkstring[5]; 4116 MakeFourCCString(chunkType, chunkstring); 4117 ALOGV("saw chunk type %s, size %lld @ %lld", chunkstring, chunkSize, offset); 4118 switch (chunkType) { 4119 case FOURCC('f', 't', 'y', 'p'): 4120 { 4121 if (chunkDataSize < 8) { 4122 return false; 4123 } 4124 4125 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 4126 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 4127 if (i == 1) { 4128 // Skip this index, it refers to the minorVersion, 4129 // not a brand. 4130 continue; 4131 } 4132 4133 uint32_t brand; 4134 if (source->readAt( 4135 chunkDataOffset + 4 * i, &brand, 4) < 4) { 4136 return false; 4137 } 4138 4139 brand = ntohl(brand); 4140 4141 if (isCompatibleBrand(brand)) { 4142 foundGoodFileType = true; 4143 break; 4144 } 4145 } 4146 4147 if (!foundGoodFileType) { 4148 return false; 4149 } 4150 4151 break; 4152 } 4153 4154 case FOURCC('m', 'o', 'o', 'v'): 4155 { 4156 moovAtomEndOffset = offset + chunkSize; 4157 4158 done = true; 4159 break; 4160 } 4161 4162 default: 4163 break; 4164 } 4165 4166 offset += chunkSize; 4167 } 4168 4169 if (!foundGoodFileType) { 4170 return false; 4171 } 4172 4173 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 4174 *confidence = 0.4f; 4175 4176 if (moovAtomEndOffset >= 0) { 4177 *meta = new AMessage; 4178 (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 4179 4180 ALOGV("found metadata size: %lld", moovAtomEndOffset); 4181 } 4182 4183 return true; 4184} 4185 4186bool SniffMPEG4( 4187 const sp<DataSource> &source, String8 *mimeType, float *confidence, 4188 sp<AMessage> *meta) { 4189 if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 4190 return true; 4191 } 4192 4193 if (LegacySniffMPEG4(source, mimeType, confidence)) { 4194 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 4195 return true; 4196 } 4197 4198 return false; 4199} 4200 4201} // namespace android 4202