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