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