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