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