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