MPEG4Extractor.cpp revision affa99c52957685f5a5652ab5254b92e729651c7
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 <media/stagefright/MediaBuffer.h> 32#include <media/stagefright/MediaBufferGroup.h> 33#include <media/stagefright/MediaDebug.h> 34#include <media/stagefright/MediaDefs.h> 35#include <media/stagefright/MediaSource.h> 36#include <media/stagefright/MetaData.h> 37#include <media/stagefright/Utils.h> 38#include <utils/String8.h> 39 40namespace android { 41 42class MPEG4Source : public MediaSource { 43public: 44 // Caller retains ownership of both "dataSource" and "sampleTable". 45 MPEG4Source(const sp<MetaData> &format, 46 const sp<DataSource> &dataSource, 47 int32_t timeScale, 48 const sp<SampleTable> &sampleTable); 49 50 virtual status_t start(MetaData *params = NULL); 51 virtual status_t stop(); 52 53 virtual sp<MetaData> getFormat(); 54 55 virtual status_t read( 56 MediaBuffer **buffer, const ReadOptions *options = NULL); 57 58protected: 59 virtual ~MPEG4Source(); 60 61private: 62 sp<MetaData> mFormat; 63 sp<DataSource> mDataSource; 64 int32_t mTimescale; 65 sp<SampleTable> mSampleTable; 66 uint32_t mCurrentSampleIndex; 67 68 bool mIsAVC; 69 size_t mNALLengthSize; 70 71 bool mStarted; 72 73 MediaBufferGroup *mGroup; 74 75 MediaBuffer *mBuffer; 76 77 bool mWantsNALFragments; 78 79 uint8_t *mSrcBuffer; 80 81 size_t parseNALSize(const uint8_t *data) const; 82 83 MPEG4Source(const MPEG4Source &); 84 MPEG4Source &operator=(const MPEG4Source &); 85}; 86 87// This custom data source wraps an existing one and satisfies requests 88// falling entirely within a cached range from the cache while forwarding 89// all remaining requests to the wrapped datasource. 90// This is used to cache the full sampletable metadata for a single track, 91// possibly wrapping multiple times to cover all tracks, i.e. 92// Each MPEG4DataSource caches the sampletable metadata for a single track. 93 94struct MPEG4DataSource : public DataSource { 95 MPEG4DataSource(const sp<DataSource> &source); 96 97 virtual status_t initCheck() const; 98 virtual ssize_t readAt(off_t offset, void *data, size_t size); 99 virtual status_t getSize(off_t *size); 100 virtual uint32_t flags(); 101 102 status_t setCachedRange(off_t offset, size_t size); 103 104protected: 105 virtual ~MPEG4DataSource(); 106 107private: 108 Mutex mLock; 109 110 sp<DataSource> mSource; 111 off_t mCachedOffset; 112 size_t mCachedSize; 113 uint8_t *mCache; 114 115 void clearCache(); 116 117 MPEG4DataSource(const MPEG4DataSource &); 118 MPEG4DataSource &operator=(const MPEG4DataSource &); 119}; 120 121MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source) 122 : mSource(source), 123 mCachedOffset(0), 124 mCachedSize(0), 125 mCache(NULL) { 126} 127 128MPEG4DataSource::~MPEG4DataSource() { 129 clearCache(); 130} 131 132void MPEG4DataSource::clearCache() { 133 if (mCache) { 134 free(mCache); 135 mCache = NULL; 136 } 137 138 mCachedOffset = 0; 139 mCachedSize = 0; 140} 141 142status_t MPEG4DataSource::initCheck() const { 143 return mSource->initCheck(); 144} 145 146ssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) { 147 Mutex::Autolock autoLock(mLock); 148 149 if (offset >= mCachedOffset 150 && offset + size <= mCachedOffset + mCachedSize) { 151 memcpy(data, &mCache[offset - mCachedOffset], size); 152 return size; 153 } 154 155 return mSource->readAt(offset, data, size); 156} 157 158status_t MPEG4DataSource::getSize(off_t *size) { 159 return mSource->getSize(size); 160} 161 162uint32_t MPEG4DataSource::flags() { 163 return mSource->flags(); 164} 165 166status_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) { 167 Mutex::Autolock autoLock(mLock); 168 169 clearCache(); 170 171 mCache = (uint8_t *)malloc(size); 172 173 if (mCache == NULL) { 174 return -ENOMEM; 175 } 176 177 mCachedOffset = offset; 178 mCachedSize = size; 179 180 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize); 181 182 if (err < (ssize_t)size) { 183 clearCache(); 184 185 return ERROR_IO; 186 } 187 188 return OK; 189} 190 191//////////////////////////////////////////////////////////////////////////////// 192 193static void hexdump(const void *_data, size_t size) { 194 const uint8_t *data = (const uint8_t *)_data; 195 size_t offset = 0; 196 while (offset < size) { 197 printf("0x%04x ", offset); 198 199 size_t n = size - offset; 200 if (n > 16) { 201 n = 16; 202 } 203 204 for (size_t i = 0; i < 16; ++i) { 205 if (i == 8) { 206 printf(" "); 207 } 208 209 if (offset + i < size) { 210 printf("%02x ", data[offset + i]); 211 } else { 212 printf(" "); 213 } 214 } 215 216 printf(" "); 217 218 for (size_t i = 0; i < n; ++i) { 219 if (isprint(data[offset + i])) { 220 printf("%c", data[offset + i]); 221 } else { 222 printf("."); 223 } 224 } 225 226 printf("\n"); 227 228 offset += 16; 229 } 230} 231 232static const char *FourCC2MIME(uint32_t fourcc) { 233 switch (fourcc) { 234 case FOURCC('m', 'p', '4', 'a'): 235 return MEDIA_MIMETYPE_AUDIO_AAC; 236 237 case FOURCC('s', 'a', 'm', 'r'): 238 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 239 240 case FOURCC('s', 'a', 'w', 'b'): 241 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 242 243 case FOURCC('m', 'p', '4', 'v'): 244 return MEDIA_MIMETYPE_VIDEO_MPEG4; 245 246 case FOURCC('s', '2', '6', '3'): 247 return MEDIA_MIMETYPE_VIDEO_H263; 248 249 case FOURCC('a', 'v', 'c', '1'): 250 return MEDIA_MIMETYPE_VIDEO_AVC; 251 252 default: 253 CHECK(!"should not be here."); 254 return NULL; 255 } 256} 257 258MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 259 : mDataSource(source), 260 mHaveMetadata(false), 261 mHasVideo(false), 262 mFirstTrack(NULL), 263 mLastTrack(NULL), 264 mFileMetaData(new MetaData) { 265} 266 267MPEG4Extractor::~MPEG4Extractor() { 268 Track *track = mFirstTrack; 269 while (track) { 270 Track *next = track->next; 271 272 delete track; 273 track = next; 274 } 275 mFirstTrack = mLastTrack = NULL; 276} 277 278sp<MetaData> MPEG4Extractor::getMetaData() { 279 status_t err; 280 if ((err = readMetaData()) != OK) { 281 return new MetaData; 282 } 283 284 return mFileMetaData; 285} 286 287size_t MPEG4Extractor::countTracks() { 288 status_t err; 289 if ((err = readMetaData()) != OK) { 290 return 0; 291 } 292 293 size_t n = 0; 294 Track *track = mFirstTrack; 295 while (track) { 296 ++n; 297 track = track->next; 298 } 299 300 return n; 301} 302 303sp<MetaData> MPEG4Extractor::getTrackMetaData( 304 size_t index, uint32_t flags) { 305 status_t err; 306 if ((err = readMetaData()) != OK) { 307 return NULL; 308 } 309 310 Track *track = mFirstTrack; 311 while (index > 0) { 312 if (track == NULL) { 313 return NULL; 314 } 315 316 track = track->next; 317 --index; 318 } 319 320 if (track == NULL) { 321 return NULL; 322 } 323 324 if ((flags & kIncludeExtensiveMetaData) 325 && !track->includes_expensive_metadata) { 326 track->includes_expensive_metadata = true; 327 328 const char *mime; 329 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 330 if (!strncasecmp("video/", mime, 6)) { 331 uint32_t sampleIndex; 332 uint32_t sampleTime; 333 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 334 && track->sampleTable->getMetaDataForSample( 335 sampleIndex, NULL /* offset */, NULL /* size */, 336 &sampleTime) == OK) { 337 track->meta->setInt64( 338 kKeyThumbnailTime, 339 ((int64_t)sampleTime * 1000000) / track->timescale); 340 } 341 } 342 } 343 344 return track->meta; 345} 346 347status_t MPEG4Extractor::readMetaData() { 348 if (mHaveMetadata) { 349 return OK; 350 } 351 352 off_t offset = 0; 353 status_t err; 354 while ((err = parseChunk(&offset, 0)) == OK) { 355 } 356 357 if (mHaveMetadata) { 358 if (mHasVideo) { 359 mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 360 } else { 361 mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 362 } 363 364 return OK; 365 } 366 367 return err; 368} 369 370static void MakeFourCCString(uint32_t x, char *s) { 371 s[0] = x >> 24; 372 s[1] = (x >> 16) & 0xff; 373 s[2] = (x >> 8) & 0xff; 374 s[3] = x & 0xff; 375 s[4] = '\0'; 376} 377 378struct PathAdder { 379 PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 380 : mPath(path) { 381 mPath->push(chunkType); 382 } 383 384 ~PathAdder() { 385 mPath->pop(); 386 } 387 388private: 389 Vector<uint32_t> *mPath; 390 391 PathAdder(const PathAdder &); 392 PathAdder &operator=(const PathAdder &); 393}; 394 395static bool underMetaDataPath(const Vector<uint32_t> &path) { 396 return path.size() >= 5 397 && path[0] == FOURCC('m', 'o', 'o', 'v') 398 && path[1] == FOURCC('u', 'd', 't', 'a') 399 && path[2] == FOURCC('m', 'e', 't', 'a') 400 && path[3] == FOURCC('i', 'l', 's', 't'); 401} 402 403// Given a time in seconds since Jan 1 1904, produce a human-readable string. 404static void convertTimeToDate(int64_t time_1904, String8 *s) { 405 time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 406 407 char tmp[32]; 408 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 409 410 s->setTo(tmp); 411} 412 413status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 414 uint32_t hdr[2]; 415 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 416 return ERROR_IO; 417 } 418 uint64_t chunk_size = ntohl(hdr[0]); 419 uint32_t chunk_type = ntohl(hdr[1]); 420 off_t data_offset = *offset + 8; 421 422 if (chunk_size == 1) { 423 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 424 return ERROR_IO; 425 } 426 chunk_size = ntoh64(chunk_size); 427 data_offset += 8; 428 } 429 430 char chunk[5]; 431 MakeFourCCString(chunk_type, chunk); 432 433#if 0 434 static const char kWhitespace[] = " "; 435 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 436 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 437 438 char buffer[256]; 439 if (chunk_size <= sizeof(buffer)) { 440 if (mDataSource->readAt(*offset, buffer, chunk_size) 441 < (ssize_t)chunk_size) { 442 return ERROR_IO; 443 } 444 445 hexdump(buffer, chunk_size); 446 } 447#endif 448 449 PathAdder autoAdder(&mPath, chunk_type); 450 451 off_t chunk_data_size = *offset + chunk_size - data_offset; 452 453 if (chunk_type != FOURCC('c', 'p', 'r', 't') 454 && mPath.size() == 5 && underMetaDataPath(mPath)) { 455 off_t stop_offset = *offset + chunk_size; 456 *offset = data_offset; 457 while (*offset < stop_offset) { 458 status_t err = parseChunk(offset, depth + 1); 459 if (err != OK) { 460 return err; 461 } 462 } 463 CHECK_EQ(*offset, stop_offset); 464 465 return OK; 466 } 467 468 switch(chunk_type) { 469 case FOURCC('m', 'o', 'o', 'v'): 470 case FOURCC('t', 'r', 'a', 'k'): 471 case FOURCC('m', 'd', 'i', 'a'): 472 case FOURCC('m', 'i', 'n', 'f'): 473 case FOURCC('d', 'i', 'n', 'f'): 474 case FOURCC('s', 't', 'b', 'l'): 475 case FOURCC('m', 'v', 'e', 'x'): 476 case FOURCC('m', 'o', 'o', 'f'): 477 case FOURCC('t', 'r', 'a', 'f'): 478 case FOURCC('m', 'f', 'r', 'a'): 479 case FOURCC('s', 'k', 'i' ,'p'): 480 case FOURCC('u', 'd', 't', 'a'): 481 case FOURCC('i', 'l', 's', 't'): 482 { 483 if (chunk_type == FOURCC('s', 't', 'b', 'l')) { 484 LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size); 485 486 if (mDataSource->flags() & DataSource::kWantsPrefetching) { 487 sp<MPEG4DataSource> cachedSource = 488 new MPEG4DataSource(mDataSource); 489 490 if (cachedSource->setCachedRange(*offset, chunk_size) == OK) { 491 mDataSource = cachedSource; 492 } 493 } 494 } 495 496 off_t stop_offset = *offset + chunk_size; 497 *offset = data_offset; 498 while (*offset < stop_offset) { 499 status_t err = parseChunk(offset, depth + 1); 500 if (err != OK) { 501 return err; 502 } 503 } 504 CHECK_EQ(*offset, stop_offset); 505 506 if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 507 mHaveMetadata = true; 508 509 return UNKNOWN_ERROR; // Return a dummy error. 510 } 511 break; 512 } 513 514 case FOURCC('t', 'k', 'h', 'd'): 515 { 516 CHECK(chunk_data_size >= 4); 517 518 uint8_t version; 519 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 520 return ERROR_IO; 521 } 522 523 uint64_t ctime, mtime, duration; 524 int32_t id; 525 uint32_t width, height; 526 527 if (version == 1) { 528 if (chunk_data_size != 36 + 60) { 529 return ERROR_MALFORMED; 530 } 531 532 uint8_t buffer[36 + 60]; 533 if (mDataSource->readAt( 534 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 535 return ERROR_IO; 536 } 537 538 ctime = U64_AT(&buffer[4]); 539 mtime = U64_AT(&buffer[12]); 540 id = U32_AT(&buffer[20]); 541 duration = U64_AT(&buffer[28]); 542 width = U32_AT(&buffer[88]); 543 height = U32_AT(&buffer[92]); 544 } else if (version == 0) { 545 if (chunk_data_size != 24 + 60) { 546 return ERROR_MALFORMED; 547 } 548 549 uint8_t buffer[24 + 60]; 550 if (mDataSource->readAt( 551 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 552 return ERROR_IO; 553 } 554 ctime = U32_AT(&buffer[4]); 555 mtime = U32_AT(&buffer[8]); 556 id = U32_AT(&buffer[12]); 557 duration = U32_AT(&buffer[20]); 558 width = U32_AT(&buffer[76]); 559 height = U32_AT(&buffer[80]); 560 } 561 562 Track *track = new Track; 563 track->next = NULL; 564 if (mLastTrack) { 565 mLastTrack->next = track; 566 } else { 567 mFirstTrack = track; 568 } 569 mLastTrack = track; 570 571 track->meta = new MetaData; 572 track->includes_expensive_metadata = false; 573 track->timescale = 0; 574 track->sampleTable = new SampleTable(mDataSource); 575 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 576 577 *offset += chunk_size; 578 break; 579 } 580 581 case FOURCC('m', 'd', 'h', 'd'): 582 { 583 if (chunk_data_size < 4) { 584 return ERROR_MALFORMED; 585 } 586 587 uint8_t version; 588 if (mDataSource->readAt( 589 data_offset, &version, sizeof(version)) 590 < (ssize_t)sizeof(version)) { 591 return ERROR_IO; 592 } 593 594 off_t timescale_offset; 595 596 if (version == 1) { 597 timescale_offset = data_offset + 4 + 16; 598 } else if (version == 0) { 599 timescale_offset = data_offset + 4 + 8; 600 } else { 601 return ERROR_IO; 602 } 603 604 uint32_t timescale; 605 if (mDataSource->readAt( 606 timescale_offset, ×cale, sizeof(timescale)) 607 < (ssize_t)sizeof(timescale)) { 608 return ERROR_IO; 609 } 610 611 mLastTrack->timescale = ntohl(timescale); 612 613 int64_t duration; 614 if (version == 1) { 615 if (mDataSource->readAt( 616 timescale_offset + 4, &duration, sizeof(duration)) 617 < (ssize_t)sizeof(duration)) { 618 return ERROR_IO; 619 } 620 duration = ntoh64(duration); 621 } else { 622 int32_t duration32; 623 if (mDataSource->readAt( 624 timescale_offset + 4, &duration32, sizeof(duration32)) 625 < (ssize_t)sizeof(duration32)) { 626 return ERROR_IO; 627 } 628 duration = ntohl(duration32); 629 } 630 mLastTrack->meta->setInt64( 631 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 632 633 *offset += chunk_size; 634 break; 635 } 636 637 case FOURCC('h', 'd', 'l', 'r'): 638 { 639 if (chunk_data_size < 25) { 640 return ERROR_MALFORMED; 641 } 642 643 uint8_t buffer[24]; 644 if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 645 return ERROR_IO; 646 } 647 648 if (U32_AT(buffer) != 0) { 649 // Should be version 0, flags 0. 650 return ERROR_MALFORMED; 651 } 652 653 if (U32_AT(&buffer[4]) != 0) { 654 // pre_defined should be 0. 655 return ERROR_MALFORMED; 656 } 657 658 mHandlerType = U32_AT(&buffer[8]); 659 *offset += chunk_size; 660 break; 661 } 662 663 case FOURCC('s', 't', 's', 'd'): 664 { 665 if (chunk_data_size < 8) { 666 return ERROR_MALFORMED; 667 } 668 669 uint8_t buffer[8]; 670 CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 671 if (mDataSource->readAt( 672 data_offset, buffer, 8) < 8) { 673 return ERROR_IO; 674 } 675 676 if (U32_AT(buffer) != 0) { 677 // Should be version 0, flags 0. 678 return ERROR_MALFORMED; 679 } 680 681 uint32_t entry_count = U32_AT(&buffer[4]); 682 683 if (entry_count > 1) { 684 // For now we only support a single type of media per track. 685 return ERROR_UNSUPPORTED; 686 } 687 688 off_t stop_offset = *offset + chunk_size; 689 *offset = data_offset + 8; 690 for (uint32_t i = 0; i < entry_count; ++i) { 691 status_t err = parseChunk(offset, depth + 1); 692 if (err != OK) { 693 return err; 694 } 695 } 696 CHECK_EQ(*offset, stop_offset); 697 break; 698 } 699 700 case FOURCC('m', 'p', '4', 'a'): 701 case FOURCC('s', 'a', 'm', 'r'): 702 case FOURCC('s', 'a', 'w', 'b'): 703 { 704 if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 705 return ERROR_MALFORMED; 706 } 707 708 uint8_t buffer[8 + 20]; 709 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 710 // Basic AudioSampleEntry size. 711 return ERROR_MALFORMED; 712 } 713 714 if (mDataSource->readAt( 715 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 716 return ERROR_IO; 717 } 718 719 uint16_t data_ref_index = U16_AT(&buffer[6]); 720 uint16_t num_channels = U16_AT(&buffer[16]); 721 722 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 723 FourCC2MIME(chunk_type)) 724 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 725 FourCC2MIME(chunk_type))) { 726 // AMR audio is always mono. 727 num_channels = 1; 728 } 729 730 uint16_t sample_size = U16_AT(&buffer[18]); 731 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 732 733 // printf("*** coding='%s' %d channels, size %d, rate %d\n", 734 // chunk, num_channels, sample_size, sample_rate); 735 736 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 737 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 738 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 739 740 off_t stop_offset = *offset + chunk_size; 741 *offset = data_offset + sizeof(buffer); 742 while (*offset < stop_offset) { 743 status_t err = parseChunk(offset, depth + 1); 744 if (err != OK) { 745 return err; 746 } 747 } 748 CHECK_EQ(*offset, stop_offset); 749 break; 750 } 751 752 case FOURCC('m', 'p', '4', 'v'): 753 case FOURCC('s', '2', '6', '3'): 754 case FOURCC('a', 'v', 'c', '1'): 755 { 756 mHasVideo = true; 757 758 if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 759 return ERROR_MALFORMED; 760 } 761 762 uint8_t buffer[78]; 763 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 764 // Basic VideoSampleEntry size. 765 return ERROR_MALFORMED; 766 } 767 768 if (mDataSource->readAt( 769 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 770 return ERROR_IO; 771 } 772 773 uint16_t data_ref_index = U16_AT(&buffer[6]); 774 uint16_t width = U16_AT(&buffer[6 + 18]); 775 uint16_t height = U16_AT(&buffer[6 + 20]); 776 777 // printf("*** coding='%s' width=%d height=%d\n", 778 // chunk, width, height); 779 780 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 781 mLastTrack->meta->setInt32(kKeyWidth, width); 782 mLastTrack->meta->setInt32(kKeyHeight, height); 783 784 off_t stop_offset = *offset + chunk_size; 785 *offset = data_offset + sizeof(buffer); 786 while (*offset < stop_offset) { 787 status_t err = parseChunk(offset, depth + 1); 788 if (err != OK) { 789 return err; 790 } 791 } 792 CHECK_EQ(*offset, stop_offset); 793 break; 794 } 795 796 case FOURCC('s', 't', 'c', 'o'): 797 case FOURCC('c', 'o', '6', '4'): 798 { 799 status_t err = 800 mLastTrack->sampleTable->setChunkOffsetParams( 801 chunk_type, data_offset, chunk_data_size); 802 803 if (err != OK) { 804 return err; 805 } 806 807 *offset += chunk_size; 808 break; 809 } 810 811 case FOURCC('s', 't', 's', 'c'): 812 { 813 status_t err = 814 mLastTrack->sampleTable->setSampleToChunkParams( 815 data_offset, chunk_data_size); 816 817 if (err != OK) { 818 return err; 819 } 820 821 *offset += chunk_size; 822 break; 823 } 824 825 case FOURCC('s', 't', 's', 'z'): 826 case FOURCC('s', 't', 'z', '2'): 827 { 828 status_t err = 829 mLastTrack->sampleTable->setSampleSizeParams( 830 chunk_type, data_offset, chunk_data_size); 831 832 if (err != OK) { 833 return err; 834 } 835 836 size_t max_size; 837 CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 838 839 // Assume that a given buffer only contains at most 10 fragments, 840 // each fragment originally prefixed with a 2 byte length will 841 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 842 // and thus will grow by 2 bytes per fragment. 843 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 844 845 *offset += chunk_size; 846 break; 847 } 848 849 case FOURCC('s', 't', 't', 's'): 850 { 851 status_t err = 852 mLastTrack->sampleTable->setTimeToSampleParams( 853 data_offset, chunk_data_size); 854 855 if (err != OK) { 856 return err; 857 } 858 859 *offset += chunk_size; 860 break; 861 } 862 863 case FOURCC('s', 't', 's', 's'): 864 { 865 status_t err = 866 mLastTrack->sampleTable->setSyncSampleParams( 867 data_offset, chunk_data_size); 868 869 if (err != OK) { 870 return err; 871 } 872 873 *offset += chunk_size; 874 break; 875 } 876 877 case FOURCC('e', 's', 'd', 's'): 878 { 879 if (chunk_data_size < 4) { 880 return ERROR_MALFORMED; 881 } 882 883 uint8_t buffer[256]; 884 if (chunk_data_size > (off_t)sizeof(buffer)) { 885 return ERROR_BUFFER_TOO_SMALL; 886 } 887 888 if (mDataSource->readAt( 889 data_offset, buffer, chunk_data_size) < chunk_data_size) { 890 return ERROR_IO; 891 } 892 893 if (U32_AT(buffer) != 0) { 894 // Should be version 0, flags 0. 895 return ERROR_MALFORMED; 896 } 897 898 mLastTrack->meta->setData( 899 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 900 901 *offset += chunk_size; 902 break; 903 } 904 905 case FOURCC('a', 'v', 'c', 'C'): 906 { 907 char buffer[256]; 908 if (chunk_data_size > (off_t)sizeof(buffer)) { 909 return ERROR_BUFFER_TOO_SMALL; 910 } 911 912 if (mDataSource->readAt( 913 data_offset, buffer, chunk_data_size) < chunk_data_size) { 914 return ERROR_IO; 915 } 916 917 mLastTrack->meta->setData( 918 kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 919 920 *offset += chunk_size; 921 break; 922 } 923 924 case FOURCC('m', 'e', 't', 'a'): 925 { 926 uint8_t buffer[4]; 927 CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 928 if (mDataSource->readAt( 929 data_offset, buffer, 4) < 4) { 930 return ERROR_IO; 931 } 932 933 if (U32_AT(buffer) != 0) { 934 // Should be version 0, flags 0. 935 return ERROR_MALFORMED; 936 } 937 938 off_t stop_offset = *offset + chunk_size; 939 *offset = data_offset + sizeof(buffer); 940 while (*offset < stop_offset) { 941 status_t err = parseChunk(offset, depth + 1); 942 if (err != OK) { 943 return err; 944 } 945 } 946 CHECK_EQ(*offset, stop_offset); 947 break; 948 } 949 950 case FOURCC('d', 'a', 't', 'a'): 951 { 952 if (mPath.size() == 6 && underMetaDataPath(mPath)) { 953 status_t err = parseMetaData(data_offset, chunk_data_size); 954 955 if (err != OK) { 956 return err; 957 } 958 } 959 960 *offset += chunk_size; 961 break; 962 } 963 964 case FOURCC('m', 'v', 'h', 'd'): 965 { 966 if (chunk_data_size < 12) { 967 return ERROR_MALFORMED; 968 } 969 970 uint8_t header[12]; 971 if (mDataSource->readAt( 972 data_offset, header, sizeof(header)) 973 < (ssize_t)sizeof(header)) { 974 return ERROR_IO; 975 } 976 977 int64_t creationTime; 978 if (header[0] == 1) { 979 creationTime = U64_AT(&header[4]); 980 } else { 981 CHECK_EQ(header[0], 0); 982 creationTime = U32_AT(&header[4]); 983 } 984 985 String8 s; 986 convertTimeToDate(creationTime, &s); 987 988 mFileMetaData->setCString(kKeyDate, s.string()); 989 990 *offset += chunk_size; 991 break; 992 } 993 994 default: 995 { 996 *offset += chunk_size; 997 break; 998 } 999 } 1000 1001 return OK; 1002} 1003 1004status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 1005 if (size < 4) { 1006 return ERROR_MALFORMED; 1007 } 1008 1009 uint8_t *buffer = new uint8_t[size + 1]; 1010 if (mDataSource->readAt( 1011 offset, buffer, size) != (ssize_t)size) { 1012 delete[] buffer; 1013 buffer = NULL; 1014 1015 return ERROR_IO; 1016 } 1017 1018 uint32_t flags = U32_AT(buffer); 1019 1020 uint32_t metadataKey = 0; 1021 switch (mPath[4]) { 1022 case FOURCC(0xa9, 'a', 'l', 'b'): 1023 { 1024 metadataKey = kKeyAlbum; 1025 break; 1026 } 1027 case FOURCC(0xa9, 'A', 'R', 'T'): 1028 { 1029 metadataKey = kKeyArtist; 1030 break; 1031 } 1032 case FOURCC(0xa9, 'd', 'a', 'y'): 1033 { 1034 metadataKey = kKeyYear; 1035 break; 1036 } 1037 case FOURCC(0xa9, 'n', 'a', 'm'): 1038 { 1039 metadataKey = kKeyTitle; 1040 break; 1041 } 1042 case FOURCC(0xa9, 'w', 'r', 't'): 1043 { 1044 metadataKey = kKeyWriter; 1045 break; 1046 } 1047 case FOURCC('c', 'o', 'v', 'r'): 1048 { 1049 metadataKey = kKeyAlbumArt; 1050 break; 1051 } 1052 case FOURCC('g', 'n', 'r', 'e'): 1053 { 1054 metadataKey = kKeyGenre; 1055 break; 1056 } 1057 case FOURCC('t', 'r', 'k', 'n'): 1058 { 1059 if (size == 16 && flags == 0) { 1060 char tmp[16]; 1061 sprintf(tmp, "%d/%d", 1062 (int)buffer[size - 5], (int)buffer[size - 3]); 1063 1064 printf("track: %s\n", tmp); 1065 mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 1066 } 1067 break; 1068 } 1069 default: 1070 break; 1071 } 1072 1073 if (size >= 8 && metadataKey) { 1074 if (metadataKey == kKeyAlbumArt) { 1075 mFileMetaData->setData( 1076 kKeyAlbumArt, MetaData::TYPE_NONE, 1077 buffer + 8, size - 8); 1078 } else if (metadataKey == kKeyGenre) { 1079 if (flags == 0) { 1080 // uint8_t 1081 char genre[10]; 1082 sprintf(genre, "%d", (int)buffer[size - 1]); 1083 1084 mFileMetaData->setCString(metadataKey, genre); 1085 } 1086 } else { 1087 buffer[size] = '\0'; 1088 1089 mFileMetaData->setCString( 1090 metadataKey, (const char *)buffer + 8); 1091 } 1092 } 1093 1094 delete[] buffer; 1095 buffer = NULL; 1096 1097 return OK; 1098} 1099 1100sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 1101 status_t err; 1102 if ((err = readMetaData()) != OK) { 1103 return NULL; 1104 } 1105 1106 Track *track = mFirstTrack; 1107 while (index > 0) { 1108 if (track == NULL) { 1109 return NULL; 1110 } 1111 1112 track = track->next; 1113 --index; 1114 } 1115 1116 if (track == NULL) { 1117 return NULL; 1118 } 1119 1120 return new MPEG4Source( 1121 track->meta, mDataSource, track->timescale, track->sampleTable); 1122} 1123 1124//////////////////////////////////////////////////////////////////////////////// 1125 1126MPEG4Source::MPEG4Source( 1127 const sp<MetaData> &format, 1128 const sp<DataSource> &dataSource, 1129 int32_t timeScale, 1130 const sp<SampleTable> &sampleTable) 1131 : mFormat(format), 1132 mDataSource(dataSource), 1133 mTimescale(timeScale), 1134 mSampleTable(sampleTable), 1135 mCurrentSampleIndex(0), 1136 mIsAVC(false), 1137 mNALLengthSize(0), 1138 mStarted(false), 1139 mGroup(NULL), 1140 mBuffer(NULL), 1141 mWantsNALFragments(false), 1142 mSrcBuffer(NULL) { 1143 const char *mime; 1144 bool success = mFormat->findCString(kKeyMIMEType, &mime); 1145 CHECK(success); 1146 1147 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 1148 1149 if (mIsAVC) { 1150 uint32_t type; 1151 const void *data; 1152 size_t size; 1153 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 1154 1155 const uint8_t *ptr = (const uint8_t *)data; 1156 1157 CHECK(size >= 7); 1158 CHECK_EQ(ptr[0], 1); // configurationVersion == 1 1159 1160 // The number of bytes used to encode the length of a NAL unit. 1161 mNALLengthSize = 1 + (ptr[4] & 3); 1162 } 1163} 1164 1165MPEG4Source::~MPEG4Source() { 1166 if (mStarted) { 1167 stop(); 1168 } 1169} 1170 1171status_t MPEG4Source::start(MetaData *params) { 1172 CHECK(!mStarted); 1173 1174 int32_t val; 1175 if (params && params->findInt32(kKeyWantsNALFragments, &val) 1176 && val != 0) { 1177 mWantsNALFragments = true; 1178 } else { 1179 mWantsNALFragments = false; 1180 } 1181 1182 mGroup = new MediaBufferGroup; 1183 1184 int32_t max_size; 1185 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 1186 1187 mGroup->add_buffer(new MediaBuffer(max_size)); 1188 1189 mSrcBuffer = new uint8_t[max_size]; 1190 1191 mStarted = true; 1192 1193 return OK; 1194} 1195 1196status_t MPEG4Source::stop() { 1197 CHECK(mStarted); 1198 1199 if (mBuffer != NULL) { 1200 mBuffer->release(); 1201 mBuffer = NULL; 1202 } 1203 1204 delete[] mSrcBuffer; 1205 mSrcBuffer = NULL; 1206 1207 delete mGroup; 1208 mGroup = NULL; 1209 1210 mStarted = false; 1211 mCurrentSampleIndex = 0; 1212 1213 return OK; 1214} 1215 1216sp<MetaData> MPEG4Source::getFormat() { 1217 return mFormat; 1218} 1219 1220size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 1221 switch (mNALLengthSize) { 1222 case 1: 1223 return *data; 1224 case 2: 1225 return U16_AT(data); 1226 case 3: 1227 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 1228 case 4: 1229 return U32_AT(data); 1230 } 1231 1232 // This cannot happen, mNALLengthSize springs to life by adding 1 to 1233 // a 2-bit integer. 1234 CHECK(!"Should not be here."); 1235 1236 return 0; 1237} 1238 1239status_t MPEG4Source::read( 1240 MediaBuffer **out, const ReadOptions *options) { 1241 CHECK(mStarted); 1242 1243 *out = NULL; 1244 1245 int64_t seekTimeUs; 1246 if (options && options->getSeekTo(&seekTimeUs)) { 1247 uint32_t sampleIndex; 1248 status_t err = mSampleTable->findClosestSample( 1249 seekTimeUs * mTimescale / 1000000, 1250 &sampleIndex, SampleTable::kSyncSample_Flag); 1251 1252 if (err != OK) { 1253 return err; 1254 } 1255 1256 mCurrentSampleIndex = sampleIndex; 1257 if (mBuffer != NULL) { 1258 mBuffer->release(); 1259 mBuffer = NULL; 1260 } 1261 1262 // fall through 1263 } 1264 1265 off_t offset; 1266 size_t size; 1267 uint32_t dts; 1268 bool newBuffer = false; 1269 if (mBuffer == NULL) { 1270 newBuffer = true; 1271 1272 status_t err = 1273 mSampleTable->getMetaDataForSample( 1274 mCurrentSampleIndex, &offset, &size, &dts); 1275 1276 if (err != OK) { 1277 return err; 1278 } 1279 1280 err = mGroup->acquire_buffer(&mBuffer); 1281 1282 if (err != OK) { 1283 CHECK_EQ(mBuffer, NULL); 1284 return err; 1285 } 1286 } 1287 1288 if (!mIsAVC || mWantsNALFragments) { 1289 if (newBuffer) { 1290 ssize_t num_bytes_read = 1291 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1292 1293 if (num_bytes_read < (ssize_t)size) { 1294 mBuffer->release(); 1295 mBuffer = NULL; 1296 1297 return ERROR_IO; 1298 } 1299 1300 mBuffer->set_range(0, size); 1301 mBuffer->meta_data()->clear(); 1302 mBuffer->meta_data()->setInt64( 1303 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1304 ++mCurrentSampleIndex; 1305 } 1306 1307 if (!mIsAVC) { 1308 *out = mBuffer; 1309 mBuffer = NULL; 1310 1311 return OK; 1312 } 1313 1314 // Each NAL unit is split up into its constituent fragments and 1315 // each one of them returned in its own buffer. 1316 1317 CHECK(mBuffer->range_length() >= mNALLengthSize); 1318 1319 const uint8_t *src = 1320 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1321 1322 size_t nal_size = parseNALSize(src); 1323 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1324 LOGE("incomplete NAL unit."); 1325 1326 mBuffer->release(); 1327 mBuffer = NULL; 1328 1329 return ERROR_MALFORMED; 1330 } 1331 1332 MediaBuffer *clone = mBuffer->clone(); 1333 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1334 1335 mBuffer->set_range( 1336 mBuffer->range_offset() + mNALLengthSize + nal_size, 1337 mBuffer->range_length() - mNALLengthSize - nal_size); 1338 1339 if (mBuffer->range_length() == 0) { 1340 mBuffer->release(); 1341 mBuffer = NULL; 1342 } 1343 1344 *out = clone; 1345 1346 return OK; 1347 } else { 1348 // Whole NAL units are returned but each fragment is prefixed by 1349 // the start code (0x00 00 00 01). 1350 1351 ssize_t num_bytes_read = 1352 mDataSource->readAt(offset, mSrcBuffer, size); 1353 1354 if (num_bytes_read < (ssize_t)size) { 1355 mBuffer->release(); 1356 mBuffer = NULL; 1357 1358 return ERROR_IO; 1359 } 1360 1361 uint8_t *dstData = (uint8_t *)mBuffer->data(); 1362 size_t srcOffset = 0; 1363 size_t dstOffset = 0; 1364 1365 while (srcOffset < size) { 1366 CHECK(srcOffset + mNALLengthSize <= size); 1367 size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1368 srcOffset += mNALLengthSize; 1369 1370 if (srcOffset + nalLength > size) { 1371 mBuffer->release(); 1372 mBuffer = NULL; 1373 1374 return ERROR_MALFORMED; 1375 } 1376 1377 if (nalLength == 0) { 1378 continue; 1379 } 1380 1381 CHECK(dstOffset + 4 <= mBuffer->size()); 1382 1383 dstData[dstOffset++] = 0; 1384 dstData[dstOffset++] = 0; 1385 dstData[dstOffset++] = 0; 1386 dstData[dstOffset++] = 1; 1387 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1388 srcOffset += nalLength; 1389 dstOffset += nalLength; 1390 } 1391 CHECK_EQ(srcOffset, size); 1392 1393 mBuffer->set_range(0, dstOffset); 1394 mBuffer->meta_data()->clear(); 1395 mBuffer->meta_data()->setInt64( 1396 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1397 ++mCurrentSampleIndex; 1398 1399 *out = mBuffer; 1400 mBuffer = NULL; 1401 1402 return OK; 1403 } 1404} 1405 1406bool SniffMPEG4( 1407 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1408 uint8_t header[8]; 1409 1410 ssize_t n = source->readAt(4, header, sizeof(header)); 1411 if (n < (ssize_t)sizeof(header)) { 1412 return false; 1413 } 1414 1415 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1416 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 1417 || !memcmp(header, "ftypM4A ", 8)) { 1418 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1419 *confidence = 0.1; 1420 1421 return true; 1422 } 1423 1424 return false; 1425} 1426 1427} // namespace android 1428 1429