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