MPEG4Extractor.cpp revision 6655174826330afe66ef766258181ae8c11f3f6c
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_TAG "MPEG4Extractor" 18#include <utils/Log.h> 19 20#include "include/MPEG4Extractor.h" 21#include "include/SampleTable.h" 22#include "include/ESDS.h" 23 24#include <arpa/inet.h> 25 26#include <ctype.h> 27#include <stdint.h> 28#include <stdlib.h> 29#include <string.h> 30 31#include <media/stagefright/foundation/ADebug.h> 32#include <media/stagefright/foundation/AMessage.h> 33#include <media/stagefright/DataSource.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 <media/stagefright/Utils.h> 40#include <utils/String8.h> 41 42namespace android { 43 44class MPEG4Source : public MediaSource { 45public: 46 // Caller retains ownership of both "dataSource" and "sampleTable". 47 MPEG4Source(const sp<MetaData> &format, 48 const sp<DataSource> &dataSource, 49 int32_t timeScale, 50 const sp<SampleTable> &sampleTable); 51 52 virtual status_t start(MetaData *params = NULL); 53 virtual status_t stop(); 54 55 virtual sp<MetaData> getFormat(); 56 57 virtual status_t read( 58 MediaBuffer **buffer, const ReadOptions *options = NULL); 59 60protected: 61 virtual ~MPEG4Source(); 62 63private: 64 Mutex mLock; 65 66 sp<MetaData> mFormat; 67 sp<DataSource> mDataSource; 68 int32_t mTimescale; 69 sp<SampleTable> mSampleTable; 70 uint32_t mCurrentSampleIndex; 71 72 bool mIsAVC; 73 size_t mNALLengthSize; 74 75 bool mStarted; 76 77 MediaBufferGroup *mGroup; 78 79 MediaBuffer *mBuffer; 80 81 bool mWantsNALFragments; 82 83 uint8_t *mSrcBuffer; 84 85 size_t parseNALSize(const uint8_t *data) const; 86 87 MPEG4Source(const MPEG4Source &); 88 MPEG4Source &operator=(const MPEG4Source &); 89}; 90 91// This custom data source wraps an existing one and satisfies requests 92// falling entirely within a cached range from the cache while forwarding 93// all remaining requests to the wrapped datasource. 94// This is used to cache the full sampletable metadata for a single track, 95// possibly wrapping multiple times to cover all tracks, i.e. 96// Each MPEG4DataSource caches the sampletable metadata for a single track. 97 98struct MPEG4DataSource : public DataSource { 99 MPEG4DataSource(const sp<DataSource> &source); 100 101 virtual status_t initCheck() const; 102 virtual ssize_t readAt(off64_t offset, void *data, size_t size); 103 virtual status_t getSize(off64_t *size); 104 virtual uint32_t flags(); 105 106 status_t setCachedRange(off64_t offset, size_t size); 107 108protected: 109 virtual ~MPEG4DataSource(); 110 111private: 112 Mutex mLock; 113 114 sp<DataSource> mSource; 115 off64_t mCachedOffset; 116 size_t mCachedSize; 117 uint8_t *mCache; 118 119 void clearCache(); 120 121 MPEG4DataSource(const MPEG4DataSource &); 122 MPEG4DataSource &operator=(const MPEG4DataSource &); 123}; 124 125MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 126 : mSource(source), 127 mCachedOffset(0), 128 mCachedSize(0), 129 mCache(NULL) { 130} 131 132MPEG4DataSource::~MPEG4DataSource() { 133 clearCache(); 134} 135 136void MPEG4DataSource::clearCache() { 137 if (mCache) { 138 free(mCache); 139 mCache = NULL; 140 } 141 142 mCachedOffset = 0; 143 mCachedSize = 0; 144} 145 146status_t MPEG4DataSource::initCheck() const { 147 return mSource->initCheck(); 148} 149 150ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { 151 Mutex::Autolock autoLock(mLock); 152 153 if (offset >= mCachedOffset 154 && offset + size <= mCachedOffset + mCachedSize) { 155 memcpy(data, &mCache[offset - mCachedOffset], size); 156 return size; 157 } 158 159 return mSource->readAt(offset, data, size); 160} 161 162status_t MPEG4DataSource::getSize(off64_t *size) { 163 return mSource->getSize(size); 164} 165 166uint32_t MPEG4DataSource::flags() { 167 return mSource->flags(); 168} 169 170status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) { 171 Mutex::Autolock autoLock(mLock); 172 173 clearCache(); 174 175 mCache = (uint8_t *)malloc(size); 176 177 if (mCache == NULL) { 178 return -ENOMEM; 179 } 180 181 mCachedOffset = offset; 182 mCachedSize = size; 183 184 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 185 186 if (err < (ssize_t)size) { 187 clearCache(); 188 189 return ERROR_IO; 190 } 191 192 return OK; 193} 194 195//////////////////////////////////////////////////////////////////////////////// 196 197static void hexdump(const void *_data, size_t size) { 198 const uint8_t *data = (const uint8_t *)_data; 199 size_t offset = 0; 200 while (offset < size) { 201 printf("0x%04x ", offset); 202 203 size_t n = size - offset; 204 if (n > 16) { 205 n = 16; 206 } 207 208 for (size_t i = 0; i < 16; ++i) { 209 if (i == 8) { 210 printf(" "); 211 } 212 213 if (offset + i < size) { 214 printf("%02x ", data[offset + i]); 215 } else { 216 printf(" "); 217 } 218 } 219 220 printf(" "); 221 222 for (size_t i = 0; i < n; ++i) { 223 if (isprint(data[offset + i])) { 224 printf("%c", data[offset + i]); 225 } else { 226 printf("."); 227 } 228 } 229 230 printf("\n"); 231 232 offset += 16; 233 } 234} 235 236static const char *FourCC2MIME(uint32_t fourcc) { 237 switch (fourcc) { 238 case FOURCC('m', 'p', '4', 'a'): 239 return MEDIA_MIMETYPE_AUDIO_AAC; 240 241 case FOURCC('s', 'a', 'm', 'r'): 242 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 243 244 case FOURCC('s', 'a', 'w', 'b'): 245 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 246 247 case FOURCC('m', 'p', '4', 'v'): 248 return MEDIA_MIMETYPE_VIDEO_MPEG4; 249 250 case FOURCC('s', '2', '6', '3'): 251 case FOURCC('h', '2', '6', '3'): 252 case FOURCC('H', '2', '6', '3'): 253 return MEDIA_MIMETYPE_VIDEO_H263; 254 255 case FOURCC('a', 'v', 'c', '1'): 256 return MEDIA_MIMETYPE_VIDEO_AVC; 257 258 default: 259 CHECK(!"should not be here."); 260 return NULL; 261 } 262} 263 264MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 265 : mDataSource(source), 266 mInitCheck(NO_INIT), 267 mHasVideo(false), 268 mFirstTrack(NULL), 269 mLastTrack(NULL), 270 mFileMetaData(new MetaData), 271 mFirstSINF(NULL), 272 mIsDrm(false) { 273} 274 275MPEG4Extractor::~MPEG4Extractor() { 276 Track *track = mFirstTrack; 277 while (track) { 278 Track *next = track->next; 279 280 delete track; 281 track = next; 282 } 283 mFirstTrack = mLastTrack = NULL; 284 285 SINF *sinf = mFirstSINF; 286 while (sinf) { 287 SINF *next = sinf->next; 288 delete sinf->IPMPData; 289 delete sinf; 290 sinf = next; 291 } 292 mFirstSINF = NULL; 293} 294 295sp<MetaData> MPEG4Extractor::getMetaData() { 296 status_t err; 297 if ((err = readMetaData()) != OK) { 298 return new MetaData; 299 } 300 301 return mFileMetaData; 302} 303 304size_t MPEG4Extractor::countTracks() { 305 status_t err; 306 if ((err = readMetaData()) != OK) { 307 return 0; 308 } 309 310 size_t n = 0; 311 Track *track = mFirstTrack; 312 while (track) { 313 ++n; 314 track = track->next; 315 } 316 317 return n; 318} 319 320sp<MetaData> MPEG4Extractor::getTrackMetaData( 321 size_t index, uint32_t flags) { 322 status_t err; 323 if ((err = readMetaData()) != OK) { 324 return NULL; 325 } 326 327 Track *track = mFirstTrack; 328 while (index > 0) { 329 if (track == NULL) { 330 return NULL; 331 } 332 333 track = track->next; 334 --index; 335 } 336 337 if (track == NULL) { 338 return NULL; 339 } 340 341 if ((flags & kIncludeExtensiveMetaData) 342 && !track->includes_expensive_metadata) { 343 track->includes_expensive_metadata = true; 344 345 const char *mime; 346 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 347 if (!strncasecmp("video/", mime, 6)) { 348 uint32_t sampleIndex; 349 uint32_t sampleTime; 350 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 351 && track->sampleTable->getMetaDataForSample( 352 sampleIndex, NULL /* offset */, NULL /* size */, 353 &sampleTime) == OK) { 354 track->meta->setInt64( 355 kKeyThumbnailTime, 356 ((int64_t)sampleTime * 1000000) / track->timescale); 357 } 358 } 359 } 360 361 return track->meta; 362} 363 364status_t MPEG4Extractor::readMetaData() { 365 if (mInitCheck != NO_INIT) { 366 return mInitCheck; 367 } 368 369 off64_t offset = 0; 370 status_t err; 371 while ((err = parseChunk(&offset, 0)) == OK) { 372 } 373 374 if (mInitCheck == OK) { 375 if (mHasVideo) { 376 mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 377 } else { 378 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 379 } 380 381 mInitCheck = OK; 382 } else { 383 mInitCheck = err; 384 } 385 386 CHECK_NE(err, (status_t)NO_INIT); 387 return mInitCheck; 388} 389 390char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) { 391 if (mFirstSINF == NULL) { 392 return NULL; 393 } 394 395 SINF *sinf = mFirstSINF; 396 while (sinf && (trackID != sinf->trackID)) { 397 sinf = sinf->next; 398 } 399 400 if (sinf == NULL) { 401 return NULL; 402 } 403 404 *len = sinf->len; 405 return sinf->IPMPData; 406} 407 408// Reads an encoded integer 7 bits at a time until it encounters the high bit clear. 409int32_t readSize(off64_t offset, 410 const sp<DataSource> DataSource, uint8_t *numOfBytes) { 411 uint32_t size = 0; 412 uint8_t data; 413 bool moreData = true; 414 *numOfBytes = 0; 415 416 while (moreData) { 417 if (DataSource->readAt(offset, &data, 1) < 1) { 418 return -1; 419 } 420 offset ++; 421 moreData = (data >= 128) ? true : false; 422 size = (size << 7) | (data & 0x7f); // Take last 7 bits 423 (*numOfBytes) ++; 424 } 425 426 return size; 427} 428 429status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { 430 uint8_t updateIdTag; 431 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 432 return ERROR_IO; 433 } 434 data_offset ++; 435 436 if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 437 return ERROR_MALFORMED; 438 } 439 440 uint8_t numOfBytes; 441 int32_t size = readSize(data_offset, mDataSource, &numOfBytes); 442 if (size < 0) { 443 return ERROR_IO; 444 } 445 int32_t classSize = size; 446 data_offset += numOfBytes; 447 448 while(size >= 11 ) { 449 uint8_t descriptorTag; 450 if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) { 451 return ERROR_IO; 452 } 453 data_offset ++; 454 455 if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) { 456 return ERROR_MALFORMED; 457 } 458 459 uint8_t buffer[8]; 460 //ObjectDescriptorID and ObjectDescriptor url flag 461 if (mDataSource->readAt(data_offset, buffer, 2) < 2) { 462 return ERROR_IO; 463 } 464 data_offset += 2; 465 466 if ((buffer[1] >> 5) & 0x0001) { //url flag is set 467 return ERROR_MALFORMED; 468 } 469 470 if (mDataSource->readAt(data_offset, buffer, 8) < 8) { 471 return ERROR_IO; 472 } 473 data_offset += 8; 474 475 if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1]) 476 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) { 477 return ERROR_MALFORMED; 478 } 479 480 SINF *sinf = new SINF; 481 sinf->trackID = U16_AT(&buffer[3]); 482 sinf->IPMPDescriptorID = buffer[7]; 483 sinf->next = mFirstSINF; 484 mFirstSINF = sinf; 485 486 size -= (8 + 2 + 1); 487 } 488 489 if (size != 0) { 490 return ERROR_MALFORMED; 491 } 492 493 if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) { 494 return ERROR_IO; 495 } 496 data_offset ++; 497 498 if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) { 499 return ERROR_MALFORMED; 500 } 501 502 size = readSize(data_offset, mDataSource, &numOfBytes); 503 if (size < 0) { 504 return ERROR_IO; 505 } 506 classSize = size; 507 data_offset += numOfBytes; 508 509 while (size > 0) { 510 uint8_t tag; 511 int32_t dataLen; 512 if (mDataSource->readAt(data_offset, &tag, 1) < 1) { 513 return ERROR_IO; 514 } 515 data_offset ++; 516 517 if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) { 518 uint8_t id; 519 dataLen = readSize(data_offset, mDataSource, &numOfBytes); 520 if (dataLen < 0) { 521 return ERROR_IO; 522 } else if (dataLen < 4) { 523 return ERROR_MALFORMED; 524 } 525 data_offset += numOfBytes; 526 527 if (mDataSource->readAt(data_offset, &id, 1) < 1) { 528 return ERROR_IO; 529 } 530 data_offset ++; 531 532 SINF *sinf = mFirstSINF; 533 while (sinf && (sinf->IPMPDescriptorID != id)) { 534 sinf = sinf->next; 535 } 536 if (sinf == NULL) { 537 return ERROR_MALFORMED; 538 } 539 sinf->len = dataLen - 3; 540 sinf->IPMPData = new char[sinf->len]; 541 542 if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { 543 return ERROR_IO; 544 } 545 data_offset += sinf->len; 546 547 size -= (dataLen + numOfBytes + 1); 548 } 549 } 550 551 if (size != 0) { 552 return ERROR_MALFORMED; 553 } 554 555 return UNKNOWN_ERROR; // Return a dummy error. 556} 557 558static void MakeFourCCString(uint32_t x, char *s) { 559 s[0] = x >> 24; 560 s[1] = (x >> 16) & 0xff; 561 s[2] = (x >> 8) & 0xff; 562 s[3] = x & 0xff; 563 s[4] = '\0'; 564} 565 566struct PathAdder { 567 PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 568 : mPath(path) { 569 mPath->push(chunkType); 570 } 571 572 ~PathAdder() { 573 mPath->pop(); 574 } 575 576private: 577 Vector<uint32_t> *mPath; 578 579 PathAdder(const PathAdder &); 580 PathAdder &operator=(const PathAdder &); 581}; 582 583static bool underMetaDataPath(const Vector<uint32_t> &path) { 584 return path.size() >= 5 585 && path[0] == FOURCC('m', 'o', 'o', 'v') 586 && path[1] == FOURCC('u', 'd', 't', 'a') 587 && path[2] == FOURCC('m', 'e', 't', 'a') 588 && path[3] == FOURCC('i', 'l', 's', 't'); 589} 590 591// Given a time in seconds since Jan 1 1904, produce a human-readable string. 592static void convertTimeToDate(int64_t time_1904, String8 *s) { 593 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 594 595 char tmp[32]; 596 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 597 598 s->setTo(tmp); 599} 600 601status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { 602 uint32_t hdr[2]; 603 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 604 return ERROR_IO; 605 } 606 uint64_t chunk_size = ntohl(hdr[0]); 607 uint32_t chunk_type = ntohl(hdr[1]); 608 off64_t data_offset = *offset + 8; 609 610 if (chunk_size == 1) { 611 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 612 return ERROR_IO; 613 } 614 chunk_size = ntoh64(chunk_size); 615 data_offset += 8; 616 617 if (chunk_size < 16) { 618 // The smallest valid chunk is 16 bytes long in this case. 619 return ERROR_MALFORMED; 620 } 621 } else if (chunk_size < 8) { 622 // The smallest valid chunk is 8 bytes long. 623 return ERROR_MALFORMED; 624 } 625 626 char chunk[5]; 627 MakeFourCCString(chunk_type, chunk); 628 629#if 0 630 static const char kWhitespace[] = " "; 631 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 632 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 633 634 char buffer[256]; 635 size_t n = chunk_size; 636 if (n > sizeof(buffer)) { 637 n = sizeof(buffer); 638 } 639 if (mDataSource->readAt(*offset, buffer, n) 640 < (ssize_t)n) { 641 return ERROR_IO; 642 } 643 644 hexdump(buffer, n); 645#endif 646 647 PathAdder autoAdder(&mPath, chunk_type); 648 649 off64_t chunk_data_size = *offset + chunk_size - data_offset; 650 651 if (chunk_type != FOURCC('c', 'p', 'r', 't') 652 && chunk_type != FOURCC('c', 'o', 'v', 'r') 653 && mPath.size() == 5 && underMetaDataPath(mPath)) { 654 off64_t stop_offset = *offset + chunk_size; 655 *offset = data_offset; 656 while (*offset < stop_offset) { 657 status_t err = parseChunk(offset, depth + 1); 658 if (err != OK) { 659 return err; 660 } 661 } 662 663 if (*offset != stop_offset) { 664 return ERROR_MALFORMED; 665 } 666 667 return OK; 668 } 669 670 switch(chunk_type) { 671 case FOURCC('m', 'o', 'o', 'v'): 672 case FOURCC('t', 'r', 'a', 'k'): 673 case FOURCC('m', 'd', 'i', 'a'): 674 case FOURCC('m', 'i', 'n', 'f'): 675 case FOURCC('d', 'i', 'n', 'f'): 676 case FOURCC('s', 't', 'b', 'l'): 677 case FOURCC('m', 'v', 'e', 'x'): 678 case FOURCC('m', 'o', 'o', 'f'): 679 case FOURCC('t', 'r', 'a', 'f'): 680 case FOURCC('m', 'f', 'r', 'a'): 681 case FOURCC('u', 'd', 't', 'a'): 682 case FOURCC('i', 'l', 's', 't'): 683 { 684 if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 685 ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 686 687 if (mDataSource->flags() 688 & (DataSource::kWantsPrefetching 689 | DataSource::kIsCachingDataSource)) { 690 sp<MPEG4DataSource> cachedSource = 691 new MPEG4DataSource(mDataSource); 692 693 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 694 mDataSource = cachedSource; 695 } 696 } 697 698 mLastTrack->sampleTable = new SampleTable(mDataSource); 699 } 700 701 bool isTrack = false; 702 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 703 isTrack = true; 704 705 Track *track = new Track; 706 track->next = NULL; 707 if (mLastTrack) { 708 mLastTrack->next = track; 709 } else { 710 mFirstTrack = track; 711 } 712 mLastTrack = track; 713 714 track->meta = new MetaData; 715 track->includes_expensive_metadata = false; 716 track->skipTrack = false; 717 track->timescale = 0; 718 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 719 } 720 721 off64_t stop_offset = *offset + chunk_size; 722 *offset = data_offset; 723 while (*offset < stop_offset) { 724 status_t err = parseChunk(offset, depth + 1); 725 if (err != OK) { 726 return err; 727 } 728 } 729 730 if (*offset != stop_offset) { 731 return ERROR_MALFORMED; 732 } 733 734 if (isTrack) { 735 if (mLastTrack->skipTrack) { 736 Track *cur = mFirstTrack; 737 738 if (cur == mLastTrack) { 739 delete cur; 740 mFirstTrack = mLastTrack = NULL; 741 } else { 742 while (cur && cur->next != mLastTrack) { 743 cur = cur->next; 744 } 745 cur->next = NULL; 746 delete mLastTrack; 747 mLastTrack = cur; 748 } 749 750 return OK; 751 } 752 753 status_t err = verifyTrack(mLastTrack); 754 755 if (err != OK) { 756 return err; 757 } 758 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 759 mInitCheck = OK; 760 761 if (!mIsDrm) { 762 return UNKNOWN_ERROR; // Return a dummy error. 763 } else { 764 return OK; 765 } 766 } 767 break; 768 } 769 770 case FOURCC('t', 'k', 'h', 'd'): 771 { 772 status_t err; 773 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { 774 return err; 775 } 776 777 *offset += chunk_size; 778 break; 779 } 780 781 case FOURCC('m', 'd', 'h', 'd'): 782 { 783 if (chunk_data_size < 4) { 784 return ERROR_MALFORMED; 785 } 786 787 uint8_t version; 788 if (mDataSource->readAt( 789 data_offset, &version, sizeof(version)) 790 < (ssize_t)sizeof(version)) { 791 return ERROR_IO; 792 } 793 794 off64_t timescale_offset; 795 796 if (version == 1) { 797 timescale_offset = data_offset + 4 + 16; 798 } else if (version == 0) { 799 timescale_offset = data_offset + 4 + 8; 800 } else { 801 return ERROR_IO; 802 } 803 804 uint32_t timescale; 805 if (mDataSource->readAt( 806 timescale_offset, ×cale, sizeof(timescale)) 807 < (ssize_t)sizeof(timescale)) { 808 return ERROR_IO; 809 } 810 811 mLastTrack->timescale = ntohl(timescale); 812 813 int64_t duration; 814 if (version == 1) { 815 if (mDataSource->readAt( 816 timescale_offset + 4, &duration, sizeof(duration)) 817 < (ssize_t)sizeof(duration)) { 818 return ERROR_IO; 819 } 820 duration = ntoh64(duration); 821 } else { 822 int32_t duration32; 823 if (mDataSource->readAt( 824 timescale_offset + 4, &duration32, sizeof(duration32)) 825 < (ssize_t)sizeof(duration32)) { 826 return ERROR_IO; 827 } 828 duration = ntohl(duration32); 829 } 830 mLastTrack->meta->setInt64( 831 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 832 833 uint8_t lang[2]; 834 off64_t lang_offset; 835 if (version == 1) { 836 lang_offset = timescale_offset + 4 + 8; 837 } else if (version == 0) { 838 lang_offset = timescale_offset + 4 + 4; 839 } else { 840 return ERROR_IO; 841 } 842 843 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang)) 844 < (ssize_t)sizeof(lang)) { 845 return ERROR_IO; 846 } 847 848 // To get the ISO-639-2/T three character language code 849 // 1 bit pad followed by 3 5-bits characters. Each character 850 // is packed as the difference between its ASCII value and 0x60. 851 char lang_code[4]; 852 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60; 853 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60; 854 lang_code[2] = (lang[1] & 0x1f) + 0x60; 855 lang_code[3] = '\0'; 856 857 mLastTrack->meta->setCString( 858 kKeyMediaLanguage, lang_code); 859 860 *offset += chunk_size; 861 break; 862 } 863 864 case FOURCC('s', 't', 's', 'd'): 865 { 866 if (chunk_data_size < 8) { 867 return ERROR_MALFORMED; 868 } 869 870 uint8_t buffer[8]; 871 if (chunk_data_size < (off64_t)sizeof(buffer)) { 872 return ERROR_MALFORMED; 873 } 874 875 if (mDataSource->readAt( 876 data_offset, buffer, 8) < 8) { 877 return ERROR_IO; 878 } 879 880 if (U32_AT(buffer) != 0) { 881 // Should be version 0, flags 0. 882 return ERROR_MALFORMED; 883 } 884 885 uint32_t entry_count = U32_AT(&buffer[4]); 886 887 if (entry_count > 1) { 888 // For 3GPP timed text, there could be multiple tx3g boxes contain 889 // multiple text display formats. These formats will be used to 890 // display the timed text. 891 const char *mime; 892 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 893 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) { 894 // For now we only support a single type of media per track. 895 mLastTrack->skipTrack = true; 896 *offset += chunk_size; 897 break; 898 } 899 } 900 901 off64_t stop_offset = *offset + chunk_size; 902 *offset = data_offset + 8; 903 for (uint32_t i = 0; i < entry_count; ++i) { 904 status_t err = parseChunk(offset, depth + 1); 905 if (err != OK) { 906 return err; 907 } 908 } 909 910 if (*offset != stop_offset) { 911 return ERROR_MALFORMED; 912 } 913 break; 914 } 915 916 case FOURCC('m', 'p', '4', 'a'): 917 case FOURCC('s', 'a', 'm', 'r'): 918 case FOURCC('s', 'a', 'w', 'b'): 919 { 920 uint8_t buffer[8 + 20]; 921 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 922 // Basic AudioSampleEntry size. 923 return ERROR_MALFORMED; 924 } 925 926 if (mDataSource->readAt( 927 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 928 return ERROR_IO; 929 } 930 931 uint16_t data_ref_index = U16_AT(&buffer[6]); 932 uint16_t num_channels = U16_AT(&buffer[16]); 933 934 uint16_t sample_size = U16_AT(&buffer[18]); 935 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 936 937 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 938 FourCC2MIME(chunk_type))) { 939 // AMR NB audio is always mono, 8kHz 940 num_channels = 1; 941 sample_rate = 8000; 942 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 943 FourCC2MIME(chunk_type))) { 944 // AMR WB audio is always mono, 16kHz 945 num_channels = 1; 946 sample_rate = 16000; 947 } 948 949#if 0 950 printf("*** coding='%s' %d channels, size %d, rate %d\n", 951 chunk, num_channels, sample_size, sample_rate); 952#endif 953 954 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 955 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 956 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 957 958 off64_t stop_offset = *offset + chunk_size; 959 *offset = data_offset + sizeof(buffer); 960 while (*offset < stop_offset) { 961 status_t err = parseChunk(offset, depth + 1); 962 if (err != OK) { 963 return err; 964 } 965 } 966 967 if (*offset != stop_offset) { 968 return ERROR_MALFORMED; 969 } 970 break; 971 } 972 973 case FOURCC('m', 'p', '4', 'v'): 974 case FOURCC('s', '2', '6', '3'): 975 case FOURCC('H', '2', '6', '3'): 976 case FOURCC('h', '2', '6', '3'): 977 case FOURCC('a', 'v', 'c', '1'): 978 { 979 mHasVideo = true; 980 981 uint8_t buffer[78]; 982 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 983 // Basic VideoSampleEntry size. 984 return ERROR_MALFORMED; 985 } 986 987 if (mDataSource->readAt( 988 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 989 return ERROR_IO; 990 } 991 992 uint16_t data_ref_index = U16_AT(&buffer[6]); 993 uint16_t width = U16_AT(&buffer[6 + 18]); 994 uint16_t height = U16_AT(&buffer[6 + 20]); 995 996 // The video sample is not stand-compliant if it has invalid dimension. 997 // Use some default width and height value, and 998 // let the decoder figure out the actual width and height (and thus 999 // be prepared for INFO_FOMRAT_CHANGED event). 1000 if (width == 0) width = 352; 1001 if (height == 0) height = 288; 1002 1003 // printf("*** coding='%s' width=%d height=%d\n", 1004 // chunk, width, height); 1005 1006 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 1007 mLastTrack->meta->setInt32(kKeyWidth, width); 1008 mLastTrack->meta->setInt32(kKeyHeight, height); 1009 1010 off64_t stop_offset = *offset + chunk_size; 1011 *offset = data_offset + sizeof(buffer); 1012 while (*offset < stop_offset) { 1013 status_t err = parseChunk(offset, depth + 1); 1014 if (err != OK) { 1015 return err; 1016 } 1017 } 1018 1019 if (*offset != stop_offset) { 1020 return ERROR_MALFORMED; 1021 } 1022 break; 1023 } 1024 1025 case FOURCC('s', 't', 'c', 'o'): 1026 case FOURCC('c', 'o', '6', '4'): 1027 { 1028 status_t err = 1029 mLastTrack->sampleTable->setChunkOffsetParams( 1030 chunk_type, data_offset, chunk_data_size); 1031 1032 if (err != OK) { 1033 return err; 1034 } 1035 1036 *offset += chunk_size; 1037 break; 1038 } 1039 1040 case FOURCC('s', 't', 's', 'c'): 1041 { 1042 status_t err = 1043 mLastTrack->sampleTable->setSampleToChunkParams( 1044 data_offset, chunk_data_size); 1045 1046 if (err != OK) { 1047 return err; 1048 } 1049 1050 *offset += chunk_size; 1051 break; 1052 } 1053 1054 case FOURCC('s', 't', 's', 'z'): 1055 case FOURCC('s', 't', 'z', '2'): 1056 { 1057 status_t err = 1058 mLastTrack->sampleTable->setSampleSizeParams( 1059 chunk_type, data_offset, chunk_data_size); 1060 1061 if (err != OK) { 1062 return err; 1063 } 1064 1065 size_t max_size; 1066 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size); 1067 1068 if (err != OK) { 1069 return err; 1070 } 1071 1072 // Assume that a given buffer only contains at most 10 fragments, 1073 // each fragment originally prefixed with a 2 byte length will 1074 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 1075 // and thus will grow by 2 bytes per fragment. 1076 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 1077 *offset += chunk_size; 1078 1079 // Calculate average frame rate. 1080 const char *mime; 1081 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); 1082 if (!strncasecmp("video/", mime, 6)) { 1083 size_t nSamples = mLastTrack->sampleTable->countSamples(); 1084 int64_t durationUs; 1085 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) { 1086 if (durationUs > 0) { 1087 int32_t frameRate = (nSamples * 1000000LL + 1088 (durationUs >> 1)) / durationUs; 1089 mLastTrack->meta->setInt32(kKeyFrameRate, frameRate); 1090 } 1091 } 1092 } 1093 1094 break; 1095 } 1096 1097 case FOURCC('s', 't', 't', 's'): 1098 { 1099 status_t err = 1100 mLastTrack->sampleTable->setTimeToSampleParams( 1101 data_offset, chunk_data_size); 1102 1103 if (err != OK) { 1104 return err; 1105 } 1106 1107 *offset += chunk_size; 1108 break; 1109 } 1110 1111 case FOURCC('c', 't', 't', 's'): 1112 { 1113 status_t err = 1114 mLastTrack->sampleTable->setCompositionTimeToSampleParams( 1115 data_offset, chunk_data_size); 1116 1117 if (err != OK) { 1118 return err; 1119 } 1120 1121 *offset += chunk_size; 1122 break; 1123 } 1124 1125 case FOURCC('s', 't', 's', 's'): 1126 { 1127 status_t err = 1128 mLastTrack->sampleTable->setSyncSampleParams( 1129 data_offset, chunk_data_size); 1130 1131 if (err != OK) { 1132 return err; 1133 } 1134 1135 *offset += chunk_size; 1136 break; 1137 } 1138 1139 // @xyz 1140 case FOURCC('\xA9', 'x', 'y', 'z'): 1141 { 1142 // Best case the total data length inside "@xyz" box 1143 // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/", 1144 // where "\x00\x04" is the text string length with value = 4, 1145 // "\0x15\xc7" is the language code = en, and "0+0" is a 1146 // location (string) value with longitude = 0 and latitude = 0. 1147 if (chunk_data_size < 8) { 1148 return ERROR_MALFORMED; 1149 } 1150 1151 // Worst case the location string length would be 18, 1152 // for instance +90.0000-180.0000, without the trailing "/" and 1153 // the string length + language code. 1154 char buffer[18]; 1155 1156 // Substracting 5 from the data size is because the text string length + 1157 // language code takes 4 bytes, and the trailing slash "/" takes 1 byte. 1158 off64_t location_length = chunk_data_size - 5; 1159 if (location_length >= (off64_t) sizeof(buffer)) { 1160 return ERROR_MALFORMED; 1161 } 1162 1163 if (mDataSource->readAt( 1164 data_offset + 4, buffer, location_length) < location_length) { 1165 return ERROR_IO; 1166 } 1167 1168 buffer[location_length] = '\0'; 1169 mFileMetaData->setCString(kKeyLocation, buffer); 1170 *offset += chunk_size; 1171 break; 1172 } 1173 1174 case FOURCC('e', 's', 'd', 's'): 1175 { 1176 if (chunk_data_size < 4) { 1177 return ERROR_MALFORMED; 1178 } 1179 1180 uint8_t buffer[256]; 1181 if (chunk_data_size > (off64_t)sizeof(buffer)) { 1182 return ERROR_BUFFER_TOO_SMALL; 1183 } 1184 1185 if (mDataSource->readAt( 1186 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1187 return ERROR_IO; 1188 } 1189 1190 if (U32_AT(buffer) != 0) { 1191 // Should be version 0, flags 0. 1192 return ERROR_MALFORMED; 1193 } 1194 1195 mLastTrack->meta->setData( 1196 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 1197 1198 if (mPath.size() >= 2 1199 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 1200 // Information from the ESDS must be relied on for proper 1201 // setup of sample rate and channel count for MPEG4 Audio. 1202 // The generic header appears to only contain generic 1203 // information... 1204 1205 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 1206 &buffer[4], chunk_data_size - 4); 1207 1208 if (err != OK) { 1209 return err; 1210 } 1211 } 1212 1213 *offset += chunk_size; 1214 break; 1215 } 1216 1217 case FOURCC('a', 'v', 'c', 'C'): 1218 { 1219 char buffer[256]; 1220 if (chunk_data_size > (off64_t)sizeof(buffer)) { 1221 return ERROR_BUFFER_TOO_SMALL; 1222 } 1223 1224 if (mDataSource->readAt( 1225 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1226 return ERROR_IO; 1227 } 1228 1229 mLastTrack->meta->setData( 1230 kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 1231 1232 *offset += chunk_size; 1233 break; 1234 } 1235 1236 case FOURCC('d', '2', '6', '3'): 1237 { 1238 /* 1239 * d263 contains a fixed 7 bytes part: 1240 * vendor - 4 bytes 1241 * version - 1 byte 1242 * level - 1 byte 1243 * profile - 1 byte 1244 * optionally, "d263" box itself may contain a 16-byte 1245 * bit rate box (bitr) 1246 * average bit rate - 4 bytes 1247 * max bit rate - 4 bytes 1248 */ 1249 char buffer[23]; 1250 if (chunk_data_size != 7 && 1251 chunk_data_size != 23) { 1252 ALOGE("Incorrect D263 box size %lld", chunk_data_size); 1253 return ERROR_MALFORMED; 1254 } 1255 1256 if (mDataSource->readAt( 1257 data_offset, buffer, chunk_data_size) < chunk_data_size) { 1258 return ERROR_IO; 1259 } 1260 1261 mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size); 1262 1263 *offset += chunk_size; 1264 break; 1265 } 1266 1267 case FOURCC('m', 'e', 't', 'a'): 1268 { 1269 uint8_t buffer[4]; 1270 if (chunk_data_size < (off64_t)sizeof(buffer)) { 1271 return ERROR_MALFORMED; 1272 } 1273 1274 if (mDataSource->readAt( 1275 data_offset, buffer, 4) < 4) { 1276 return ERROR_IO; 1277 } 1278 1279 if (U32_AT(buffer) != 0) { 1280 // Should be version 0, flags 0. 1281 1282 // If it's not, let's assume this is one of those 1283 // apparently malformed chunks that don't have flags 1284 // and completely different semantics than what's 1285 // in the MPEG4 specs and skip it. 1286 *offset += chunk_size; 1287 return OK; 1288 } 1289 1290 off64_t stop_offset = *offset + chunk_size; 1291 *offset = data_offset + sizeof(buffer); 1292 while (*offset < stop_offset) { 1293 status_t err = parseChunk(offset, depth + 1); 1294 if (err != OK) { 1295 return err; 1296 } 1297 } 1298 1299 if (*offset != stop_offset) { 1300 return ERROR_MALFORMED; 1301 } 1302 break; 1303 } 1304 1305 case FOURCC('d', 'a', 't', 'a'): 1306 { 1307 if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1308 status_t err = parseMetaData(data_offset, chunk_data_size); 1309 1310 if (err != OK) { 1311 return err; 1312 } 1313 } 1314 1315 *offset += chunk_size; 1316 break; 1317 } 1318 1319 case FOURCC('m', 'v', 'h', 'd'): 1320 { 1321 if (chunk_data_size < 12) { 1322 return ERROR_MALFORMED; 1323 } 1324 1325 uint8_t header[12]; 1326 if (mDataSource->readAt( 1327 data_offset, header, sizeof(header)) 1328 < (ssize_t)sizeof(header)) { 1329 return ERROR_IO; 1330 } 1331 1332 int64_t creationTime; 1333 if (header[0] == 1) { 1334 creationTime = U64_AT(&header[4]); 1335 } else if (header[0] != 0) { 1336 return ERROR_MALFORMED; 1337 } else { 1338 creationTime = U32_AT(&header[4]); 1339 } 1340 1341 String8 s; 1342 convertTimeToDate(creationTime, &s); 1343 1344 mFileMetaData->setCString(kKeyDate, s.string()); 1345 1346 *offset += chunk_size; 1347 break; 1348 } 1349 1350 case FOURCC('m', 'd', 'a', 't'): 1351 { 1352 if (!mIsDrm) { 1353 *offset += chunk_size; 1354 break; 1355 } 1356 1357 if (chunk_size < 8) { 1358 return ERROR_MALFORMED; 1359 } 1360 1361 return parseDrmSINF(offset, data_offset); 1362 } 1363 1364 case FOURCC('h', 'd', 'l', 'r'): 1365 { 1366 uint32_t buffer; 1367 if (mDataSource->readAt( 1368 data_offset + 8, &buffer, 4) < 4) { 1369 return ERROR_IO; 1370 } 1371 1372 uint32_t type = ntohl(buffer); 1373 // For the 3GPP file format, the handler-type within the 'hdlr' box 1374 // shall be 'text'. We also want to support 'sbtl' handler type 1375 // for a practical reason as various MPEG4 containers use it. 1376 if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) { 1377 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP); 1378 } 1379 1380 *offset += chunk_size; 1381 break; 1382 } 1383 1384 case FOURCC('t', 'x', '3', 'g'): 1385 { 1386 uint32_t type; 1387 const void *data; 1388 size_t size = 0; 1389 if (!mLastTrack->meta->findData( 1390 kKeyTextFormatData, &type, &data, &size)) { 1391 size = 0; 1392 } 1393 1394 uint8_t *buffer = new uint8_t[size + chunk_size]; 1395 1396 if (size > 0) { 1397 memcpy(buffer, data, size); 1398 } 1399 1400 if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size)) 1401 < chunk_size) { 1402 delete[] buffer; 1403 buffer = NULL; 1404 1405 return ERROR_IO; 1406 } 1407 1408 mLastTrack->meta->setData( 1409 kKeyTextFormatData, 0, buffer, size + chunk_size); 1410 1411 delete[] buffer; 1412 1413 *offset += chunk_size; 1414 break; 1415 } 1416 1417 case FOURCC('c', 'o', 'v', 'r'): 1418 { 1419 if (mFileMetaData != NULL) { 1420 ALOGV("chunk_data_size = %lld and data_offset = %lld", 1421 chunk_data_size, data_offset); 1422 uint8_t *buffer = new uint8_t[chunk_data_size + 1]; 1423 if (mDataSource->readAt( 1424 data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) { 1425 delete[] buffer; 1426 buffer = NULL; 1427 1428 return ERROR_IO; 1429 } 1430 const int kSkipBytesOfDataBox = 16; 1431 mFileMetaData->setData( 1432 kKeyAlbumArt, MetaData::TYPE_NONE, 1433 buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox); 1434 } 1435 1436 *offset += chunk_size; 1437 break; 1438 } 1439 1440 default: 1441 { 1442 *offset += chunk_size; 1443 break; 1444 } 1445 } 1446 1447 return OK; 1448} 1449 1450status_t MPEG4Extractor::parseTrackHeader( 1451 off64_t data_offset, off64_t data_size) { 1452 if (data_size < 4) { 1453 return ERROR_MALFORMED; 1454 } 1455 1456 uint8_t version; 1457 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 1458 return ERROR_IO; 1459 } 1460 1461 size_t dynSize = (version == 1) ? 36 : 24; 1462 1463 uint8_t buffer[36 + 60]; 1464 1465 if (data_size != (off64_t)dynSize + 60) { 1466 return ERROR_MALFORMED; 1467 } 1468 1469 if (mDataSource->readAt( 1470 data_offset, buffer, data_size) < (ssize_t)data_size) { 1471 return ERROR_IO; 1472 } 1473 1474 uint64_t ctime, mtime, duration; 1475 int32_t id; 1476 1477 if (version == 1) { 1478 ctime = U64_AT(&buffer[4]); 1479 mtime = U64_AT(&buffer[12]); 1480 id = U32_AT(&buffer[20]); 1481 duration = U64_AT(&buffer[28]); 1482 } else { 1483 CHECK_EQ((unsigned)version, 0u); 1484 1485 ctime = U32_AT(&buffer[4]); 1486 mtime = U32_AT(&buffer[8]); 1487 id = U32_AT(&buffer[12]); 1488 duration = U32_AT(&buffer[20]); 1489 } 1490 1491 mLastTrack->meta->setInt32(kKeyTrackID, id); 1492 1493 size_t matrixOffset = dynSize + 16; 1494 int32_t a00 = U32_AT(&buffer[matrixOffset]); 1495 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); 1496 int32_t dx = U32_AT(&buffer[matrixOffset + 8]); 1497 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); 1498 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); 1499 int32_t dy = U32_AT(&buffer[matrixOffset + 20]); 1500 1501#if 0 1502 ALOGI("x' = %.2f * x + %.2f * y + %.2f", 1503 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); 1504 ALOGI("y' = %.2f * x + %.2f * y + %.2f", 1505 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); 1506#endif 1507 1508 uint32_t rotationDegrees; 1509 1510 static const int32_t kFixedOne = 0x10000; 1511 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { 1512 // Identity, no rotation 1513 rotationDegrees = 0; 1514 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { 1515 rotationDegrees = 90; 1516 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { 1517 rotationDegrees = 270; 1518 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { 1519 rotationDegrees = 180; 1520 } else { 1521 ALOGW("We only support 0,90,180,270 degree rotation matrices"); 1522 rotationDegrees = 0; 1523 } 1524 1525 if (rotationDegrees != 0) { 1526 mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); 1527 } 1528 1529 // Handle presentation display size, which could be different 1530 // from the image size indicated by kKeyWidth and kKeyHeight. 1531 uint32_t width = U32_AT(&buffer[dynSize + 52]); 1532 uint32_t height = U32_AT(&buffer[dynSize + 56]); 1533 mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16); 1534 mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16); 1535 1536 return OK; 1537} 1538 1539status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) { 1540 if (size < 4) { 1541 return ERROR_MALFORMED; 1542 } 1543 1544 uint8_t *buffer = new uint8_t[size + 1]; 1545 if (mDataSource->readAt( 1546 offset, buffer, size) != (ssize_t)size) { 1547 delete[] buffer; 1548 buffer = NULL; 1549 1550 return ERROR_IO; 1551 } 1552 1553 uint32_t flags = U32_AT(buffer); 1554 1555 uint32_t metadataKey = 0; 1556 switch (mPath[4]) { 1557 case FOURCC(0xa9, 'a', 'l', 'b'): 1558 { 1559 metadataKey = kKeyAlbum; 1560 break; 1561 } 1562 case FOURCC(0xa9, 'A', 'R', 'T'): 1563 { 1564 metadataKey = kKeyArtist; 1565 break; 1566 } 1567 case FOURCC('a', 'A', 'R', 'T'): 1568 { 1569 metadataKey = kKeyAlbumArtist; 1570 break; 1571 } 1572 case FOURCC(0xa9, 'd', 'a', 'y'): 1573 { 1574 metadataKey = kKeyYear; 1575 break; 1576 } 1577 case FOURCC(0xa9, 'n', 'a', 'm'): 1578 { 1579 metadataKey = kKeyTitle; 1580 break; 1581 } 1582 case FOURCC(0xa9, 'w', 'r', 't'): 1583 { 1584 metadataKey = kKeyWriter; 1585 break; 1586 } 1587 case FOURCC('c', 'o', 'v', 'r'): 1588 { 1589 metadataKey = kKeyAlbumArt; 1590 break; 1591 } 1592 case FOURCC('g', 'n', 'r', 'e'): 1593 { 1594 metadataKey = kKeyGenre; 1595 break; 1596 } 1597 case FOURCC(0xa9, 'g', 'e', 'n'): 1598 { 1599 metadataKey = kKeyGenre; 1600 break; 1601 } 1602 case FOURCC('c', 'p', 'i', 'l'): 1603 { 1604 if (size == 9 && flags == 21) { 1605 char tmp[16]; 1606 sprintf(tmp, "%d", 1607 (int)buffer[size - 1]); 1608 1609 mFileMetaData->setCString(kKeyCompilation, tmp); 1610 } 1611 break; 1612 } 1613 case FOURCC('t', 'r', 'k', 'n'): 1614 { 1615 if (size == 16 && flags == 0) { 1616 char tmp[16]; 1617 sprintf(tmp, "%d/%d", 1618 (int)buffer[size - 5], (int)buffer[size - 3]); 1619 1620 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1621 } 1622 break; 1623 } 1624 case FOURCC('d', 'i', 's', 'k'): 1625 { 1626 if (size == 14 && flags == 0) { 1627 char tmp[16]; 1628 sprintf(tmp, "%d/%d", 1629 (int)buffer[size - 3], (int)buffer[size - 1]); 1630 1631 mFileMetaData->setCString(kKeyDiscNumber, tmp); 1632 } 1633 break; 1634 } 1635 1636 default: 1637 break; 1638 } 1639 1640 if (size >= 8 && metadataKey) { 1641 if (metadataKey == kKeyAlbumArt) { 1642 mFileMetaData->setData( 1643 kKeyAlbumArt, MetaData::TYPE_NONE, 1644 buffer + 8, size - 8); 1645 } else if (metadataKey == kKeyGenre) { 1646 if (flags == 0) { 1647 // uint8_t genre code, iTunes genre codes are 1648 // the standard id3 codes, except they start 1649 // at 1 instead of 0 (e.g. Pop is 14, not 13) 1650 // We use standard id3 numbering, so subtract 1. 1651 int genrecode = (int)buffer[size - 1]; 1652 genrecode--; 1653 if (genrecode < 0) { 1654 genrecode = 255; // reserved for 'unknown genre' 1655 } 1656 char genre[10]; 1657 sprintf(genre, "%d", genrecode); 1658 1659 mFileMetaData->setCString(metadataKey, genre); 1660 } else if (flags == 1) { 1661 // custom genre string 1662 buffer[size] = '\0'; 1663 1664 mFileMetaData->setCString( 1665 metadataKey, (const char *)buffer + 8); 1666 } 1667 } else { 1668 buffer[size] = '\0'; 1669 1670 mFileMetaData->setCString( 1671 metadataKey, (const char *)buffer + 8); 1672 } 1673 } 1674 1675 delete[] buffer; 1676 buffer = NULL; 1677 1678 return OK; 1679} 1680 1681sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1682 status_t err; 1683 if ((err = readMetaData()) != OK) { 1684 return NULL; 1685 } 1686 1687 Track *track = mFirstTrack; 1688 while (index > 0) { 1689 if (track == NULL) { 1690 return NULL; 1691 } 1692 1693 track = track->next; 1694 --index; 1695 } 1696 1697 if (track == NULL) { 1698 return NULL; 1699 } 1700 1701 return new MPEG4Source( 1702 track->meta, mDataSource, track->timescale, track->sampleTable); 1703} 1704 1705// static 1706status_t MPEG4Extractor::verifyTrack(Track *track) { 1707 const char *mime; 1708 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1709 1710 uint32_t type; 1711 const void *data; 1712 size_t size; 1713 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1714 if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1715 || type != kTypeAVCC) { 1716 return ERROR_MALFORMED; 1717 } 1718 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1719 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1720 if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1721 || type != kTypeESDS) { 1722 return ERROR_MALFORMED; 1723 } 1724 } 1725 1726 if (!track->sampleTable->isValid()) { 1727 // Make sure we have all the metadata we need. 1728 return ERROR_MALFORMED; 1729 } 1730 1731 return OK; 1732} 1733 1734status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1735 const void *esds_data, size_t esds_size) { 1736 ESDS esds(esds_data, esds_size); 1737 1738 uint8_t objectTypeIndication; 1739 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1740 return ERROR_MALFORMED; 1741 } 1742 1743 if (objectTypeIndication == 0xe1) { 1744 // This isn't MPEG4 audio at all, it's QCELP 14k... 1745 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 1746 return OK; 1747 } 1748 1749 if (objectTypeIndication == 0x6b) { 1750 // The media subtype is MP3 audio 1751 // Our software MP3 audio decoder may not be able to handle 1752 // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED 1753 ALOGE("MP3 track in MP4/3GPP file is not supported"); 1754 return ERROR_UNSUPPORTED; 1755 } 1756 1757 const uint8_t *csd; 1758 size_t csd_size; 1759 if (esds.getCodecSpecificInfo( 1760 (const void **)&csd, &csd_size) != OK) { 1761 return ERROR_MALFORMED; 1762 } 1763 1764#if 0 1765 printf("ESD of size %d\n", csd_size); 1766 hexdump(csd, csd_size); 1767#endif 1768 1769 if (csd_size == 0) { 1770 // There's no further information, i.e. no codec specific data 1771 // Let's assume that the information provided in the mpeg4 headers 1772 // is accurate and hope for the best. 1773 1774 return OK; 1775 } 1776 1777 if (csd_size < 2) { 1778 return ERROR_MALFORMED; 1779 } 1780 1781 uint32_t objectType = csd[0] >> 3; 1782 1783 if (objectType == 31) { 1784 return ERROR_UNSUPPORTED; 1785 } 1786 1787 uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1788 int32_t sampleRate = 0; 1789 int32_t numChannels = 0; 1790 if (freqIndex == 15) { 1791 if (csd_size < 5) { 1792 return ERROR_MALFORMED; 1793 } 1794 1795 sampleRate = (csd[1] & 0x7f) << 17 1796 | csd[2] << 9 1797 | csd[3] << 1 1798 | (csd[4] >> 7); 1799 1800 numChannels = (csd[4] >> 3) & 15; 1801 } else { 1802 static uint32_t kSamplingRate[] = { 1803 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1804 16000, 12000, 11025, 8000, 7350 1805 }; 1806 1807 if (freqIndex == 13 || freqIndex == 14) { 1808 return ERROR_MALFORMED; 1809 } 1810 1811 sampleRate = kSamplingRate[freqIndex]; 1812 numChannels = (csd[1] >> 3) & 15; 1813 } 1814 1815 if (numChannels == 0) { 1816 return ERROR_UNSUPPORTED; 1817 } 1818 1819 int32_t prevSampleRate; 1820 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1821 1822 if (prevSampleRate != sampleRate) { 1823 ALOGV("mpeg4 audio sample rate different from previous setting. " 1824 "was: %d, now: %d", prevSampleRate, sampleRate); 1825 } 1826 1827 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1828 1829 int32_t prevChannelCount; 1830 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1831 1832 if (prevChannelCount != numChannels) { 1833 ALOGV("mpeg4 audio channel count different from previous setting. " 1834 "was: %d, now: %d", prevChannelCount, numChannels); 1835 } 1836 1837 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1838 1839 return OK; 1840} 1841 1842//////////////////////////////////////////////////////////////////////////////// 1843 1844MPEG4Source::MPEG4Source( 1845 const sp<MetaData> &format, 1846 const sp<DataSource> &dataSource, 1847 int32_t timeScale, 1848 const sp<SampleTable> &sampleTable) 1849 : mFormat(format), 1850 mDataSource(dataSource), 1851 mTimescale(timeScale), 1852 mSampleTable(sampleTable), 1853 mCurrentSampleIndex(0), 1854 mIsAVC(false), 1855 mNALLengthSize(0), 1856 mStarted(false), 1857 mGroup(NULL), 1858 mBuffer(NULL), 1859 mWantsNALFragments(false), 1860 mSrcBuffer(NULL) { 1861 const char *mime; 1862 bool success = mFormat->findCString(kKeyMIMEType, &mime); 1863 CHECK(success); 1864 1865 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1866 1867 if (mIsAVC) { 1868 uint32_t type; 1869 const void *data; 1870 size_t size; 1871 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1872 1873 const uint8_t *ptr = (const uint8_t *)data; 1874 1875 CHECK(size >= 7); 1876 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 1877 1878 // The number of bytes used to encode the length of a NAL unit. 1879 mNALLengthSize = 1 + (ptr[4] & 3); 1880 } 1881} 1882 1883MPEG4Source::~MPEG4Source() { 1884 if (mStarted) { 1885 stop(); 1886 } 1887} 1888 1889status_t MPEG4Source::start(MetaData *params) { 1890 Mutex::Autolock autoLock(mLock); 1891 1892 CHECK(!mStarted); 1893 1894 int32_t val; 1895 if (params && params->findInt32(kKeyWantsNALFragments, &val) 1896 && val != 0) { 1897 mWantsNALFragments = true; 1898 } else { 1899 mWantsNALFragments = false; 1900 } 1901 1902 mGroup = new MediaBufferGroup; 1903 1904 int32_t max_size; 1905 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1906 1907 mGroup->add_buffer(new MediaBuffer(max_size)); 1908 1909 mSrcBuffer = new uint8_t[max_size]; 1910 1911 mStarted = true; 1912 1913 return OK; 1914} 1915 1916status_t MPEG4Source::stop() { 1917 Mutex::Autolock autoLock(mLock); 1918 1919 CHECK(mStarted); 1920 1921 if (mBuffer != NULL) { 1922 mBuffer->release(); 1923 mBuffer = NULL; 1924 } 1925 1926 delete[] mSrcBuffer; 1927 mSrcBuffer = NULL; 1928 1929 delete mGroup; 1930 mGroup = NULL; 1931 1932 mStarted = false; 1933 mCurrentSampleIndex = 0; 1934 1935 return OK; 1936} 1937 1938sp<MetaData> MPEG4Source::getFormat() { 1939 Mutex::Autolock autoLock(mLock); 1940 1941 return mFormat; 1942} 1943 1944size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1945 switch (mNALLengthSize) { 1946 case 1: 1947 return *data; 1948 case 2: 1949 return U16_AT(data); 1950 case 3: 1951 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1952 case 4: 1953 return U32_AT(data); 1954 } 1955 1956 // This cannot happen, mNALLengthSize springs to life by adding 1 to 1957 // a 2-bit integer. 1958 CHECK(!"Should not be here."); 1959 1960 return 0; 1961} 1962 1963status_t MPEG4Source::read( 1964 MediaBuffer **out, const ReadOptions *options) { 1965 Mutex::Autolock autoLock(mLock); 1966 1967 CHECK(mStarted); 1968 1969 *out = NULL; 1970 1971 int64_t targetSampleTimeUs = -1; 1972 1973 int64_t seekTimeUs; 1974 ReadOptions::SeekMode mode; 1975 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 1976 uint32_t findFlags = 0; 1977 switch (mode) { 1978 case ReadOptions::SEEK_PREVIOUS_SYNC: 1979 findFlags = SampleTable::kFlagBefore; 1980 break; 1981 case ReadOptions::SEEK_NEXT_SYNC: 1982 findFlags = SampleTable::kFlagAfter; 1983 break; 1984 case ReadOptions::SEEK_CLOSEST_SYNC: 1985 case ReadOptions::SEEK_CLOSEST: 1986 findFlags = SampleTable::kFlagClosest; 1987 break; 1988 default: 1989 CHECK(!"Should not be here."); 1990 break; 1991 } 1992 1993 uint32_t sampleIndex; 1994 status_t err = mSampleTable->findSampleAtTime( 1995 seekTimeUs * mTimescale / 1000000, 1996 &sampleIndex, findFlags); 1997 1998 if (mode == ReadOptions::SEEK_CLOSEST) { 1999 // We found the closest sample already, now we want the sync 2000 // sample preceding it (or the sample itself of course), even 2001 // if the subsequent sync sample is closer. 2002 findFlags = SampleTable::kFlagBefore; 2003 } 2004 2005 uint32_t syncSampleIndex; 2006 if (err == OK) { 2007 err = mSampleTable->findSyncSampleNear( 2008 sampleIndex, &syncSampleIndex, findFlags); 2009 } 2010 2011 uint32_t sampleTime; 2012 if (err == OK) { 2013 err = mSampleTable->getMetaDataForSample( 2014 sampleIndex, NULL, NULL, &sampleTime); 2015 } 2016 2017 if (err != OK) { 2018 if (err == ERROR_OUT_OF_RANGE) { 2019 // An attempt to seek past the end of the stream would 2020 // normally cause this ERROR_OUT_OF_RANGE error. Propagating 2021 // this all the way to the MediaPlayer would cause abnormal 2022 // termination. Legacy behaviour appears to be to behave as if 2023 // we had seeked to the end of stream, ending normally. 2024 err = ERROR_END_OF_STREAM; 2025 } 2026 return err; 2027 } 2028 2029 if (mode == ReadOptions::SEEK_CLOSEST) { 2030 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale; 2031 } 2032 2033#if 0 2034 uint32_t syncSampleTime; 2035 CHECK_EQ(OK, mSampleTable->getMetaDataForSample( 2036 syncSampleIndex, NULL, NULL, &syncSampleTime)); 2037 2038 ALOGI("seek to time %lld us => sample at time %lld us, " 2039 "sync sample at time %lld us", 2040 seekTimeUs, 2041 sampleTime * 1000000ll / mTimescale, 2042 syncSampleTime * 1000000ll / mTimescale); 2043#endif 2044 2045 mCurrentSampleIndex = syncSampleIndex; 2046 if (mBuffer != NULL) { 2047 mBuffer->release(); 2048 mBuffer = NULL; 2049 } 2050 2051 // fall through 2052 } 2053 2054 off64_t offset; 2055 size_t size; 2056 uint32_t cts; 2057 bool isSyncSample; 2058 bool newBuffer = false; 2059 if (mBuffer == NULL) { 2060 newBuffer = true; 2061 2062 status_t err = 2063 mSampleTable->getMetaDataForSample( 2064 mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample); 2065 2066 if (err != OK) { 2067 return err; 2068 } 2069 2070 err = mGroup->acquire_buffer(&mBuffer); 2071 2072 if (err != OK) { 2073 CHECK(mBuffer == NULL); 2074 return err; 2075 } 2076 } 2077 2078 if (!mIsAVC || mWantsNALFragments) { 2079 if (newBuffer) { 2080 ssize_t num_bytes_read = 2081 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 2082 2083 if (num_bytes_read < (ssize_t)size) { 2084 mBuffer->release(); 2085 mBuffer = NULL; 2086 2087 return ERROR_IO; 2088 } 2089 2090 CHECK(mBuffer != NULL); 2091 mBuffer->set_range(0, size); 2092 mBuffer->meta_data()->clear(); 2093 mBuffer->meta_data()->setInt64( 2094 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2095 2096 if (targetSampleTimeUs >= 0) { 2097 mBuffer->meta_data()->setInt64( 2098 kKeyTargetTime, targetSampleTimeUs); 2099 } 2100 2101 if (isSyncSample) { 2102 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2103 } 2104 2105 ++mCurrentSampleIndex; 2106 } 2107 2108 if (!mIsAVC) { 2109 *out = mBuffer; 2110 mBuffer = NULL; 2111 2112 return OK; 2113 } 2114 2115 // Each NAL unit is split up into its constituent fragments and 2116 // each one of them returned in its own buffer. 2117 2118 CHECK(mBuffer->range_length() >= mNALLengthSize); 2119 2120 const uint8_t *src = 2121 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 2122 2123 size_t nal_size = parseNALSize(src); 2124 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 2125 ALOGE("incomplete NAL unit."); 2126 2127 mBuffer->release(); 2128 mBuffer = NULL; 2129 2130 return ERROR_MALFORMED; 2131 } 2132 2133 MediaBuffer *clone = mBuffer->clone(); 2134 CHECK(clone != NULL); 2135 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 2136 2137 CHECK(mBuffer != NULL); 2138 mBuffer->set_range( 2139 mBuffer->range_offset() + mNALLengthSize + nal_size, 2140 mBuffer->range_length() - mNALLengthSize - nal_size); 2141 2142 if (mBuffer->range_length() == 0) { 2143 mBuffer->release(); 2144 mBuffer = NULL; 2145 } 2146 2147 *out = clone; 2148 2149 return OK; 2150 } else { 2151 // Whole NAL units are returned but each fragment is prefixed by 2152 // the start code (0x00 00 00 01). 2153 ssize_t num_bytes_read = 0; 2154 int32_t drm = 0; 2155 bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0); 2156 if (usesDRM) { 2157 num_bytes_read = 2158 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size); 2159 } else { 2160 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size); 2161 } 2162 2163 if (num_bytes_read < (ssize_t)size) { 2164 mBuffer->release(); 2165 mBuffer = NULL; 2166 2167 return ERROR_IO; 2168 } 2169 2170 if (usesDRM) { 2171 CHECK(mBuffer != NULL); 2172 mBuffer->set_range(0, size); 2173 2174 } else { 2175 uint8_t *dstData = (uint8_t *)mBuffer->data(); 2176 size_t srcOffset = 0; 2177 size_t dstOffset = 0; 2178 2179 while (srcOffset < size) { 2180 bool isMalFormed = (srcOffset + mNALLengthSize > size); 2181 size_t nalLength = 0; 2182 if (!isMalFormed) { 2183 nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 2184 srcOffset += mNALLengthSize; 2185 isMalFormed = srcOffset + nalLength > size; 2186 } 2187 2188 if (isMalFormed) { 2189 ALOGE("Video is malformed"); 2190 mBuffer->release(); 2191 mBuffer = NULL; 2192 return ERROR_MALFORMED; 2193 } 2194 2195 if (nalLength == 0) { 2196 continue; 2197 } 2198 2199 CHECK(dstOffset + 4 <= mBuffer->size()); 2200 2201 dstData[dstOffset++] = 0; 2202 dstData[dstOffset++] = 0; 2203 dstData[dstOffset++] = 0; 2204 dstData[dstOffset++] = 1; 2205 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 2206 srcOffset += nalLength; 2207 dstOffset += nalLength; 2208 } 2209 CHECK_EQ(srcOffset, size); 2210 CHECK(mBuffer != NULL); 2211 mBuffer->set_range(0, dstOffset); 2212 } 2213 2214 mBuffer->meta_data()->clear(); 2215 mBuffer->meta_data()->setInt64( 2216 kKeyTime, ((int64_t)cts * 1000000) / mTimescale); 2217 2218 if (targetSampleTimeUs >= 0) { 2219 mBuffer->meta_data()->setInt64( 2220 kKeyTargetTime, targetSampleTimeUs); 2221 } 2222 2223 if (isSyncSample) { 2224 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1); 2225 } 2226 2227 ++mCurrentSampleIndex; 2228 2229 *out = mBuffer; 2230 mBuffer = NULL; 2231 2232 return OK; 2233 } 2234} 2235 2236MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix( 2237 const char *mimePrefix) { 2238 for (Track *track = mFirstTrack; track != NULL; track = track->next) { 2239 const char *mime; 2240 if (track->meta != NULL 2241 && track->meta->findCString(kKeyMIMEType, &mime) 2242 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) { 2243 return track; 2244 } 2245 } 2246 2247 return NULL; 2248} 2249 2250static bool LegacySniffMPEG4( 2251 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 2252 uint8_t header[8]; 2253 2254 ssize_t n = source->readAt(4, header, sizeof(header)); 2255 if (n < (ssize_t)sizeof(header)) { 2256 return false; 2257 } 2258 2259 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 2260 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 2261 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 2262 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 2263 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 2264 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 2265 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2266 *confidence = 0.4; 2267 2268 return true; 2269 } 2270 2271 return false; 2272} 2273 2274static bool isCompatibleBrand(uint32_t fourcc) { 2275 static const uint32_t kCompatibleBrands[] = { 2276 FOURCC('i', 's', 'o', 'm'), 2277 FOURCC('i', 's', 'o', '2'), 2278 FOURCC('a', 'v', 'c', '1'), 2279 FOURCC('3', 'g', 'p', '4'), 2280 FOURCC('m', 'p', '4', '1'), 2281 FOURCC('m', 'p', '4', '2'), 2282 2283 // Won't promise that the following file types can be played. 2284 // Just give these file types a chance. 2285 FOURCC('q', 't', ' ', ' '), // Apple's QuickTime 2286 FOURCC('M', 'S', 'N', 'V'), // Sony's PSP 2287 2288 FOURCC('3', 'g', '2', 'a'), // 3GPP2 2289 FOURCC('3', 'g', '2', 'b'), 2290 }; 2291 2292 for (size_t i = 0; 2293 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 2294 ++i) { 2295 if (kCompatibleBrands[i] == fourcc) { 2296 return true; 2297 } 2298 } 2299 2300 return false; 2301} 2302 2303// Attempt to actually parse the 'ftyp' atom and determine if a suitable 2304// compatible brand is present. 2305// Also try to identify where this file's metadata ends 2306// (end of the 'moov' atom) and report it to the caller as part of 2307// the metadata. 2308static bool BetterSniffMPEG4( 2309 const sp<DataSource> &source, String8 *mimeType, float *confidence, 2310 sp<AMessage> *meta) { 2311 // We scan up to 128 bytes to identify this file as an MP4. 2312 static const off64_t kMaxScanOffset = 128ll; 2313 2314 off64_t offset = 0ll; 2315 bool foundGoodFileType = false; 2316 off64_t moovAtomEndOffset = -1ll; 2317 bool done = false; 2318 2319 while (!done && offset < kMaxScanOffset) { 2320 uint32_t hdr[2]; 2321 if (source->readAt(offset, hdr, 8) < 8) { 2322 return false; 2323 } 2324 2325 uint64_t chunkSize = ntohl(hdr[0]); 2326 uint32_t chunkType = ntohl(hdr[1]); 2327 off64_t chunkDataOffset = offset + 8; 2328 2329 if (chunkSize == 1) { 2330 if (source->readAt(offset + 8, &chunkSize, 8) < 8) { 2331 return false; 2332 } 2333 2334 chunkSize = ntoh64(chunkSize); 2335 chunkDataOffset += 8; 2336 2337 if (chunkSize < 16) { 2338 // The smallest valid chunk is 16 bytes long in this case. 2339 return false; 2340 } 2341 } else if (chunkSize < 8) { 2342 // The smallest valid chunk is 8 bytes long. 2343 return false; 2344 } 2345 2346 off64_t chunkDataSize = offset + chunkSize - chunkDataOffset; 2347 2348 switch (chunkType) { 2349 case FOURCC('f', 't', 'y', 'p'): 2350 { 2351 if (chunkDataSize < 8) { 2352 return false; 2353 } 2354 2355 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4; 2356 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) { 2357 if (i == 1) { 2358 // Skip this index, it refers to the minorVersion, 2359 // not a brand. 2360 continue; 2361 } 2362 2363 uint32_t brand; 2364 if (source->readAt( 2365 chunkDataOffset + 4 * i, &brand, 4) < 4) { 2366 return false; 2367 } 2368 2369 brand = ntohl(brand); 2370 2371 if (isCompatibleBrand(brand)) { 2372 foundGoodFileType = true; 2373 break; 2374 } 2375 } 2376 2377 if (!foundGoodFileType) { 2378 return false; 2379 } 2380 2381 break; 2382 } 2383 2384 case FOURCC('m', 'o', 'o', 'v'): 2385 { 2386 moovAtomEndOffset = offset + chunkSize; 2387 2388 done = true; 2389 break; 2390 } 2391 2392 default: 2393 break; 2394 } 2395 2396 offset += chunkSize; 2397 } 2398 2399 if (!foundGoodFileType) { 2400 return false; 2401 } 2402 2403 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 2404 *confidence = 0.4f; 2405 2406 if (moovAtomEndOffset >= 0) { 2407 *meta = new AMessage; 2408 (*meta)->setInt64("meta-data-size", moovAtomEndOffset); 2409 2410 ALOGV("found metadata size: %lld", moovAtomEndOffset); 2411 } 2412 2413 return true; 2414} 2415 2416bool SniffMPEG4( 2417 const sp<DataSource> &source, String8 *mimeType, float *confidence, 2418 sp<AMessage> *meta) { 2419 if (BetterSniffMPEG4(source, mimeType, confidence, meta)) { 2420 return true; 2421 } 2422 2423 if (LegacySniffMPEG4(source, mimeType, confidence)) { 2424 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 2425 return true; 2426 } 2427 2428 return false; 2429} 2430 2431} // namespace android 2432