MPEG4Extractor.cpp revision cc14a8393b92cd1ed6cba74829396045605ab211
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 23#include <arpa/inet.h> 24 25#include <ctype.h> 26#include <stdint.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include <media/stagefright/DataSource.h> 31#include "include/ESDS.h" 32#include <media/stagefright/MediaBuffer.h> 33#include <media/stagefright/MediaBufferGroup.h> 34#include <media/stagefright/MediaDebug.h> 35#include <media/stagefright/MediaDefs.h> 36#include <media/stagefright/MediaSource.h> 37#include <media/stagefright/MetaData.h> 38#include <media/stagefright/Utils.h> 39#include <utils/String8.h> 40 41namespace android { 42 43class MPEG4Source : public MediaSource { 44public: 45 // Caller retains ownership of both "dataSource" and "sampleTable". 46 MPEG4Source(const sp<MetaData> &format, 47 const sp<DataSource> &dataSource, 48 int32_t timeScale, 49 const sp<SampleTable> &sampleTable); 50 51 virtual status_t start(MetaData *params = NULL); 52 virtual status_t stop(); 53 54 virtual sp<MetaData> getFormat(); 55 56 virtual status_t read( 57 MediaBuffer **buffer, const ReadOptions *options = NULL); 58 59protected: 60 virtual ~MPEG4Source(); 61 62private: 63 Mutex mLock; 64 65 sp<MetaData> mFormat; 66 sp<DataSource> mDataSource; 67 int32_t mTimescale; 68 sp<SampleTable> mSampleTable; 69 uint32_t mCurrentSampleIndex; 70 71 bool mIsAVC; 72 size_t mNALLengthSize; 73 74 bool mStarted; 75 76 MediaBufferGroup *mGroup; 77 78 MediaBuffer *mBuffer; 79 80 bool mWantsNALFragments; 81 82 uint8_t *mSrcBuffer; 83 84 size_t parseNALSize(const uint8_t *data) const; 85 86 MPEG4Source(const MPEG4Source &); 87 MPEG4Source &operator=(const MPEG4Source &); 88}; 89 90// This custom data source wraps an existing one and satisfies requests 91// falling entirely within a cached range from the cache while forwarding 92// all remaining requests to the wrapped datasource. 93// This is used to cache the full sampletable metadata for a single track, 94// possibly wrapping multiple times to cover all tracks, i.e. 95// Each MPEG4DataSource caches the sampletable metadata for a single track. 96 97struct MPEG4DataSource : public DataSource { 98 MPEG4DataSource(const sp<DataSource> &source); 99 100 virtual status_t initCheck() const; 101 virtual ssize_t readAt(off_t offset, void *data, size_t size); 102 virtual status_t getSize(off_t *size); 103 virtual uint32_t flags(); 104 105 status_t setCachedRange(off_t offset, size_t size); 106 107protected: 108 virtual ~MPEG4DataSource(); 109 110private: 111 Mutex mLock; 112 113 sp<DataSource> mSource; 114 off_t mCachedOffset; 115 size_t mCachedSize; 116 uint8_t *mCache; 117 118 void clearCache(); 119 120 MPEG4DataSource(const MPEG4DataSource &); 121 MPEG4DataSource &operator=(const MPEG4DataSource &); 122}; 123 124MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 125 : mSource(source), 126 mCachedOffset(0), 127 mCachedSize(0), 128 mCache(NULL) { 129} 130 131MPEG4DataSource::~MPEG4DataSource() { 132 clearCache(); 133} 134 135void MPEG4DataSource::clearCache() { 136 if (mCache) { 137 free(mCache); 138 mCache = NULL; 139 } 140 141 mCachedOffset = 0; 142 mCachedSize = 0; 143} 144 145status_t MPEG4DataSource::initCheck() const { 146 return mSource->initCheck(); 147} 148 149ssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 150 Mutex::Autolock autoLock(mLock); 151 152 if (offset >= mCachedOffset 153 && offset + size <= mCachedOffset + mCachedSize) { 154 memcpy(data, &mCache[offset - mCachedOffset], size); 155 return size; 156 } 157 158 return mSource->readAt(offset, data, size); 159} 160 161status_t MPEG4DataSource::getSize(off_t *size) { 162 return mSource->getSize(size); 163} 164 165uint32_t MPEG4DataSource::flags() { 166 return mSource->flags(); 167} 168 169status_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 170 Mutex::Autolock autoLock(mLock); 171 172 clearCache(); 173 174 mCache = (uint8_t *)malloc(size); 175 176 if (mCache == NULL) { 177 return -ENOMEM; 178 } 179 180 mCachedOffset = offset; 181 mCachedSize = size; 182 183 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 184 185 if (err < (ssize_t)size) { 186 clearCache(); 187 188 return ERROR_IO; 189 } 190 191 return OK; 192} 193 194//////////////////////////////////////////////////////////////////////////////// 195 196static void hexdump(const void *_data, size_t size) { 197 const uint8_t *data = (const uint8_t *)_data; 198 size_t offset = 0; 199 while (offset < size) { 200 printf("0x%04x ", offset); 201 202 size_t n = size - offset; 203 if (n > 16) { 204 n = 16; 205 } 206 207 for (size_t i = 0; i < 16; ++i) { 208 if (i == 8) { 209 printf(" "); 210 } 211 212 if (offset + i < size) { 213 printf("%02x ", data[offset + i]); 214 } else { 215 printf(" "); 216 } 217 } 218 219 printf(" "); 220 221 for (size_t i = 0; i < n; ++i) { 222 if (isprint(data[offset + i])) { 223 printf("%c", data[offset + i]); 224 } else { 225 printf("."); 226 } 227 } 228 229 printf("\n"); 230 231 offset += 16; 232 } 233} 234 235static const char *FourCC2MIME(uint32_t fourcc) { 236 switch (fourcc) { 237 case FOURCC('m', 'p', '4', 'a'): 238 return MEDIA_MIMETYPE_AUDIO_AAC; 239 240 case FOURCC('s', 'a', 'm', 'r'): 241 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 242 243 case FOURCC('s', 'a', 'w', 'b'): 244 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 245 246 case FOURCC('m', 'p', '4', 'v'): 247 return MEDIA_MIMETYPE_VIDEO_MPEG4; 248 249 case FOURCC('s', '2', '6', '3'): 250 return MEDIA_MIMETYPE_VIDEO_H263; 251 252 case FOURCC('a', 'v', 'c', '1'): 253 return MEDIA_MIMETYPE_VIDEO_AVC; 254 255 default: 256 CHECK(!"should not be here."); 257 return NULL; 258 } 259} 260 261MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 262 : mDataSource(source), 263 mHaveMetadata(false), 264 mHasVideo(false), 265 mFirstTrack(NULL), 266 mLastTrack(NULL), 267 mFileMetaData(new MetaData) { 268} 269 270MPEG4Extractor::~MPEG4Extractor() { 271 Track *track = mFirstTrack; 272 while (track) { 273 Track *next = track->next; 274 275 delete track; 276 track = next; 277 } 278 mFirstTrack = mLastTrack = NULL; 279} 280 281sp<MetaData> MPEG4Extractor::getMetaData() { 282 status_t err; 283 if ((err = readMetaData()) != OK) { 284 return new MetaData; 285 } 286 287 return mFileMetaData; 288} 289 290size_t MPEG4Extractor::countTracks() { 291 status_t err; 292 if ((err = readMetaData()) != OK) { 293 return 0; 294 } 295 296 size_t n = 0; 297 Track *track = mFirstTrack; 298 while (track) { 299 ++n; 300 track = track->next; 301 } 302 303 return n; 304} 305 306sp<MetaData> MPEG4Extractor::getTrackMetaData( 307 size_t index, uint32_t flags) { 308 status_t err; 309 if ((err = readMetaData()) != OK) { 310 return NULL; 311 } 312 313 Track *track = mFirstTrack; 314 while (index > 0) { 315 if (track == NULL) { 316 return NULL; 317 } 318 319 track = track->next; 320 --index; 321 } 322 323 if (track == NULL) { 324 return NULL; 325 } 326 327 if ((flags & kIncludeExtensiveMetaData) 328 && !track->includes_expensive_metadata) { 329 track->includes_expensive_metadata = true; 330 331 const char *mime; 332 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 333 if (!strncasecmp("video/", mime, 6)) { 334 uint32_t sampleIndex; 335 uint32_t sampleTime; 336 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 337 && track->sampleTable->getMetaDataForSample( 338 sampleIndex, NULL /* offset */, NULL /* size */, 339 &sampleTime) == OK) { 340 track->meta->setInt64( 341 kKeyThumbnailTime, 342 ((int64_t)sampleTime * 1000000) / track->timescale); 343 } 344 } 345 } 346 347 return track->meta; 348} 349 350status_t MPEG4Extractor::readMetaData() { 351 if (mHaveMetadata) { 352 return OK; 353 } 354 355 off_t offset = 0; 356 status_t err; 357 while ((err = parseChunk(&offset, 0)) == OK) { 358 } 359 360 if (mHaveMetadata) { 361 if (mHasVideo) { 362 mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 363 } else { 364 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 365 } 366 367 return OK; 368 } 369 370 return err; 371} 372 373static void MakeFourCCString(uint32_t x, char *s) { 374 s[0] = x >> 24; 375 s[1] = (x >> 16) & 0xff; 376 s[2] = (x >> 8) & 0xff; 377 s[3] = x & 0xff; 378 s[4] = '\0'; 379} 380 381struct PathAdder { 382 PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 383 : mPath(path) { 384 mPath->push(chunkType); 385 } 386 387 ~PathAdder() { 388 mPath->pop(); 389 } 390 391private: 392 Vector<uint32_t> *mPath; 393 394 PathAdder(const PathAdder &); 395 PathAdder &operator=(const PathAdder &); 396}; 397 398static bool underMetaDataPath(const Vector<uint32_t> &path) { 399 return path.size() >= 5 400 && path[0] == FOURCC('m', 'o', 'o', 'v') 401 && path[1] == FOURCC('u', 'd', 't', 'a') 402 && path[2] == FOURCC('m', 'e', 't', 'a') 403 && path[3] == FOURCC('i', 'l', 's', 't'); 404} 405 406// Given a time in seconds since Jan 1 1904, produce a human-readable string. 407static void convertTimeToDate(int64_t time_1904, String8 *s) { 408 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 409 410 char tmp[32]; 411 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 412 413 s->setTo(tmp); 414} 415 416status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 417 uint32_t hdr[2]; 418 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 419 return ERROR_IO; 420 } 421 uint64_t chunk_size = ntohl(hdr[0]); 422 uint32_t chunk_type = ntohl(hdr[1]); 423 off_t data_offset = *offset + 8; 424 425 if (chunk_size == 1) { 426 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 427 return ERROR_IO; 428 } 429 chunk_size = ntoh64(chunk_size); 430 data_offset += 8; 431 432 if (chunk_size < 16) { 433 // The smallest valid chunk is 16 bytes long in this case. 434 return ERROR_MALFORMED; 435 } 436 } else if (chunk_size < 8) { 437 // The smallest valid chunk is 8 bytes long. 438 return ERROR_MALFORMED; 439 } 440 441 char chunk[5]; 442 MakeFourCCString(chunk_type, chunk); 443 444#if 0 445 static const char kWhitespace[] = " "; 446 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 447 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 448 449 char buffer[256]; 450 size_t n = chunk_size; 451 if (n > sizeof(buffer)) { 452 n = sizeof(buffer); 453 } 454 if (mDataSource->readAt(*offset, buffer, n) 455 < (ssize_t)n) { 456 return ERROR_IO; 457 } 458 459 hexdump(buffer, n); 460#endif 461 462 PathAdder autoAdder(&mPath, chunk_type); 463 464 off_t chunk_data_size = *offset + chunk_size - data_offset; 465 466 if (chunk_type != FOURCC('c', 'p', 'r', 't') 467 && mPath.size() == 5 && underMetaDataPath(mPath)) { 468 off_t stop_offset = *offset + chunk_size; 469 *offset = data_offset; 470 while (*offset < stop_offset) { 471 status_t err = parseChunk(offset, depth + 1); 472 if (err != OK) { 473 return err; 474 } 475 } 476 477 if (*offset != stop_offset) { 478 return ERROR_MALFORMED; 479 } 480 481 return OK; 482 } 483 484 switch(chunk_type) { 485 case FOURCC('m', 'o', 'o', 'v'): 486 case FOURCC('t', 'r', 'a', 'k'): 487 case FOURCC('m', 'd', 'i', 'a'): 488 case FOURCC('m', 'i', 'n', 'f'): 489 case FOURCC('d', 'i', 'n', 'f'): 490 case FOURCC('s', 't', 'b', 'l'): 491 case FOURCC('m', 'v', 'e', 'x'): 492 case FOURCC('m', 'o', 'o', 'f'): 493 case FOURCC('t', 'r', 'a', 'f'): 494 case FOURCC('m', 'f', 'r', 'a'): 495 case FOURCC('s', 'k', 'i' ,'p'): 496 case FOURCC('u', 'd', 't', 'a'): 497 case FOURCC('i', 'l', 's', 't'): 498 { 499 if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 500 LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 501 502 if (mDataSource->flags() & DataSource::kWantsPrefetching) { 503 sp<MPEG4DataSource> cachedSource = 504 new MPEG4DataSource(mDataSource); 505 506 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 507 mDataSource = cachedSource; 508 } 509 } 510 511 mLastTrack->sampleTable = new SampleTable(mDataSource); 512 } 513 514 bool isTrack = false; 515 if (chunk_type == FOURCC('t', 'r', 'a', 'k')) { 516 isTrack = true; 517 518 Track *track = new Track; 519 track->next = NULL; 520 if (mLastTrack) { 521 mLastTrack->next = track; 522 } else { 523 mFirstTrack = track; 524 } 525 mLastTrack = track; 526 527 track->meta = new MetaData; 528 track->includes_expensive_metadata = false; 529 track->skipTrack = false; 530 track->timescale = 0; 531 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 532 } 533 534 off_t stop_offset = *offset + chunk_size; 535 *offset = data_offset; 536 while (*offset < stop_offset) { 537 status_t err = parseChunk(offset, depth + 1); 538 if (err != OK) { 539 return err; 540 } 541 } 542 543 if (*offset != stop_offset) { 544 return ERROR_MALFORMED; 545 } 546 547 if (isTrack) { 548 if (mLastTrack->skipTrack) { 549 Track *cur = mFirstTrack; 550 551 if (cur == mLastTrack) { 552 delete cur; 553 mFirstTrack = mLastTrack = NULL; 554 } else { 555 while (cur && cur->next != mLastTrack) { 556 cur = cur->next; 557 } 558 cur->next = NULL; 559 delete mLastTrack; 560 mLastTrack = cur; 561 } 562 563 return OK; 564 } 565 566 status_t err = verifyTrack(mLastTrack); 567 568 if (err != OK) { 569 return err; 570 } 571 } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 572 mHaveMetadata = true; 573 574 return UNKNOWN_ERROR; // Return a dummy error. 575 } 576 break; 577 } 578 579 case FOURCC('t', 'k', 'h', 'd'): 580 { 581 if (chunk_data_size < 4) { 582 return ERROR_MALFORMED; 583 } 584 585 uint8_t version; 586 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 587 return ERROR_IO; 588 } 589 590 uint64_t ctime, mtime, duration; 591 int32_t id; 592 uint32_t width, height; 593 594 if (version == 1) { 595 if (chunk_data_size != 36 + 60) { 596 return ERROR_MALFORMED; 597 } 598 599 uint8_t buffer[36 + 60]; 600 if (mDataSource->readAt( 601 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 602 return ERROR_IO; 603 } 604 605 ctime = U64_AT(&buffer[4]); 606 mtime = U64_AT(&buffer[12]); 607 id = U32_AT(&buffer[20]); 608 duration = U64_AT(&buffer[28]); 609 width = U32_AT(&buffer[88]); 610 height = U32_AT(&buffer[92]); 611 } else if (version == 0) { 612 if (chunk_data_size != 24 + 60) { 613 return ERROR_MALFORMED; 614 } 615 616 uint8_t buffer[24 + 60]; 617 if (mDataSource->readAt( 618 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 619 return ERROR_IO; 620 } 621 ctime = U32_AT(&buffer[4]); 622 mtime = U32_AT(&buffer[8]); 623 id = U32_AT(&buffer[12]); 624 duration = U32_AT(&buffer[20]); 625 width = U32_AT(&buffer[76]); 626 height = U32_AT(&buffer[80]); 627 } 628 629 *offset += chunk_size; 630 break; 631 } 632 633 case FOURCC('m', 'd', 'h', 'd'): 634 { 635 if (chunk_data_size < 4) { 636 return ERROR_MALFORMED; 637 } 638 639 uint8_t version; 640 if (mDataSource->readAt( 641 data_offset, &version, sizeof(version)) 642 < (ssize_t)sizeof(version)) { 643 return ERROR_IO; 644 } 645 646 off_t timescale_offset; 647 648 if (version == 1) { 649 timescale_offset = data_offset + 4 + 16; 650 } else if (version == 0) { 651 timescale_offset = data_offset + 4 + 8; 652 } else { 653 return ERROR_IO; 654 } 655 656 uint32_t timescale; 657 if (mDataSource->readAt( 658 timescale_offset, ×cale, sizeof(timescale)) 659 < (ssize_t)sizeof(timescale)) { 660 return ERROR_IO; 661 } 662 663 mLastTrack->timescale = ntohl(timescale); 664 665 int64_t duration; 666 if (version == 1) { 667 if (mDataSource->readAt( 668 timescale_offset + 4, &duration, sizeof(duration)) 669 < (ssize_t)sizeof(duration)) { 670 return ERROR_IO; 671 } 672 duration = ntoh64(duration); 673 } else { 674 int32_t duration32; 675 if (mDataSource->readAt( 676 timescale_offset + 4, &duration32, sizeof(duration32)) 677 < (ssize_t)sizeof(duration32)) { 678 return ERROR_IO; 679 } 680 duration = ntohl(duration32); 681 } 682 mLastTrack->meta->setInt64( 683 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 684 685 *offset += chunk_size; 686 break; 687 } 688 689 case FOURCC('s', 't', 's', 'd'): 690 { 691 if (chunk_data_size < 8) { 692 return ERROR_MALFORMED; 693 } 694 695 uint8_t buffer[8]; 696 if (chunk_data_size < (off_t)sizeof(buffer)) { 697 return ERROR_MALFORMED; 698 } 699 700 if (mDataSource->readAt( 701 data_offset, buffer, 8) < 8) { 702 return ERROR_IO; 703 } 704 705 if (U32_AT(buffer) != 0) { 706 // Should be version 0, flags 0. 707 return ERROR_MALFORMED; 708 } 709 710 uint32_t entry_count = U32_AT(&buffer[4]); 711 712 if (entry_count > 1) { 713 // For now we only support a single type of media per track. 714 715 mLastTrack->skipTrack = true; 716 *offset += chunk_size; 717 break; 718 } 719 720 off_t stop_offset = *offset + chunk_size; 721 *offset = data_offset + 8; 722 for (uint32_t i = 0; i < entry_count; ++i) { 723 status_t err = parseChunk(offset, depth + 1); 724 if (err != OK) { 725 return err; 726 } 727 } 728 729 if (*offset != stop_offset) { 730 return ERROR_MALFORMED; 731 } 732 break; 733 } 734 735 case FOURCC('m', 'p', '4', 'a'): 736 case FOURCC('s', 'a', 'm', 'r'): 737 case FOURCC('s', 'a', 'w', 'b'): 738 { 739 uint8_t buffer[8 + 20]; 740 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 741 // Basic AudioSampleEntry size. 742 return ERROR_MALFORMED; 743 } 744 745 if (mDataSource->readAt( 746 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 747 return ERROR_IO; 748 } 749 750 uint16_t data_ref_index = U16_AT(&buffer[6]); 751 uint16_t num_channels = U16_AT(&buffer[16]); 752 753 uint16_t sample_size = U16_AT(&buffer[18]); 754 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 755 756 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 757 FourCC2MIME(chunk_type))) { 758 // AMR NB audio is always mono, 8kHz 759 num_channels = 1; 760 sample_rate = 8000; 761 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 762 FourCC2MIME(chunk_type))) { 763 // AMR WB audio is always mono, 16kHz 764 num_channels = 1; 765 sample_rate = 16000; 766 } 767 768#if 0 769 printf("*** coding='%s' %d channels, size %d, rate %d\n", 770 chunk, num_channels, sample_size, sample_rate); 771#endif 772 773 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 774 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 775 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 776 777 off_t stop_offset = *offset + chunk_size; 778 *offset = data_offset + sizeof(buffer); 779 while (*offset < stop_offset) { 780 status_t err = parseChunk(offset, depth + 1); 781 if (err != OK) { 782 return err; 783 } 784 } 785 786 if (*offset != stop_offset) { 787 return ERROR_MALFORMED; 788 } 789 break; 790 } 791 792 case FOURCC('m', 'p', '4', 'v'): 793 case FOURCC('s', '2', '6', '3'): 794 case FOURCC('a', 'v', 'c', '1'): 795 { 796 mHasVideo = true; 797 798 uint8_t buffer[78]; 799 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 800 // Basic VideoSampleEntry size. 801 return ERROR_MALFORMED; 802 } 803 804 if (mDataSource->readAt( 805 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 806 return ERROR_IO; 807 } 808 809 uint16_t data_ref_index = U16_AT(&buffer[6]); 810 uint16_t width = U16_AT(&buffer[6 + 18]); 811 uint16_t height = U16_AT(&buffer[6 + 20]); 812 813 // printf("*** coding='%s' width=%d height=%d\n", 814 // chunk, width, height); 815 816 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 817 mLastTrack->meta->setInt32(kKeyWidth, width); 818 mLastTrack->meta->setInt32(kKeyHeight, height); 819 820 off_t stop_offset = *offset + chunk_size; 821 *offset = data_offset + sizeof(buffer); 822 while (*offset < stop_offset) { 823 status_t err = parseChunk(offset, depth + 1); 824 if (err != OK) { 825 return err; 826 } 827 } 828 829 if (*offset != stop_offset) { 830 return ERROR_MALFORMED; 831 } 832 break; 833 } 834 835 case FOURCC('s', 't', 'c', 'o'): 836 case FOURCC('c', 'o', '6', '4'): 837 { 838 status_t err = 839 mLastTrack->sampleTable->setChunkOffsetParams( 840 chunk_type, data_offset, chunk_data_size); 841 842 if (err != OK) { 843 return err; 844 } 845 846 *offset += chunk_size; 847 break; 848 } 849 850 case FOURCC('s', 't', 's', 'c'): 851 { 852 status_t err = 853 mLastTrack->sampleTable->setSampleToChunkParams( 854 data_offset, chunk_data_size); 855 856 if (err != OK) { 857 return err; 858 } 859 860 *offset += chunk_size; 861 break; 862 } 863 864 case FOURCC('s', 't', 's', 'z'): 865 case FOURCC('s', 't', 'z', '2'): 866 { 867 status_t err = 868 mLastTrack->sampleTable->setSampleSizeParams( 869 chunk_type, data_offset, chunk_data_size); 870 871 if (err != OK) { 872 return err; 873 } 874 875 size_t max_size; 876 CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 877 878 // Assume that a given buffer only contains at most 10 fragments, 879 // each fragment originally prefixed with a 2 byte length will 880 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 881 // and thus will grow by 2 bytes per fragment. 882 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 883 884 *offset += chunk_size; 885 break; 886 } 887 888 case FOURCC('s', 't', 't', 's'): 889 { 890 status_t err = 891 mLastTrack->sampleTable->setTimeToSampleParams( 892 data_offset, chunk_data_size); 893 894 if (err != OK) { 895 return err; 896 } 897 898 *offset += chunk_size; 899 break; 900 } 901 902 case FOURCC('s', 't', 's', 's'): 903 { 904 status_t err = 905 mLastTrack->sampleTable->setSyncSampleParams( 906 data_offset, chunk_data_size); 907 908 if (err != OK) { 909 return err; 910 } 911 912 *offset += chunk_size; 913 break; 914 } 915 916 case FOURCC('e', 's', 'd', 's'): 917 { 918 if (chunk_data_size < 4) { 919 return ERROR_MALFORMED; 920 } 921 922 uint8_t buffer[256]; 923 if (chunk_data_size > (off_t)sizeof(buffer)) { 924 return ERROR_BUFFER_TOO_SMALL; 925 } 926 927 if (mDataSource->readAt( 928 data_offset, buffer, chunk_data_size) < chunk_data_size) { 929 return ERROR_IO; 930 } 931 932 if (U32_AT(buffer) != 0) { 933 // Should be version 0, flags 0. 934 return ERROR_MALFORMED; 935 } 936 937 mLastTrack->meta->setData( 938 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 939 940 if (mPath.size() >= 2 941 && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) { 942 // Information from the ESDS must be relied on for proper 943 // setup of sample rate and channel count for MPEG4 Audio. 944 // The generic header appears to only contain generic 945 // information... 946 947 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio( 948 &buffer[4], chunk_data_size - 4); 949 950 if (err != OK) { 951 return err; 952 } 953 } 954 955 *offset += chunk_size; 956 break; 957 } 958 959 case FOURCC('a', 'v', 'c', 'C'): 960 { 961 char buffer[256]; 962 if (chunk_data_size > (off_t)sizeof(buffer)) { 963 return ERROR_BUFFER_TOO_SMALL; 964 } 965 966 if (mDataSource->readAt( 967 data_offset, buffer, chunk_data_size) < chunk_data_size) { 968 return ERROR_IO; 969 } 970 971 mLastTrack->meta->setData( 972 kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 973 974 *offset += chunk_size; 975 break; 976 } 977 978 case FOURCC('m', 'e', 't', 'a'): 979 { 980 uint8_t buffer[4]; 981 if (chunk_data_size < (off_t)sizeof(buffer)) { 982 return ERROR_MALFORMED; 983 } 984 985 if (mDataSource->readAt( 986 data_offset, buffer, 4) < 4) { 987 return ERROR_IO; 988 } 989 990 if (U32_AT(buffer) != 0) { 991 // Should be version 0, flags 0. 992 993 // If it's not, let's assume this is one of those 994 // apparently malformed chunks that don't have flags 995 // and completely different semantics than what's 996 // in the MPEG4 specs and skip it. 997 *offset += chunk_size; 998 return OK; 999 } 1000 1001 off_t stop_offset = *offset + chunk_size; 1002 *offset = data_offset + sizeof(buffer); 1003 while (*offset < stop_offset) { 1004 status_t err = parseChunk(offset, depth + 1); 1005 if (err != OK) { 1006 return err; 1007 } 1008 } 1009 1010 if (*offset != stop_offset) { 1011 return ERROR_MALFORMED; 1012 } 1013 break; 1014 } 1015 1016 case FOURCC('d', 'a', 't', 'a'): 1017 { 1018 if (mPath.size() == 6 && underMetaDataPath(mPath)) { 1019 status_t err = parseMetaData(data_offset, chunk_data_size); 1020 1021 if (err != OK) { 1022 return err; 1023 } 1024 } 1025 1026 *offset += chunk_size; 1027 break; 1028 } 1029 1030 case FOURCC('m', 'v', 'h', 'd'): 1031 { 1032 if (chunk_data_size < 12) { 1033 return ERROR_MALFORMED; 1034 } 1035 1036 uint8_t header[12]; 1037 if (mDataSource->readAt( 1038 data_offset, header, sizeof(header)) 1039 < (ssize_t)sizeof(header)) { 1040 return ERROR_IO; 1041 } 1042 1043 int64_t creationTime; 1044 if (header[0] == 1) { 1045 creationTime = U64_AT(&header[4]); 1046 } else if (header[0] != 0) { 1047 return ERROR_MALFORMED; 1048 } else { 1049 creationTime = U32_AT(&header[4]); 1050 } 1051 1052 String8 s; 1053 convertTimeToDate(creationTime, &s); 1054 1055 mFileMetaData->setCString(kKeyDate, s.string()); 1056 1057 *offset += chunk_size; 1058 break; 1059 } 1060 1061 default: 1062 { 1063 *offset += chunk_size; 1064 break; 1065 } 1066 } 1067 1068 return OK; 1069} 1070 1071status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 1072 if (size < 4) { 1073 return ERROR_MALFORMED; 1074 } 1075 1076 uint8_t *buffer = new uint8_t[size + 1]; 1077 if (mDataSource->readAt( 1078 offset, buffer, size) != (ssize_t)size) { 1079 delete[] buffer; 1080 buffer = NULL; 1081 1082 return ERROR_IO; 1083 } 1084 1085 uint32_t flags = U32_AT(buffer); 1086 1087 uint32_t metadataKey = 0; 1088 switch (mPath[4]) { 1089 case FOURCC(0xa9, 'a', 'l', 'b'): 1090 { 1091 metadataKey = kKeyAlbum; 1092 break; 1093 } 1094 case FOURCC(0xa9, 'A', 'R', 'T'): 1095 { 1096 metadataKey = kKeyArtist; 1097 break; 1098 } 1099 case FOURCC('a', 'A', 'R', 'T'): 1100 { 1101 metadataKey = kKeyAlbumArtist; 1102 break; 1103 } 1104 case FOURCC(0xa9, 'd', 'a', 'y'): 1105 { 1106 metadataKey = kKeyYear; 1107 break; 1108 } 1109 case FOURCC(0xa9, 'n', 'a', 'm'): 1110 { 1111 metadataKey = kKeyTitle; 1112 break; 1113 } 1114 case FOURCC(0xa9, 'w', 'r', 't'): 1115 { 1116 metadataKey = kKeyWriter; 1117 break; 1118 } 1119 case FOURCC('c', 'o', 'v', 'r'): 1120 { 1121 metadataKey = kKeyAlbumArt; 1122 break; 1123 } 1124 case FOURCC('g', 'n', 'r', 'e'): 1125 { 1126 metadataKey = kKeyGenre; 1127 break; 1128 } 1129 case FOURCC(0xa9, 'g', 'e', 'n'): 1130 { 1131 metadataKey = kKeyGenre; 1132 break; 1133 } 1134 case FOURCC('t', 'r', 'k', 'n'): 1135 { 1136 if (size == 16 && flags == 0) { 1137 char tmp[16]; 1138 sprintf(tmp, "%d/%d", 1139 (int)buffer[size - 5], (int)buffer[size - 3]); 1140 1141 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1142 } 1143 break; 1144 } 1145 case FOURCC('d', 'i', 's', 'k'): 1146 { 1147 if (size == 14 && flags == 0) { 1148 char tmp[16]; 1149 sprintf(tmp, "%d/%d", 1150 (int)buffer[size - 3], (int)buffer[size - 1]); 1151 1152 mFileMetaData->setCString(kKeyDiscNumber, tmp); 1153 } 1154 break; 1155 } 1156 1157 default: 1158 break; 1159 } 1160 1161 if (size >= 8 && metadataKey) { 1162 if (metadataKey == kKeyAlbumArt) { 1163 mFileMetaData->setData( 1164 kKeyAlbumArt, MetaData::TYPE_NONE, 1165 buffer + 8, size - 8); 1166 } else if (metadataKey == kKeyGenre) { 1167 if (flags == 0) { 1168 // uint8_t genre code, iTunes genre codes are 1169 // the standard id3 codes, except they start 1170 // at 1 instead of 0 (e.g. Pop is 14, not 13) 1171 // We use standard id3 numbering, so subtract 1. 1172 int genrecode = (int)buffer[size - 1]; 1173 genrecode--; 1174 if (genrecode < 0) { 1175 genrecode = 255; // reserved for 'unknown genre' 1176 } 1177 char genre[10]; 1178 sprintf(genre, "%d", genrecode); 1179 1180 mFileMetaData->setCString(metadataKey, genre); 1181 } else if (flags == 1) { 1182 // custom genre string 1183 buffer[size] = '\0'; 1184 1185 mFileMetaData->setCString( 1186 metadataKey, (const char *)buffer + 8); 1187 } 1188 } else { 1189 buffer[size] = '\0'; 1190 1191 mFileMetaData->setCString( 1192 metadataKey, (const char *)buffer + 8); 1193 } 1194 } 1195 1196 delete[] buffer; 1197 buffer = NULL; 1198 1199 return OK; 1200} 1201 1202sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1203 status_t err; 1204 if ((err = readMetaData()) != OK) { 1205 return NULL; 1206 } 1207 1208 Track *track = mFirstTrack; 1209 while (index > 0) { 1210 if (track == NULL) { 1211 return NULL; 1212 } 1213 1214 track = track->next; 1215 --index; 1216 } 1217 1218 if (track == NULL) { 1219 return NULL; 1220 } 1221 1222 return new MPEG4Source( 1223 track->meta, mDataSource, track->timescale, track->sampleTable); 1224} 1225 1226// static 1227status_t MPEG4Extractor::verifyTrack(Track *track) { 1228 const char *mime; 1229 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 1230 1231 uint32_t type; 1232 const void *data; 1233 size_t size; 1234 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { 1235 if (!track->meta->findData(kKeyAVCC, &type, &data, &size) 1236 || type != kTypeAVCC) { 1237 return ERROR_MALFORMED; 1238 } 1239 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) 1240 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) { 1241 if (!track->meta->findData(kKeyESDS, &type, &data, &size) 1242 || type != kTypeESDS) { 1243 return ERROR_MALFORMED; 1244 } 1245 } 1246 1247 return OK; 1248} 1249 1250status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( 1251 const void *esds_data, size_t esds_size) { 1252 ESDS esds(esds_data, esds_size); 1253 1254 uint8_t objectTypeIndication; 1255 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) { 1256 return ERROR_MALFORMED; 1257 } 1258 1259 if (objectTypeIndication == 0xe1) { 1260 // This isn't MPEG4 audio at all, it's QCELP 14k... 1261 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP); 1262 return OK; 1263 } 1264 1265 const uint8_t *csd; 1266 size_t csd_size; 1267 if (esds.getCodecSpecificInfo( 1268 (const void **)&csd, &csd_size) != OK) { 1269 return ERROR_MALFORMED; 1270 } 1271 1272#if 0 1273 printf("ESD of size %d\n", csd_size); 1274 hexdump(csd, csd_size); 1275#endif 1276 1277 if (csd_size < 2) { 1278 return ERROR_MALFORMED; 1279 } 1280 1281 uint32_t objectType = csd[0] >> 3; 1282 1283 if (objectType == 31) { 1284 return ERROR_UNSUPPORTED; 1285 } 1286 1287 uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7); 1288 int32_t sampleRate = 0; 1289 int32_t numChannels = 0; 1290 if (freqIndex == 15) { 1291 if (csd_size < 5) { 1292 return ERROR_MALFORMED; 1293 } 1294 1295 sampleRate = (csd[1] & 0x7f) << 17 1296 | csd[2] << 9 1297 | csd[3] << 1 1298 | (csd[4] >> 7); 1299 1300 numChannels = (csd[4] >> 3) & 15; 1301 } else { 1302 static uint32_t kSamplingRate[] = { 1303 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 1304 16000, 12000, 11025, 8000, 7350 1305 }; 1306 1307 if (freqIndex == 13 || freqIndex == 14) { 1308 return ERROR_MALFORMED; 1309 } 1310 1311 sampleRate = kSamplingRate[freqIndex]; 1312 numChannels = (csd[1] >> 3) & 15; 1313 } 1314 1315 if (numChannels == 0) { 1316 return ERROR_UNSUPPORTED; 1317 } 1318 1319 int32_t prevSampleRate; 1320 CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate)); 1321 1322 if (prevSampleRate != sampleRate) { 1323 LOGV("mpeg4 audio sample rate different from previous setting. " 1324 "was: %d, now: %d", prevSampleRate, sampleRate); 1325 } 1326 1327 mLastTrack->meta->setInt32(kKeySampleRate, sampleRate); 1328 1329 int32_t prevChannelCount; 1330 CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount)); 1331 1332 if (prevChannelCount != numChannels) { 1333 LOGV("mpeg4 audio channel count different from previous setting. " 1334 "was: %d, now: %d", prevChannelCount, numChannels); 1335 } 1336 1337 mLastTrack->meta->setInt32(kKeyChannelCount, numChannels); 1338 1339 return OK; 1340} 1341 1342//////////////////////////////////////////////////////////////////////////////// 1343 1344MPEG4Source::MPEG4Source( 1345 const sp<MetaData> &format, 1346 const sp<DataSource> &dataSource, 1347 int32_t timeScale, 1348 const sp<SampleTable> &sampleTable) 1349 : mFormat(format), 1350 mDataSource(dataSource), 1351 mTimescale(timeScale), 1352 mSampleTable(sampleTable), 1353 mCurrentSampleIndex(0), 1354 mIsAVC(false), 1355 mNALLengthSize(0), 1356 mStarted(false), 1357 mGroup(NULL), 1358 mBuffer(NULL), 1359 mWantsNALFragments(false), 1360 mSrcBuffer(NULL) { 1361 const char *mime; 1362 bool success = mFormat->findCString(kKeyMIMEType, &mime); 1363 CHECK(success); 1364 1365 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1366 1367 if (mIsAVC) { 1368 uint32_t type; 1369 const void *data; 1370 size_t size; 1371 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1372 1373 const uint8_t *ptr = (const uint8_t *)data; 1374 1375 CHECK(size >= 7); 1376 CHECK_EQ(ptr[0], 1); // configurationVersion == 1 1377 1378 // The number of bytes used to encode the length of a NAL unit. 1379 mNALLengthSize = 1 + (ptr[4] & 3); 1380 } 1381} 1382 1383MPEG4Source::~MPEG4Source() { 1384 if (mStarted) { 1385 stop(); 1386 } 1387} 1388 1389status_t MPEG4Source::start(MetaData *params) { 1390 Mutex::Autolock autoLock(mLock); 1391 1392 CHECK(!mStarted); 1393 1394 int32_t val; 1395 if (params && params->findInt32(kKeyWantsNALFragments, &val) 1396 && val != 0) { 1397 mWantsNALFragments = true; 1398 } else { 1399 mWantsNALFragments = false; 1400 } 1401 1402 mGroup = new MediaBufferGroup; 1403 1404 int32_t max_size; 1405 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1406 1407 mGroup->add_buffer(new MediaBuffer(max_size)); 1408 1409 mSrcBuffer = new uint8_t[max_size]; 1410 1411 mStarted = true; 1412 1413 return OK; 1414} 1415 1416status_t MPEG4Source::stop() { 1417 Mutex::Autolock autoLock(mLock); 1418 1419 CHECK(mStarted); 1420 1421 if (mBuffer != NULL) { 1422 mBuffer->release(); 1423 mBuffer = NULL; 1424 } 1425 1426 delete[] mSrcBuffer; 1427 mSrcBuffer = NULL; 1428 1429 delete mGroup; 1430 mGroup = NULL; 1431 1432 mStarted = false; 1433 mCurrentSampleIndex = 0; 1434 1435 return OK; 1436} 1437 1438sp<MetaData> MPEG4Source::getFormat() { 1439 Mutex::Autolock autoLock(mLock); 1440 1441 return mFormat; 1442} 1443 1444size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1445 switch (mNALLengthSize) { 1446 case 1: 1447 return *data; 1448 case 2: 1449 return U16_AT(data); 1450 case 3: 1451 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1452 case 4: 1453 return U32_AT(data); 1454 } 1455 1456 // This cannot happen, mNALLengthSize springs to life by adding 1 to 1457 // a 2-bit integer. 1458 CHECK(!"Should not be here."); 1459 1460 return 0; 1461} 1462 1463status_t MPEG4Source::read( 1464 MediaBuffer **out, const ReadOptions *options) { 1465 Mutex::Autolock autoLock(mLock); 1466 1467 CHECK(mStarted); 1468 1469 *out = NULL; 1470 1471 int64_t seekTimeUs; 1472 if (options && options->getSeekTo(&seekTimeUs)) { 1473 uint32_t sampleIndex; 1474 status_t err = mSampleTable->findClosestSample( 1475 seekTimeUs * mTimescale / 1000000, 1476 &sampleIndex, SampleTable::kSyncSample_Flag); 1477 1478 if (err != OK) { 1479 if (err == ERROR_OUT_OF_RANGE) { 1480 // An attempt to seek past the end of the stream would 1481 // normally cause this ERROR_OUT_OF_RANGE error. Propagating 1482 // this all the way to the MediaPlayer would cause abnormal 1483 // termination. Legacy behaviour appears to be to behave as if 1484 // we had seeked to the end of stream, ending normally. 1485 err = ERROR_END_OF_STREAM; 1486 } 1487 return err; 1488 } 1489 1490 mCurrentSampleIndex = sampleIndex; 1491 if (mBuffer != NULL) { 1492 mBuffer->release(); 1493 mBuffer = NULL; 1494 } 1495 1496 // fall through 1497 } 1498 1499 off_t offset; 1500 size_t size; 1501 uint32_t dts; 1502 bool newBuffer = false; 1503 if (mBuffer == NULL) { 1504 newBuffer = true; 1505 1506 status_t err = 1507 mSampleTable->getMetaDataForSample( 1508 mCurrentSampleIndex, &offset, &size, &dts); 1509 1510 if (err != OK) { 1511 return err; 1512 } 1513 1514 err = mGroup->acquire_buffer(&mBuffer); 1515 1516 if (err != OK) { 1517 CHECK_EQ(mBuffer, NULL); 1518 return err; 1519 } 1520 } 1521 1522 if (!mIsAVC || mWantsNALFragments) { 1523 if (newBuffer) { 1524 ssize_t num_bytes_read = 1525 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1526 1527 if (num_bytes_read < (ssize_t)size) { 1528 mBuffer->release(); 1529 mBuffer = NULL; 1530 1531 return ERROR_IO; 1532 } 1533 1534 CHECK(mBuffer != NULL); 1535 mBuffer->set_range(0, size); 1536 mBuffer->meta_data()->clear(); 1537 mBuffer->meta_data()->setInt64( 1538 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1539 ++mCurrentSampleIndex; 1540 } 1541 1542 if (!mIsAVC) { 1543 *out = mBuffer; 1544 mBuffer = NULL; 1545 1546 return OK; 1547 } 1548 1549 // Each NAL unit is split up into its constituent fragments and 1550 // each one of them returned in its own buffer. 1551 1552 CHECK(mBuffer->range_length() >= mNALLengthSize); 1553 1554 const uint8_t *src = 1555 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1556 1557 size_t nal_size = parseNALSize(src); 1558 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1559 LOGE("incomplete NAL unit."); 1560 1561 mBuffer->release(); 1562 mBuffer = NULL; 1563 1564 return ERROR_MALFORMED; 1565 } 1566 1567 MediaBuffer *clone = mBuffer->clone(); 1568 CHECK(clone != NULL); 1569 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1570 1571 CHECK(mBuffer != NULL); 1572 mBuffer->set_range( 1573 mBuffer->range_offset() + mNALLengthSize + nal_size, 1574 mBuffer->range_length() - mNALLengthSize - nal_size); 1575 1576 if (mBuffer->range_length() == 0) { 1577 mBuffer->release(); 1578 mBuffer = NULL; 1579 } 1580 1581 *out = clone; 1582 1583 return OK; 1584 } else { 1585 // Whole NAL units are returned but each fragment is prefixed by 1586 // the start code (0x00 00 00 01). 1587 1588 ssize_t num_bytes_read = 1589 mDataSource->readAt(offset, mSrcBuffer, size); 1590 1591 if (num_bytes_read < (ssize_t)size) { 1592 mBuffer->release(); 1593 mBuffer = NULL; 1594 1595 return ERROR_IO; 1596 } 1597 1598 uint8_t *dstData = (uint8_t *)mBuffer->data(); 1599 size_t srcOffset = 0; 1600 size_t dstOffset = 0; 1601 1602 while (srcOffset < size) { 1603 CHECK(srcOffset + mNALLengthSize <= size); 1604 size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1605 srcOffset += mNALLengthSize; 1606 1607 if (srcOffset + nalLength > size) { 1608 mBuffer->release(); 1609 mBuffer = NULL; 1610 1611 return ERROR_MALFORMED; 1612 } 1613 1614 if (nalLength == 0) { 1615 continue; 1616 } 1617 1618 CHECK(dstOffset + 4 <= mBuffer->size()); 1619 1620 dstData[dstOffset++] = 0; 1621 dstData[dstOffset++] = 0; 1622 dstData[dstOffset++] = 0; 1623 dstData[dstOffset++] = 1; 1624 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1625 srcOffset += nalLength; 1626 dstOffset += nalLength; 1627 } 1628 CHECK_EQ(srcOffset, size); 1629 1630 CHECK(mBuffer != NULL); 1631 mBuffer->set_range(0, dstOffset); 1632 mBuffer->meta_data()->clear(); 1633 mBuffer->meta_data()->setInt64( 1634 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1635 ++mCurrentSampleIndex; 1636 1637 *out = mBuffer; 1638 mBuffer = NULL; 1639 1640 return OK; 1641 } 1642} 1643 1644static bool LegacySniffMPEG4( 1645 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1646 uint8_t header[8]; 1647 1648 ssize_t n = source->readAt(4, header, sizeof(header)); 1649 if (n < (ssize_t)sizeof(header)) { 1650 return false; 1651 } 1652 1653 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1654 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8) 1655 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8) 1656 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 1657 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8) 1658 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) { 1659 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1660 *confidence = 0.1; 1661 1662 return true; 1663 } 1664 1665 return false; 1666} 1667 1668static bool isCompatibleBrand(uint32_t fourcc) { 1669 static const uint32_t kCompatibleBrands[] = { 1670 FOURCC('i', 's', 'o', 'm'), 1671 FOURCC('i', 's', 'o', '2'), 1672 FOURCC('a', 'v', 'c', '1'), 1673 FOURCC('3', 'g', 'p', '4'), 1674 FOURCC('m', 'p', '4', '1'), 1675 FOURCC('m', 'p', '4', '2'), 1676 }; 1677 1678 for (size_t i = 0; 1679 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]); 1680 ++i) { 1681 if (kCompatibleBrands[i] == fourcc) { 1682 return true; 1683 } 1684 } 1685 1686 return false; 1687} 1688 1689// Attempt to actually parse the 'ftyp' atom and determine if a suitable 1690// compatible brand is present. 1691static bool BetterSniffMPEG4( 1692 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1693 uint8_t header[12]; 1694 if (source->readAt(0, header, 12) != 12 1695 || memcmp("ftyp", &header[4], 4)) { 1696 return false; 1697 } 1698 1699 size_t atomSize = U32_AT(&header[0]); 1700 if (atomSize < 16 || (atomSize % 4) != 0) { 1701 return false; 1702 } 1703 1704 bool success = false; 1705 if (isCompatibleBrand(U32_AT(&header[8]))) { 1706 success = true; 1707 } else { 1708 size_t numCompatibleBrands = (atomSize - 16) / 4; 1709 for (size_t i = 0; i < numCompatibleBrands; ++i) { 1710 uint8_t tmp[4]; 1711 if (source->readAt(16 + i * 4, tmp, 4) != 4) { 1712 return false; 1713 } 1714 1715 if (isCompatibleBrand(U32_AT(&tmp[0]))) { 1716 success = true; 1717 break; 1718 } 1719 } 1720 } 1721 1722 if (!success) { 1723 return false; 1724 } 1725 1726 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1727 *confidence = 0.3f; 1728 1729 return true; 1730} 1731 1732bool SniffMPEG4( 1733 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1734 if (BetterSniffMPEG4(source, mimeType, confidence)) { 1735 return true; 1736 } 1737 1738 if (LegacySniffMPEG4(source, mimeType, confidence)) { 1739 LOGW("Identified supported mpeg4 through LegacySniffMPEG4."); 1740 return true; 1741 } 1742 1743 return false; 1744} 1745 1746} // namespace android 1747 1748