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