MPEG4Extractor.cpp revision 909255a9cf425534e4a8b582a320686852dc59dc
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 87static void hexdump(const void *_data, size_t size) { 88 const uint8_t *data = (const uint8_t *)_data; 89 size_t offset = 0; 90 while (offset < size) { 91 printf("0x%04x ", offset); 92 93 size_t n = size - offset; 94 if (n > 16) { 95 n = 16; 96 } 97 98 for (size_t i = 0; i < 16; ++i) { 99 if (i == 8) { 100 printf(" "); 101 } 102 103 if (offset + i < size) { 104 printf("%02x ", data[offset + i]); 105 } else { 106 printf(" "); 107 } 108 } 109 110 printf(" "); 111 112 for (size_t i = 0; i < n; ++i) { 113 if (isprint(data[offset + i])) { 114 printf("%c", data[offset + i]); 115 } else { 116 printf("."); 117 } 118 } 119 120 printf("\n"); 121 122 offset += 16; 123 } 124} 125 126static const char *FourCC2MIME(uint32_t fourcc) { 127 switch (fourcc) { 128 case FOURCC('m', 'p', '4', 'a'): 129 return MEDIA_MIMETYPE_AUDIO_AAC; 130 131 case FOURCC('s', 'a', 'm', 'r'): 132 return MEDIA_MIMETYPE_AUDIO_AMR_NB; 133 134 case FOURCC('s', 'a', 'w', 'b'): 135 return MEDIA_MIMETYPE_AUDIO_AMR_WB; 136 137 case FOURCC('m', 'p', '4', 'v'): 138 return MEDIA_MIMETYPE_VIDEO_MPEG4; 139 140 case FOURCC('s', '2', '6', '3'): 141 return MEDIA_MIMETYPE_VIDEO_H263; 142 143 case FOURCC('a', 'v', 'c', '1'): 144 return MEDIA_MIMETYPE_VIDEO_AVC; 145 146 default: 147 CHECK(!"should not be here."); 148 return NULL; 149 } 150} 151 152MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 153 : mDataSource(source), 154 mHaveMetadata(false), 155 mHasVideo(false), 156 mFirstTrack(NULL), 157 mLastTrack(NULL) { 158} 159 160MPEG4Extractor::~MPEG4Extractor() { 161 Track *track = mFirstTrack; 162 while (track) { 163 Track *next = track->next; 164 165 delete track; 166 track = next; 167 } 168 mFirstTrack = mLastTrack = NULL; 169} 170 171sp<MetaData> MPEG4Extractor::getMetaData() { 172 sp<MetaData> meta = new MetaData; 173 174 status_t err; 175 if ((err = readMetaData()) != OK) { 176 return meta; 177 } 178 179 if (mHasVideo) { 180 meta->setCString(kKeyMIMEType, "video/mp4"); 181 } else { 182 meta->setCString(kKeyMIMEType, "audio/mp4"); 183 } 184 185 return meta; 186} 187 188size_t MPEG4Extractor::countTracks() { 189 status_t err; 190 if ((err = readMetaData()) != OK) { 191 return 0; 192 } 193 194 size_t n = 0; 195 Track *track = mFirstTrack; 196 while (track) { 197 ++n; 198 track = track->next; 199 } 200 201 return n; 202} 203 204sp<MetaData> MPEG4Extractor::getTrackMetaData( 205 size_t index, uint32_t flags) { 206 status_t err; 207 if ((err = readMetaData()) != OK) { 208 return NULL; 209 } 210 211 Track *track = mFirstTrack; 212 while (index > 0) { 213 if (track == NULL) { 214 return NULL; 215 } 216 217 track = track->next; 218 --index; 219 } 220 221 if (track == NULL) { 222 return NULL; 223 } 224 225 if ((flags & kIncludeExtensiveMetaData) 226 && !track->includes_expensive_metadata) { 227 track->includes_expensive_metadata = true; 228 229 const char *mime; 230 CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 231 if (!strncasecmp("video/", mime, 6)) { 232 uint32_t sampleIndex; 233 uint32_t sampleTime; 234 if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 235 && track->sampleTable->getDecodingTime( 236 sampleIndex, &sampleTime) == OK) { 237 track->meta->setInt64( 238 kKeyThumbnailTime, 239 ((int64_t)sampleTime * 1000000) / track->timescale); 240 } 241 } 242 } 243 244 return track->meta; 245} 246 247status_t MPEG4Extractor::readMetaData() { 248 if (mHaveMetadata) { 249 return OK; 250 } 251 252 off_t offset = 0; 253 status_t err; 254 while ((err = parseChunk(&offset, 0)) == OK) { 255 } 256 257 if (mHaveMetadata) { 258 return OK; 259 } 260 261 return err; 262} 263 264static void MakeFourCCString(uint32_t x, char *s) { 265 s[0] = x >> 24; 266 s[1] = (x >> 16) & 0xff; 267 s[2] = (x >> 8) & 0xff; 268 s[3] = x & 0xff; 269 s[4] = '\0'; 270} 271 272status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 273 uint32_t hdr[2]; 274 if (mDataSource->readAt(*offset, hdr, 8) < 8) { 275 return ERROR_IO; 276 } 277 uint64_t chunk_size = ntohl(hdr[0]); 278 uint32_t chunk_type = ntohl(hdr[1]); 279 off_t data_offset = *offset + 8; 280 281 if (chunk_size == 1) { 282 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 283 return ERROR_IO; 284 } 285 chunk_size = ntoh64(chunk_size); 286 data_offset += 8; 287 } 288 289 char chunk[5]; 290 MakeFourCCString(chunk_type, chunk); 291 292#if 0 293 static const char kWhitespace[] = " "; 294 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 295 printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 296 297 char buffer[256]; 298 if (chunk_size <= sizeof(buffer)) { 299 if (mDataSource->readAt(*offset, buffer, chunk_size) < chunk_size) { 300 return ERROR_IO; 301 } 302 303 hexdump(buffer, chunk_size); 304 } 305#endif 306 307 off_t chunk_data_size = *offset + chunk_size - data_offset; 308 309 switch(chunk_type) { 310 case FOURCC('m', 'o', 'o', 'v'): 311 case FOURCC('t', 'r', 'a', 'k'): 312 case FOURCC('m', 'd', 'i', 'a'): 313 case FOURCC('m', 'i', 'n', 'f'): 314 case FOURCC('d', 'i', 'n', 'f'): 315 case FOURCC('s', 't', 'b', 'l'): 316 case FOURCC('m', 'v', 'e', 'x'): 317 case FOURCC('m', 'o', 'o', 'f'): 318 case FOURCC('t', 'r', 'a', 'f'): 319 case FOURCC('m', 'f', 'r', 'a'): 320 case FOURCC('s', 'k', 'i' ,'p'): 321 { 322 off_t stop_offset = *offset + chunk_size; 323 *offset = data_offset; 324 while (*offset < stop_offset) { 325 status_t err = parseChunk(offset, depth + 1); 326 if (err != OK) { 327 return err; 328 } 329 } 330 CHECK_EQ(*offset, stop_offset); 331 332 if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 333 mHaveMetadata = true; 334 335 return UNKNOWN_ERROR; // Return a dummy error. 336 } 337 break; 338 } 339 340 case FOURCC('t', 'k', 'h', 'd'): 341 { 342 CHECK(chunk_data_size >= 4); 343 344 uint8_t version; 345 if (mDataSource->readAt(data_offset, &version, 1) < 1) { 346 return ERROR_IO; 347 } 348 349 uint64_t ctime, mtime, duration; 350 int32_t id; 351 uint32_t width, height; 352 353 if (version == 1) { 354 if (chunk_data_size != 36 + 60) { 355 return ERROR_MALFORMED; 356 } 357 358 uint8_t buffer[36 + 60]; 359 if (mDataSource->readAt( 360 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 361 return ERROR_IO; 362 } 363 364 ctime = U64_AT(&buffer[4]); 365 mtime = U64_AT(&buffer[12]); 366 id = U32_AT(&buffer[20]); 367 duration = U64_AT(&buffer[28]); 368 width = U32_AT(&buffer[88]); 369 height = U32_AT(&buffer[92]); 370 } else if (version == 0) { 371 if (chunk_data_size != 24 + 60) { 372 return ERROR_MALFORMED; 373 } 374 375 uint8_t buffer[24 + 60]; 376 if (mDataSource->readAt( 377 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 378 return ERROR_IO; 379 } 380 ctime = U32_AT(&buffer[4]); 381 mtime = U32_AT(&buffer[8]); 382 id = U32_AT(&buffer[12]); 383 duration = U32_AT(&buffer[20]); 384 width = U32_AT(&buffer[76]); 385 height = U32_AT(&buffer[80]); 386 } 387 388 Track *track = new Track; 389 track->next = NULL; 390 if (mLastTrack) { 391 mLastTrack->next = track; 392 } else { 393 mFirstTrack = track; 394 } 395 mLastTrack = track; 396 397 track->meta = new MetaData; 398 track->includes_expensive_metadata = false; 399 track->timescale = 0; 400 track->sampleTable = new SampleTable(mDataSource); 401 track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 402 403 *offset += chunk_size; 404 break; 405 } 406 407 case FOURCC('m', 'd', 'h', 'd'): 408 { 409 if (chunk_data_size < 4) { 410 return ERROR_MALFORMED; 411 } 412 413 uint8_t version; 414 if (mDataSource->readAt( 415 data_offset, &version, sizeof(version)) 416 < (ssize_t)sizeof(version)) { 417 return ERROR_IO; 418 } 419 420 off_t timescale_offset; 421 422 if (version == 1) { 423 timescale_offset = data_offset + 4 + 16; 424 } else if (version == 0) { 425 timescale_offset = data_offset + 4 + 8; 426 } else { 427 return ERROR_IO; 428 } 429 430 uint32_t timescale; 431 if (mDataSource->readAt( 432 timescale_offset, ×cale, sizeof(timescale)) 433 < (ssize_t)sizeof(timescale)) { 434 return ERROR_IO; 435 } 436 437 mLastTrack->timescale = ntohl(timescale); 438 439 int64_t duration; 440 if (version == 1) { 441 if (mDataSource->readAt( 442 timescale_offset + 4, &duration, sizeof(duration)) 443 < (ssize_t)sizeof(duration)) { 444 return ERROR_IO; 445 } 446 duration = ntoh64(duration); 447 } else { 448 int32_t duration32; 449 if (mDataSource->readAt( 450 timescale_offset + 4, &duration32, sizeof(duration32)) 451 < (ssize_t)sizeof(duration32)) { 452 return ERROR_IO; 453 } 454 duration = ntohl(duration32); 455 } 456 mLastTrack->meta->setInt64( 457 kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 458 459 *offset += chunk_size; 460 break; 461 } 462 463 case FOURCC('h', 'd', 'l', 'r'): 464 { 465 if (chunk_data_size < 25) { 466 return ERROR_MALFORMED; 467 } 468 469 uint8_t buffer[24]; 470 if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 471 return ERROR_IO; 472 } 473 474 if (U32_AT(buffer) != 0) { 475 // Should be version 0, flags 0. 476 return ERROR_MALFORMED; 477 } 478 479 if (U32_AT(&buffer[4]) != 0) { 480 // pre_defined should be 0. 481 return ERROR_MALFORMED; 482 } 483 484 mHandlerType = U32_AT(&buffer[8]); 485 *offset += chunk_size; 486 break; 487 } 488 489 case FOURCC('s', 't', 's', 'd'): 490 { 491 if (chunk_data_size < 8) { 492 return ERROR_MALFORMED; 493 } 494 495 uint8_t buffer[8]; 496 CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 497 if (mDataSource->readAt( 498 data_offset, buffer, 8) < 8) { 499 return ERROR_IO; 500 } 501 502 if (U32_AT(buffer) != 0) { 503 // Should be version 0, flags 0. 504 return ERROR_MALFORMED; 505 } 506 507 uint32_t entry_count = U32_AT(&buffer[4]); 508 509 if (entry_count > 1) { 510 // For now we only support a single type of media per track. 511 return ERROR_UNSUPPORTED; 512 } 513 514 off_t stop_offset = *offset + chunk_size; 515 *offset = data_offset + 8; 516 for (uint32_t i = 0; i < entry_count; ++i) { 517 status_t err = parseChunk(offset, depth + 1); 518 if (err != OK) { 519 return err; 520 } 521 } 522 CHECK_EQ(*offset, stop_offset); 523 break; 524 } 525 526 case FOURCC('m', 'p', '4', 'a'): 527 case FOURCC('s', 'a', 'm', 'r'): 528 case FOURCC('s', 'a', 'w', 'b'): 529 { 530 if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 531 return ERROR_MALFORMED; 532 } 533 534 uint8_t buffer[8 + 20]; 535 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 536 // Basic AudioSampleEntry size. 537 return ERROR_MALFORMED; 538 } 539 540 if (mDataSource->readAt( 541 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 542 return ERROR_IO; 543 } 544 545 uint16_t data_ref_index = U16_AT(&buffer[6]); 546 uint16_t num_channels = U16_AT(&buffer[16]); 547 548 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 549 FourCC2MIME(chunk_type)) 550 || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 551 FourCC2MIME(chunk_type))) { 552 // AMR audio is always mono. 553 num_channels = 1; 554 } 555 556 uint16_t sample_size = U16_AT(&buffer[18]); 557 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 558 559 // printf("*** coding='%s' %d channels, size %d, rate %d\n", 560 // chunk, num_channels, sample_size, sample_rate); 561 562 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 563 mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 564 mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 565 566 off_t stop_offset = *offset + chunk_size; 567 *offset = data_offset + sizeof(buffer); 568 while (*offset < stop_offset) { 569 status_t err = parseChunk(offset, depth + 1); 570 if (err != OK) { 571 return err; 572 } 573 } 574 CHECK_EQ(*offset, stop_offset); 575 break; 576 } 577 578 case FOURCC('m', 'p', '4', 'v'): 579 case FOURCC('s', '2', '6', '3'): 580 case FOURCC('a', 'v', 'c', '1'): 581 { 582 mHasVideo = true; 583 584 if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 585 return ERROR_MALFORMED; 586 } 587 588 uint8_t buffer[78]; 589 if (chunk_data_size < (ssize_t)sizeof(buffer)) { 590 // Basic VideoSampleEntry size. 591 return ERROR_MALFORMED; 592 } 593 594 if (mDataSource->readAt( 595 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 596 return ERROR_IO; 597 } 598 599 uint16_t data_ref_index = U16_AT(&buffer[6]); 600 uint16_t width = U16_AT(&buffer[6 + 18]); 601 uint16_t height = U16_AT(&buffer[6 + 20]); 602 603 // printf("*** coding='%s' width=%d height=%d\n", 604 // chunk, width, height); 605 606 mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 607 mLastTrack->meta->setInt32(kKeyWidth, width); 608 mLastTrack->meta->setInt32(kKeyHeight, height); 609 610 off_t stop_offset = *offset + chunk_size; 611 *offset = data_offset + sizeof(buffer); 612 while (*offset < stop_offset) { 613 status_t err = parseChunk(offset, depth + 1); 614 if (err != OK) { 615 return err; 616 } 617 } 618 CHECK_EQ(*offset, stop_offset); 619 break; 620 } 621 622 case FOURCC('s', 't', 'c', 'o'): 623 case FOURCC('c', 'o', '6', '4'): 624 { 625 status_t err = 626 mLastTrack->sampleTable->setChunkOffsetParams( 627 chunk_type, data_offset, chunk_data_size); 628 629 if (err != OK) { 630 return err; 631 } 632 633 *offset += chunk_size; 634 break; 635 } 636 637 case FOURCC('s', 't', 's', 'c'): 638 { 639 status_t err = 640 mLastTrack->sampleTable->setSampleToChunkParams( 641 data_offset, chunk_data_size); 642 643 if (err != OK) { 644 return err; 645 } 646 647 *offset += chunk_size; 648 break; 649 } 650 651 case FOURCC('s', 't', 's', 'z'): 652 case FOURCC('s', 't', 'z', '2'): 653 { 654 status_t err = 655 mLastTrack->sampleTable->setSampleSizeParams( 656 chunk_type, data_offset, chunk_data_size); 657 658 if (err != OK) { 659 return err; 660 } 661 662 size_t max_size; 663 CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 664 665 // Assume that a given buffer only contains at most 10 fragments, 666 // each fragment originally prefixed with a 2 byte length will 667 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 668 // and thus will grow by 2 bytes per fragment. 669 mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 670 671 *offset += chunk_size; 672 break; 673 } 674 675 case FOURCC('s', 't', 't', 's'): 676 { 677 status_t err = 678 mLastTrack->sampleTable->setTimeToSampleParams( 679 data_offset, chunk_data_size); 680 681 if (err != OK) { 682 return err; 683 } 684 685 *offset += chunk_size; 686 break; 687 } 688 689 case FOURCC('s', 't', 's', 's'): 690 { 691 status_t err = 692 mLastTrack->sampleTable->setSyncSampleParams( 693 data_offset, chunk_data_size); 694 695 if (err != OK) { 696 return err; 697 } 698 699 *offset += chunk_size; 700 break; 701 } 702 703 case FOURCC('e', 's', 'd', 's'): 704 { 705 if (chunk_data_size < 4) { 706 return ERROR_MALFORMED; 707 } 708 709 uint8_t buffer[256]; 710 if (chunk_data_size > (off_t)sizeof(buffer)) { 711 return ERROR_BUFFER_TOO_SMALL; 712 } 713 714 if (mDataSource->readAt( 715 data_offset, buffer, chunk_data_size) < chunk_data_size) { 716 return ERROR_IO; 717 } 718 719 if (U32_AT(buffer) != 0) { 720 // Should be version 0, flags 0. 721 return ERROR_MALFORMED; 722 } 723 724 mLastTrack->meta->setData( 725 kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 726 727 *offset += chunk_size; 728 break; 729 } 730 731 case FOURCC('a', 'v', 'c', 'C'): 732 { 733 char buffer[256]; 734 if (chunk_data_size > (off_t)sizeof(buffer)) { 735 return ERROR_BUFFER_TOO_SMALL; 736 } 737 738 if (mDataSource->readAt( 739 data_offset, buffer, chunk_data_size) < chunk_data_size) { 740 return ERROR_IO; 741 } 742 743 mLastTrack->meta->setData( 744 kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 745 746 *offset += chunk_size; 747 break; 748 } 749 750 default: 751 { 752 *offset += chunk_size; 753 break; 754 } 755 } 756 757 return OK; 758} 759 760sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 761 status_t err; 762 if ((err = readMetaData()) != OK) { 763 return NULL; 764 } 765 766 Track *track = mFirstTrack; 767 while (index > 0) { 768 if (track == NULL) { 769 return NULL; 770 } 771 772 track = track->next; 773 --index; 774 } 775 776 if (track == NULL) { 777 return NULL; 778 } 779 780 return new MPEG4Source( 781 track->meta, mDataSource, track->timescale, track->sampleTable); 782} 783 784//////////////////////////////////////////////////////////////////////////////// 785 786MPEG4Source::MPEG4Source( 787 const sp<MetaData> &format, 788 const sp<DataSource> &dataSource, 789 int32_t timeScale, 790 const sp<SampleTable> &sampleTable) 791 : mFormat(format), 792 mDataSource(dataSource), 793 mTimescale(timeScale), 794 mSampleTable(sampleTable), 795 mCurrentSampleIndex(0), 796 mIsAVC(false), 797 mNALLengthSize(0), 798 mStarted(false), 799 mGroup(NULL), 800 mBuffer(NULL), 801 mWantsNALFragments(false), 802 mSrcBuffer(NULL) { 803 const char *mime; 804 bool success = mFormat->findCString(kKeyMIMEType, &mime); 805 CHECK(success); 806 807 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 808 809 if (mIsAVC) { 810 uint32_t type; 811 const void *data; 812 size_t size; 813 CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 814 815 const uint8_t *ptr = (const uint8_t *)data; 816 817 CHECK(size >= 7); 818 CHECK_EQ(ptr[0], 1); // configurationVersion == 1 819 820 // The number of bytes used to encode the length of a NAL unit. 821 mNALLengthSize = 1 + (ptr[4] & 3); 822 } 823} 824 825MPEG4Source::~MPEG4Source() { 826 if (mStarted) { 827 stop(); 828 } 829} 830 831status_t MPEG4Source::start(MetaData *params) { 832 CHECK(!mStarted); 833 834 int32_t val; 835 if (params && params->findInt32(kKeyWantsNALFragments, &val) 836 && val != 0) { 837 mWantsNALFragments = true; 838 } else { 839 mWantsNALFragments = false; 840 } 841 842 mGroup = new MediaBufferGroup; 843 844 int32_t max_size; 845 CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 846 847 mGroup->add_buffer(new MediaBuffer(max_size)); 848 849 mSrcBuffer = new uint8_t[max_size]; 850 851 mStarted = true; 852 853 return OK; 854} 855 856status_t MPEG4Source::stop() { 857 CHECK(mStarted); 858 859 if (mBuffer != NULL) { 860 mBuffer->release(); 861 mBuffer = NULL; 862 } 863 864 delete[] mSrcBuffer; 865 mSrcBuffer = NULL; 866 867 delete mGroup; 868 mGroup = NULL; 869 870 mStarted = false; 871 mCurrentSampleIndex = 0; 872 873 return OK; 874} 875 876sp<MetaData> MPEG4Source::getFormat() { 877 return mFormat; 878} 879 880size_t MPEG4Source::parseNALSize(const uint8_t *data) const { 881 switch (mNALLengthSize) { 882 case 1: 883 return *data; 884 case 2: 885 return U16_AT(data); 886 case 3: 887 return ((size_t)data[0] << 16) | U16_AT(&data[1]); 888 case 4: 889 return U32_AT(data); 890 } 891 892 // This cannot happen, mNALLengthSize springs to life by adding 1 to 893 // a 2-bit integer. 894 CHECK(!"Should not be here."); 895 896 return 0; 897} 898 899status_t MPEG4Source::read( 900 MediaBuffer **out, const ReadOptions *options) { 901 CHECK(mStarted); 902 903 *out = NULL; 904 905 int64_t seekTimeUs; 906 if (options && options->getSeekTo(&seekTimeUs)) { 907 uint32_t sampleIndex; 908 status_t err = mSampleTable->findClosestSample( 909 seekTimeUs * mTimescale / 1000000, 910 &sampleIndex, SampleTable::kSyncSample_Flag); 911 912 if (err != OK) { 913 return err; 914 } 915 916 mCurrentSampleIndex = sampleIndex; 917 if (mBuffer != NULL) { 918 mBuffer->release(); 919 mBuffer = NULL; 920 } 921 922 // fall through 923 } 924 925 off_t offset; 926 size_t size; 927 uint32_t dts; 928 bool newBuffer = false; 929 if (mBuffer == NULL) { 930 newBuffer = true; 931 932 status_t err = mSampleTable->getSampleOffsetAndSize( 933 mCurrentSampleIndex, &offset, &size); 934 935 if (err != OK) { 936 return err; 937 } 938 939 err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 940 941 if (err != OK) { 942 return err; 943 } 944 945 err = mGroup->acquire_buffer(&mBuffer); 946 if (err != OK) { 947 CHECK_EQ(mBuffer, NULL); 948 return err; 949 } 950 } 951 952 if (!mIsAVC || mWantsNALFragments) { 953 if (newBuffer) { 954 ssize_t num_bytes_read = 955 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 956 957 if (num_bytes_read < (ssize_t)size) { 958 mBuffer->release(); 959 mBuffer = NULL; 960 961 return ERROR_IO; 962 } 963 964 mBuffer->set_range(0, size); 965 mBuffer->meta_data()->clear(); 966 mBuffer->meta_data()->setInt64( 967 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 968 ++mCurrentSampleIndex; 969 } 970 971 if (!mIsAVC) { 972 *out = mBuffer; 973 mBuffer = NULL; 974 975 return OK; 976 } 977 978 // Each NAL unit is split up into its constituent fragments and 979 // each one of them returned in its own buffer. 980 981 CHECK(mBuffer->range_length() >= mNALLengthSize); 982 983 const uint8_t *src = 984 (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 985 986 size_t nal_size = parseNALSize(src); 987 if (mBuffer->range_length() < mNALLengthSize + nal_size) { 988 LOGE("incomplete NAL unit."); 989 990 mBuffer->release(); 991 mBuffer = NULL; 992 993 return ERROR_MALFORMED; 994 } 995 996 MediaBuffer *clone = mBuffer->clone(); 997 clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 998 999 mBuffer->set_range( 1000 mBuffer->range_offset() + mNALLengthSize + nal_size, 1001 mBuffer->range_length() - mNALLengthSize - nal_size); 1002 1003 if (mBuffer->range_length() == 0) { 1004 mBuffer->release(); 1005 mBuffer = NULL; 1006 } 1007 1008 *out = clone; 1009 1010 return OK; 1011 } else { 1012 // Whole NAL units are returned but each fragment is prefixed by 1013 // the start code (0x00 00 00 01). 1014 1015 ssize_t num_bytes_read = 1016 mDataSource->readAt(offset, mSrcBuffer, size); 1017 1018 if (num_bytes_read < (ssize_t)size) { 1019 mBuffer->release(); 1020 mBuffer = NULL; 1021 1022 return ERROR_IO; 1023 } 1024 1025 uint8_t *dstData = (uint8_t *)mBuffer->data(); 1026 size_t srcOffset = 0; 1027 size_t dstOffset = 0; 1028 1029 while (srcOffset < size) { 1030 CHECK(srcOffset + mNALLengthSize <= size); 1031 size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 1032 srcOffset += mNALLengthSize; 1033 1034 if (srcOffset + nalLength > size) { 1035 mBuffer->release(); 1036 mBuffer = NULL; 1037 1038 return ERROR_MALFORMED; 1039 } 1040 1041 if (nalLength == 0) { 1042 continue; 1043 } 1044 1045 CHECK(dstOffset + 4 <= mBuffer->size()); 1046 1047 dstData[dstOffset++] = 0; 1048 dstData[dstOffset++] = 0; 1049 dstData[dstOffset++] = 0; 1050 dstData[dstOffset++] = 1; 1051 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1052 srcOffset += nalLength; 1053 dstOffset += nalLength; 1054 } 1055 CHECK_EQ(srcOffset, size); 1056 1057 mBuffer->set_range(0, dstOffset); 1058 mBuffer->meta_data()->clear(); 1059 mBuffer->meta_data()->setInt64( 1060 kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1061 ++mCurrentSampleIndex; 1062 1063 *out = mBuffer; 1064 mBuffer = NULL; 1065 1066 return OK; 1067 } 1068} 1069 1070bool SniffMPEG4( 1071 const sp<DataSource> &source, String8 *mimeType, float *confidence) { 1072 uint8_t header[8]; 1073 1074 ssize_t n = source->readAt(4, header, sizeof(header)); 1075 if (n < (ssize_t)sizeof(header)) { 1076 return false; 1077 } 1078 1079 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1080 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 1081 || !memcmp(header, "ftypM4A ", 8)) { 1082 *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1083 *confidence = 0.1; 1084 1085 return true; 1086 } 1087 1088 return false; 1089} 1090 1091} // namespace android 1092 1093