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