1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "AVIExtractor" 19 #include <utils/Log.h> 20 21 #include "include/avc_utils.h" 22 #include "include/AVIExtractor.h" 23 24 #include <binder/ProcessState.h> 25 #include <media/stagefright/foundation/hexdump.h> 26 #include <media/stagefright/foundation/ABuffer.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/DataSource.h> 29 #include <media/stagefright/MediaBuffer.h> 30 #include <media/stagefright/MediaBufferGroup.h> 31 #include <media/stagefright/MediaDefs.h> 32 #include <media/stagefright/MediaErrors.h> 33 #include <media/stagefright/MetaData.h> 34 #include <media/stagefright/Utils.h> 35 36 namespace android { 37 38 struct AVIExtractor::AVISource : public MediaSource { 39 AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex); 40 41 virtual status_t start(MetaData *params); 42 virtual status_t stop(); 43 44 virtual sp<MetaData> getFormat(); 45 46 virtual status_t read( 47 MediaBuffer **buffer, const ReadOptions *options); 48 49 protected: 50 virtual ~AVISource(); 51 52 private: 53 sp<AVIExtractor> mExtractor; 54 size_t mTrackIndex; 55 const AVIExtractor::Track &mTrack; 56 MediaBufferGroup *mBufferGroup; 57 size_t mSampleIndex; 58 59 sp<MP3Splitter> mSplitter; 60 61 DISALLOW_EVIL_CONSTRUCTORS(AVISource); 62 }; 63 64 //////////////////////////////////////////////////////////////////////////////// 65 66 struct AVIExtractor::MP3Splitter : public RefBase { 67 MP3Splitter(); 68 69 void clear(); 70 void append(MediaBuffer *buffer); 71 status_t read(MediaBuffer **buffer); 72 73 protected: 74 virtual ~MP3Splitter(); 75 76 private: 77 bool mFindSync; 78 int64_t mBaseTimeUs; 79 int64_t mNumSamplesRead; 80 sp<ABuffer> mBuffer; 81 82 bool resync(); 83 84 DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter); 85 }; 86 87 //////////////////////////////////////////////////////////////////////////////// 88 89 AVIExtractor::AVISource::AVISource( 90 const sp<AVIExtractor> &extractor, size_t trackIndex) 91 : mExtractor(extractor), 92 mTrackIndex(trackIndex), 93 mTrack(mExtractor->mTracks.itemAt(trackIndex)), 94 mBufferGroup(NULL) { 95 } 96 97 AVIExtractor::AVISource::~AVISource() { 98 if (mBufferGroup) { 99 stop(); 100 } 101 } 102 103 status_t AVIExtractor::AVISource::start(MetaData *params) { 104 CHECK(!mBufferGroup); 105 106 mBufferGroup = new MediaBufferGroup; 107 108 mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 109 mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize)); 110 mSampleIndex = 0; 111 112 const char *mime; 113 CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime)); 114 115 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { 116 mSplitter = new MP3Splitter; 117 } else { 118 mSplitter.clear(); 119 } 120 121 return OK; 122 } 123 124 status_t AVIExtractor::AVISource::stop() { 125 CHECK(mBufferGroup); 126 127 delete mBufferGroup; 128 mBufferGroup = NULL; 129 130 mSplitter.clear(); 131 132 return OK; 133 } 134 135 sp<MetaData> AVIExtractor::AVISource::getFormat() { 136 return mTrack.mMeta; 137 } 138 139 status_t AVIExtractor::AVISource::read( 140 MediaBuffer **buffer, const ReadOptions *options) { 141 CHECK(mBufferGroup); 142 143 *buffer = NULL; 144 145 int64_t seekTimeUs; 146 ReadOptions::SeekMode seekMode; 147 if (options && options->getSeekTo(&seekTimeUs, &seekMode)) { 148 status_t err = 149 mExtractor->getSampleIndexAtTime( 150 mTrackIndex, seekTimeUs, seekMode, &mSampleIndex); 151 152 if (err != OK) { 153 return ERROR_END_OF_STREAM; 154 } 155 156 if (mSplitter != NULL) { 157 mSplitter->clear(); 158 } 159 } 160 161 for (;;) { 162 if (mSplitter != NULL) { 163 status_t err = mSplitter->read(buffer); 164 165 if (err == OK) { 166 break; 167 } else if (err != -EAGAIN) { 168 return err; 169 } 170 } 171 172 off64_t offset; 173 size_t size; 174 bool isKey; 175 int64_t timeUs; 176 status_t err = mExtractor->getSampleInfo( 177 mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs); 178 179 ++mSampleIndex; 180 181 if (err != OK) { 182 return ERROR_END_OF_STREAM; 183 } 184 185 MediaBuffer *out; 186 CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK); 187 188 ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size); 189 190 if (n < (ssize_t)size) { 191 return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 192 } 193 194 out->set_range(0, size); 195 196 out->meta_data()->setInt64(kKeyTime, timeUs); 197 198 if (isKey) { 199 out->meta_data()->setInt32(kKeyIsSyncFrame, 1); 200 } 201 202 if (mSplitter == NULL) { 203 *buffer = out; 204 break; 205 } 206 207 mSplitter->append(out); 208 out->release(); 209 out = NULL; 210 } 211 212 return OK; 213 } 214 215 //////////////////////////////////////////////////////////////////////////////// 216 217 AVIExtractor::MP3Splitter::MP3Splitter() 218 : mFindSync(true), 219 mBaseTimeUs(-1ll), 220 mNumSamplesRead(0) { 221 } 222 223 AVIExtractor::MP3Splitter::~MP3Splitter() { 224 } 225 226 void AVIExtractor::MP3Splitter::clear() { 227 mFindSync = true; 228 mBaseTimeUs = -1ll; 229 mNumSamplesRead = 0; 230 231 if (mBuffer != NULL) { 232 mBuffer->setRange(0, 0); 233 } 234 } 235 236 void AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) { 237 size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0; 238 239 if (mBaseTimeUs < 0) { 240 CHECK(mBuffer == NULL || mBuffer->size() == 0); 241 CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs)); 242 mNumSamplesRead = 0; 243 } 244 245 if (mBuffer != NULL && mBuffer->offset() > 0) { 246 memmove(mBuffer->base(), mBuffer->data(), mBuffer->size()); 247 mBuffer->setRange(0, mBuffer->size()); 248 } 249 250 if (mBuffer == NULL 251 || mBuffer->size() + buffer->range_length() > prevCapacity) { 252 size_t newCapacity = 253 (prevCapacity + buffer->range_length() + 1023) & ~1023; 254 255 sp<ABuffer> newBuffer = new ABuffer(newCapacity); 256 if (mBuffer != NULL) { 257 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 258 newBuffer->setRange(0, mBuffer->size()); 259 } else { 260 newBuffer->setRange(0, 0); 261 } 262 mBuffer = newBuffer; 263 } 264 265 memcpy(mBuffer->data() + mBuffer->size(), 266 (const uint8_t *)buffer->data() + buffer->range_offset(), 267 buffer->range_length()); 268 269 mBuffer->setRange(0, mBuffer->size() + buffer->range_length()); 270 } 271 272 bool AVIExtractor::MP3Splitter::resync() { 273 if (mBuffer == NULL) { 274 return false; 275 } 276 277 bool foundSync = false; 278 for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) { 279 uint32_t firstHeader = U32_AT(mBuffer->data() + offset); 280 281 size_t frameSize; 282 if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) { 283 continue; 284 } 285 286 size_t subsequentOffset = offset + frameSize; 287 size_t i = 3; 288 while (i > 0) { 289 if (subsequentOffset + 3 >= mBuffer->size()) { 290 break; 291 } 292 293 static const uint32_t kMask = 0xfffe0c00; 294 295 uint32_t header = U32_AT(mBuffer->data() + subsequentOffset); 296 if ((header & kMask) != (firstHeader & kMask)) { 297 break; 298 } 299 300 if (!GetMPEGAudioFrameSize(header, &frameSize)) { 301 break; 302 } 303 304 subsequentOffset += frameSize; 305 --i; 306 } 307 308 if (i == 0) { 309 foundSync = true; 310 memmove(mBuffer->data(), 311 mBuffer->data() + offset, 312 mBuffer->size() - offset); 313 314 mBuffer->setRange(0, mBuffer->size() - offset); 315 break; 316 } 317 } 318 319 return foundSync; 320 } 321 322 status_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) { 323 *out = NULL; 324 325 if (mFindSync) { 326 if (!resync()) { 327 return -EAGAIN; 328 } 329 330 mFindSync = false; 331 } 332 333 if (mBuffer->size() < 4) { 334 return -EAGAIN; 335 } 336 337 uint32_t header = U32_AT(mBuffer->data()); 338 size_t frameSize; 339 int sampleRate; 340 int numSamples; 341 if (!GetMPEGAudioFrameSize( 342 header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) { 343 return ERROR_MALFORMED; 344 } 345 346 if (mBuffer->size() < frameSize) { 347 return -EAGAIN; 348 } 349 350 MediaBuffer *mbuf = new MediaBuffer(frameSize); 351 memcpy(mbuf->data(), mBuffer->data(), frameSize); 352 353 int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate; 354 mNumSamplesRead += numSamples; 355 356 mbuf->meta_data()->setInt64(kKeyTime, timeUs); 357 358 mBuffer->setRange( 359 mBuffer->offset() + frameSize, mBuffer->size() - frameSize); 360 361 *out = mbuf; 362 363 return OK; 364 } 365 366 //////////////////////////////////////////////////////////////////////////////// 367 368 AVIExtractor::AVIExtractor(const sp<DataSource> &dataSource) 369 : mDataSource(dataSource) { 370 mInitCheck = parseHeaders(); 371 372 if (mInitCheck != OK) { 373 mTracks.clear(); 374 } 375 } 376 377 AVIExtractor::~AVIExtractor() { 378 } 379 380 size_t AVIExtractor::countTracks() { 381 return mTracks.size(); 382 } 383 384 sp<MediaSource> AVIExtractor::getTrack(size_t index) { 385 return index < mTracks.size() ? new AVISource(this, index) : NULL; 386 } 387 388 sp<MetaData> AVIExtractor::getTrackMetaData( 389 size_t index, uint32_t flags) { 390 return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL; 391 } 392 393 sp<MetaData> AVIExtractor::getMetaData() { 394 sp<MetaData> meta = new MetaData; 395 396 if (mInitCheck == OK) { 397 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI); 398 } 399 400 return meta; 401 } 402 403 status_t AVIExtractor::parseHeaders() { 404 mTracks.clear(); 405 mMovieOffset = 0; 406 mFoundIndex = false; 407 mOffsetsAreAbsolute = false; 408 409 ssize_t res = parseChunk(0ll, -1ll); 410 411 if (res < 0) { 412 return (status_t)res; 413 } 414 415 if (mMovieOffset == 0ll || !mFoundIndex) { 416 return ERROR_MALFORMED; 417 } 418 419 return OK; 420 } 421 422 ssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) { 423 if (size >= 0 && size < 8) { 424 return ERROR_MALFORMED; 425 } 426 427 uint8_t tmp[12]; 428 ssize_t n = mDataSource->readAt(offset, tmp, 8); 429 430 if (n < 8) { 431 return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 432 } 433 434 uint32_t fourcc = U32_AT(tmp); 435 uint32_t chunkSize = U32LE_AT(&tmp[4]); 436 437 if (size >= 0 && chunkSize + 8 > size) { 438 return ERROR_MALFORMED; 439 } 440 441 static const char kPrefix[] = " "; 442 const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth]; 443 444 if (fourcc == FOURCC('L', 'I', 'S', 'T') 445 || fourcc == FOURCC('R', 'I', 'F', 'F')) { 446 // It's a list of chunks 447 448 if (size >= 0 && size < 12) { 449 return ERROR_MALFORMED; 450 } 451 452 n = mDataSource->readAt(offset + 8, &tmp[8], 4); 453 454 if (n < 4) { 455 return (n < 0) ? n : (ssize_t)ERROR_MALFORMED; 456 } 457 458 uint32_t subFourcc = U32_AT(&tmp[8]); 459 460 ALOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d", 461 prefix, 462 offset, 463 (char)(subFourcc >> 24), 464 (char)((subFourcc >> 16) & 0xff), 465 (char)((subFourcc >> 8) & 0xff), 466 (char)(subFourcc & 0xff), 467 chunkSize - 4); 468 469 if (subFourcc == FOURCC('m', 'o', 'v', 'i')) { 470 // We're not going to parse this, but will take note of the 471 // offset. 472 473 mMovieOffset = offset; 474 } else { 475 off64_t subOffset = offset + 12; 476 off64_t subOffsetLimit = subOffset + chunkSize - 4; 477 while (subOffset < subOffsetLimit) { 478 ssize_t res = 479 parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1); 480 481 if (res < 0) { 482 return res; 483 } 484 485 subOffset += res; 486 } 487 } 488 } else { 489 ALOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'", 490 prefix, 491 offset, 492 (char)(fourcc >> 24), 493 (char)((fourcc >> 16) & 0xff), 494 (char)((fourcc >> 8) & 0xff), 495 (char)(fourcc & 0xff)); 496 497 status_t err = OK; 498 499 switch (fourcc) { 500 case FOURCC('s', 't', 'r', 'h'): 501 { 502 err = parseStreamHeader(offset + 8, chunkSize); 503 break; 504 } 505 506 case FOURCC('s', 't', 'r', 'f'): 507 { 508 err = parseStreamFormat(offset + 8, chunkSize); 509 break; 510 } 511 512 case FOURCC('i', 'd', 'x', '1'): 513 { 514 err = parseIndex(offset + 8, chunkSize); 515 break; 516 } 517 518 default: 519 break; 520 } 521 522 if (err != OK) { 523 return err; 524 } 525 } 526 527 if (chunkSize & 1) { 528 ++chunkSize; 529 } 530 531 return chunkSize + 8; 532 } 533 534 static const char *GetMIMETypeForHandler(uint32_t handler) { 535 switch (handler) { 536 // Wow... shamelessly copied from 537 // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4 538 539 case FOURCC('3', 'I', 'V', '2'): 540 case FOURCC('3', 'i', 'v', '2'): 541 case FOURCC('B', 'L', 'Z', '0'): 542 case FOURCC('D', 'I', 'G', 'I'): 543 case FOURCC('D', 'I', 'V', '1'): 544 case FOURCC('d', 'i', 'v', '1'): 545 case FOURCC('D', 'I', 'V', 'X'): 546 case FOURCC('d', 'i', 'v', 'x'): 547 case FOURCC('D', 'X', '5', '0'): 548 case FOURCC('d', 'x', '5', '0'): 549 case FOURCC('D', 'X', 'G', 'M'): 550 case FOURCC('E', 'M', '4', 'A'): 551 case FOURCC('E', 'P', 'H', 'V'): 552 case FOURCC('F', 'M', 'P', '4'): 553 case FOURCC('f', 'm', 'p', '4'): 554 case FOURCC('F', 'V', 'F', 'W'): 555 case FOURCC('H', 'D', 'X', '4'): 556 case FOURCC('h', 'd', 'x', '4'): 557 case FOURCC('M', '4', 'C', 'C'): 558 case FOURCC('M', '4', 'S', '2'): 559 case FOURCC('m', '4', 's', '2'): 560 case FOURCC('M', 'P', '4', 'S'): 561 case FOURCC('m', 'p', '4', 's'): 562 case FOURCC('M', 'P', '4', 'V'): 563 case FOURCC('m', 'p', '4', 'v'): 564 case FOURCC('M', 'V', 'X', 'M'): 565 case FOURCC('R', 'M', 'P', '4'): 566 case FOURCC('S', 'E', 'D', 'G'): 567 case FOURCC('S', 'M', 'P', '4'): 568 case FOURCC('U', 'M', 'P', '4'): 569 case FOURCC('W', 'V', '1', 'F'): 570 case FOURCC('X', 'V', 'I', 'D'): 571 case FOURCC('X', 'v', 'i', 'D'): 572 case FOURCC('x', 'v', 'i', 'd'): 573 case FOURCC('X', 'V', 'I', 'X'): 574 return MEDIA_MIMETYPE_VIDEO_MPEG4; 575 576 // from http://wiki.multimedia.cx/index.php?title=H264 577 case FOURCC('a', 'v', 'c', '1'): 578 case FOURCC('d', 'a', 'v', 'c'): 579 case FOURCC('x', '2', '6', '4'): 580 case FOURCC('H', '2', '6', '4'): 581 case FOURCC('v', 's', 's', 'h'): 582 return MEDIA_MIMETYPE_VIDEO_AVC; 583 584 default: 585 return NULL; 586 } 587 } 588 589 status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) { 590 if (size != 56) { 591 return ERROR_MALFORMED; 592 } 593 594 if (mTracks.size() > 99) { 595 return -ERANGE; 596 } 597 598 sp<ABuffer> buffer = new ABuffer(size); 599 ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 600 601 if (n < (ssize_t)size) { 602 return n < 0 ? (status_t)n : ERROR_MALFORMED; 603 } 604 605 const uint8_t *data = buffer->data(); 606 607 uint32_t type = U32_AT(data); 608 uint32_t handler = U32_AT(&data[4]); 609 uint32_t flags = U32LE_AT(&data[8]); 610 611 sp<MetaData> meta = new MetaData; 612 613 uint32_t rate = U32LE_AT(&data[20]); 614 uint32_t scale = U32LE_AT(&data[24]); 615 616 uint32_t sampleSize = U32LE_AT(&data[44]); 617 618 const char *mime = NULL; 619 Track::Kind kind = Track::OTHER; 620 621 if (type == FOURCC('v', 'i', 'd', 's')) { 622 mime = GetMIMETypeForHandler(handler); 623 624 if (mime && strncasecmp(mime, "video/", 6)) { 625 return ERROR_MALFORMED; 626 } 627 628 if (mime == NULL) { 629 ALOGW("Unsupported video format '%c%c%c%c'", 630 (char)(handler >> 24), 631 (char)((handler >> 16) & 0xff), 632 (char)((handler >> 8) & 0xff), 633 (char)(handler & 0xff)); 634 } 635 636 kind = Track::VIDEO; 637 } else if (type == FOURCC('a', 'u', 'd', 's')) { 638 if (mime && strncasecmp(mime, "audio/", 6)) { 639 return ERROR_MALFORMED; 640 } 641 642 kind = Track::AUDIO; 643 } 644 645 if (!mime) { 646 mime = "application/octet-stream"; 647 } 648 649 meta->setCString(kKeyMIMEType, mime); 650 651 mTracks.push(); 652 Track *track = &mTracks.editItemAt(mTracks.size() - 1); 653 654 track->mMeta = meta; 655 track->mRate = rate; 656 track->mScale = scale; 657 track->mBytesPerSample = sampleSize; 658 track->mKind = kind; 659 track->mNumSyncSamples = 0; 660 track->mThumbnailSampleSize = 0; 661 track->mThumbnailSampleIndex = -1; 662 track->mMaxSampleSize = 0; 663 track->mAvgChunkSize = 1.0; 664 track->mFirstChunkSize = 0; 665 666 return OK; 667 } 668 669 status_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) { 670 if (mTracks.isEmpty()) { 671 return ERROR_MALFORMED; 672 } 673 674 Track *track = &mTracks.editItemAt(mTracks.size() - 1); 675 676 if (track->mKind == Track::OTHER) { 677 // We don't support this content, but that's not a parsing error. 678 return OK; 679 } 680 681 bool isVideo = (track->mKind == Track::VIDEO); 682 683 if ((isVideo && size < 40) || (!isVideo && size < 16)) { 684 // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively. 685 return ERROR_MALFORMED; 686 } 687 688 sp<ABuffer> buffer = new ABuffer(size); 689 ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 690 691 if (n < (ssize_t)size) { 692 return n < 0 ? (status_t)n : ERROR_MALFORMED; 693 } 694 695 const uint8_t *data = buffer->data(); 696 697 if (isVideo) { 698 uint32_t width = U32LE_AT(&data[4]); 699 uint32_t height = U32LE_AT(&data[8]); 700 701 track->mMeta->setInt32(kKeyWidth, width); 702 track->mMeta->setInt32(kKeyHeight, height); 703 } else { 704 uint32_t format = U16LE_AT(data); 705 706 if (format == 0x55) { 707 track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 708 } else { 709 ALOGW("Unsupported audio format = 0x%04x", format); 710 } 711 712 uint32_t numChannels = U16LE_AT(&data[2]); 713 uint32_t sampleRate = U32LE_AT(&data[4]); 714 715 track->mMeta->setInt32(kKeyChannelCount, numChannels); 716 track->mMeta->setInt32(kKeySampleRate, sampleRate); 717 } 718 719 return OK; 720 } 721 722 // static 723 bool AVIExtractor::IsCorrectChunkType( 724 ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) { 725 uint32_t chunkBase = chunkType & 0xffff; 726 727 switch (kind) { 728 case Track::VIDEO: 729 { 730 if (chunkBase != FOURCC(0, 0, 'd', 'c') 731 && chunkBase != FOURCC(0, 0, 'd', 'b')) { 732 return false; 733 } 734 break; 735 } 736 737 case Track::AUDIO: 738 { 739 if (chunkBase != FOURCC(0, 0, 'w', 'b')) { 740 return false; 741 } 742 break; 743 } 744 745 default: 746 break; 747 } 748 749 if (trackIndex < 0) { 750 return true; 751 } 752 753 uint8_t hi = chunkType >> 24; 754 uint8_t lo = (chunkType >> 16) & 0xff; 755 756 if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 757 return false; 758 } 759 760 if (trackIndex != (10 * (hi - '0') + (lo - '0'))) { 761 return false; 762 } 763 764 return true; 765 } 766 767 status_t AVIExtractor::parseIndex(off64_t offset, size_t size) { 768 if ((size % 16) != 0) { 769 return ERROR_MALFORMED; 770 } 771 772 sp<ABuffer> buffer = new ABuffer(size); 773 ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 774 775 if (n < (ssize_t)size) { 776 return n < 0 ? (status_t)n : ERROR_MALFORMED; 777 } 778 779 const uint8_t *data = buffer->data(); 780 781 while (size > 0) { 782 uint32_t chunkType = U32_AT(data); 783 784 uint8_t hi = chunkType >> 24; 785 uint8_t lo = (chunkType >> 16) & 0xff; 786 787 if (hi < '0' || hi > '9' || lo < '0' || lo > '9') { 788 return ERROR_MALFORMED; 789 } 790 791 size_t trackIndex = 10 * (hi - '0') + (lo - '0'); 792 793 if (trackIndex >= mTracks.size()) { 794 return ERROR_MALFORMED; 795 } 796 797 Track *track = &mTracks.editItemAt(trackIndex); 798 799 if (!IsCorrectChunkType(-1, track->mKind, chunkType)) { 800 return ERROR_MALFORMED; 801 } 802 803 if (track->mKind == Track::OTHER) { 804 data += 16; 805 size -= 16; 806 continue; 807 } 808 809 uint32_t flags = U32LE_AT(&data[4]); 810 uint32_t offset = U32LE_AT(&data[8]); 811 uint32_t chunkSize = U32LE_AT(&data[12]); 812 813 if (chunkSize > track->mMaxSampleSize) { 814 track->mMaxSampleSize = chunkSize; 815 } 816 817 track->mSamples.push(); 818 819 SampleInfo *info = 820 &track->mSamples.editItemAt(track->mSamples.size() - 1); 821 822 info->mOffset = offset; 823 info->mIsKey = (flags & 0x10) != 0; 824 825 if (info->mIsKey) { 826 static const size_t kMaxNumSyncSamplesToScan = 20; 827 828 if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) { 829 if (chunkSize > track->mThumbnailSampleSize) { 830 track->mThumbnailSampleSize = chunkSize; 831 832 track->mThumbnailSampleIndex = 833 track->mSamples.size() - 1; 834 } 835 } 836 837 ++track->mNumSyncSamples; 838 } 839 840 data += 16; 841 size -= 16; 842 } 843 844 if (!mTracks.isEmpty()) { 845 off64_t offset; 846 size_t size; 847 bool isKey; 848 int64_t timeUs; 849 status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 850 851 if (err != OK) { 852 mOffsetsAreAbsolute = !mOffsetsAreAbsolute; 853 err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs); 854 855 if (err != OK) { 856 return err; 857 } 858 } 859 860 ALOGV("Chunk offsets are %s", 861 mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative"); 862 } 863 864 for (size_t i = 0; i < mTracks.size(); ++i) { 865 Track *track = &mTracks.editItemAt(i); 866 867 if (track->mBytesPerSample > 0) { 868 // Assume all chunks are roughly the same size for now. 869 870 // Compute the avg. size of the first 128 chunks (if there are 871 // that many), but exclude the size of the first one, since 872 // it may be an outlier. 873 size_t numSamplesToAverage = track->mSamples.size(); 874 if (numSamplesToAverage > 256) { 875 numSamplesToAverage = 256; 876 } 877 878 double avgChunkSize = 0; 879 size_t j; 880 for (j = 0; j <= numSamplesToAverage; ++j) { 881 off64_t offset; 882 size_t size; 883 bool isKey; 884 int64_t dummy; 885 886 status_t err = 887 getSampleInfo( 888 i, j, 889 &offset, &size, &isKey, &dummy); 890 891 if (err != OK) { 892 return err; 893 } 894 895 if (j == 0) { 896 track->mFirstChunkSize = size; 897 continue; 898 } 899 900 avgChunkSize += size; 901 } 902 903 avgChunkSize /= numSamplesToAverage; 904 905 track->mAvgChunkSize = avgChunkSize; 906 } 907 908 int64_t durationUs; 909 CHECK_EQ((status_t)OK, 910 getSampleTime(i, track->mSamples.size() - 1, &durationUs)); 911 912 ALOGV("track %d duration = %.2f secs", i, durationUs / 1E6); 913 914 track->mMeta->setInt64(kKeyDuration, durationUs); 915 track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize); 916 917 const char *tmp; 918 CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp)); 919 920 AString mime = tmp; 921 922 if (!strncasecmp("video/", mime.c_str(), 6)) { 923 if (track->mThumbnailSampleIndex >= 0) { 924 int64_t thumbnailTimeUs; 925 CHECK_EQ((status_t)OK, 926 getSampleTime(i, track->mThumbnailSampleIndex, 927 &thumbnailTimeUs)); 928 929 track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs); 930 } 931 932 status_t err = OK; 933 934 if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) { 935 err = addMPEG4CodecSpecificData(i); 936 } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 937 err = addH264CodecSpecificData(i); 938 } 939 940 if (err != OK) { 941 return err; 942 } 943 } 944 } 945 946 mFoundIndex = true; 947 948 return OK; 949 } 950 951 static size_t GetSizeWidth(size_t x) { 952 size_t n = 1; 953 while (x > 127) { 954 ++n; 955 x >>= 7; 956 } 957 return n; 958 } 959 960 static uint8_t *EncodeSize(uint8_t *dst, size_t x) { 961 while (x > 127) { 962 *dst++ = (x & 0x7f) | 0x80; 963 x >>= 7; 964 } 965 *dst++ = x; 966 return dst; 967 } 968 969 sp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) { 970 size_t len1 = config->size() + GetSizeWidth(config->size()) + 1; 971 size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13; 972 size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3; 973 974 sp<ABuffer> csd = new ABuffer(len3); 975 uint8_t *dst = csd->data(); 976 *dst++ = 0x03; 977 dst = EncodeSize(dst, len2 + 3); 978 *dst++ = 0x00; // ES_ID 979 *dst++ = 0x00; 980 *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 981 982 *dst++ = 0x04; 983 dst = EncodeSize(dst, len1 + 13); 984 *dst++ = 0x01; // Video ISO/IEC 14496-2 Simple Profile 985 for (size_t i = 0; i < 12; ++i) { 986 *dst++ = 0x00; 987 } 988 989 *dst++ = 0x05; 990 dst = EncodeSize(dst, config->size()); 991 memcpy(dst, config->data(), config->size()); 992 dst += config->size(); 993 994 // hexdump(csd->data(), csd->size()); 995 996 return csd; 997 } 998 999 status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) { 1000 Track *track = &mTracks.editItemAt(trackIndex); 1001 1002 off64_t offset; 1003 size_t size; 1004 bool isKey; 1005 int64_t timeUs; 1006 status_t err = 1007 getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs); 1008 1009 if (err != OK) { 1010 return err; 1011 } 1012 1013 sp<ABuffer> buffer = new ABuffer(size); 1014 ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1015 1016 if (n < (ssize_t)size) { 1017 return n < 0 ? (status_t)n : ERROR_MALFORMED; 1018 } 1019 1020 // Extract everything up to the first VOP start code from the first 1021 // frame's encoded data and use it to construct an ESDS with the 1022 // codec specific data. 1023 1024 size_t i = 0; 1025 bool found = false; 1026 while (i + 3 < buffer->size()) { 1027 if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) { 1028 found = true; 1029 break; 1030 } 1031 1032 ++i; 1033 } 1034 1035 if (!found) { 1036 return ERROR_MALFORMED; 1037 } 1038 1039 buffer->setRange(0, i); 1040 1041 sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer); 1042 track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size()); 1043 1044 return OK; 1045 } 1046 1047 status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) { 1048 Track *track = &mTracks.editItemAt(trackIndex); 1049 1050 off64_t offset; 1051 size_t size; 1052 bool isKey; 1053 int64_t timeUs; 1054 1055 // Extract codec specific data from the first non-empty sample. 1056 1057 size_t sampleIndex = 0; 1058 for (;;) { 1059 status_t err = 1060 getSampleInfo( 1061 trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs); 1062 1063 if (err != OK) { 1064 return err; 1065 } 1066 1067 if (size > 0) { 1068 break; 1069 } 1070 1071 ++sampleIndex; 1072 } 1073 1074 sp<ABuffer> buffer = new ABuffer(size); 1075 ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size()); 1076 1077 if (n < (ssize_t)size) { 1078 return n < 0 ? (status_t)n : ERROR_MALFORMED; 1079 } 1080 1081 sp<MetaData> meta = MakeAVCCodecSpecificData(buffer); 1082 1083 if (meta == NULL) { 1084 ALOGE("Unable to extract AVC codec specific data"); 1085 return ERROR_MALFORMED; 1086 } 1087 1088 int32_t width, height; 1089 CHECK(meta->findInt32(kKeyWidth, &width)); 1090 CHECK(meta->findInt32(kKeyHeight, &height)); 1091 1092 uint32_t type; 1093 const void *csd; 1094 size_t csdSize; 1095 CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize)); 1096 1097 track->mMeta->setInt32(kKeyWidth, width); 1098 track->mMeta->setInt32(kKeyHeight, height); 1099 track->mMeta->setData(kKeyAVCC, type, csd, csdSize); 1100 1101 return OK; 1102 } 1103 1104 status_t AVIExtractor::getSampleInfo( 1105 size_t trackIndex, size_t sampleIndex, 1106 off64_t *offset, size_t *size, bool *isKey, 1107 int64_t *sampleTimeUs) { 1108 if (trackIndex >= mTracks.size()) { 1109 return -ERANGE; 1110 } 1111 1112 const Track &track = mTracks.itemAt(trackIndex); 1113 1114 if (sampleIndex >= track.mSamples.size()) { 1115 return -ERANGE; 1116 } 1117 1118 const SampleInfo &info = track.mSamples.itemAt(sampleIndex); 1119 1120 if (!mOffsetsAreAbsolute) { 1121 *offset = info.mOffset + mMovieOffset + 8; 1122 } else { 1123 *offset = info.mOffset; 1124 } 1125 1126 *size = 0; 1127 1128 uint8_t tmp[8]; 1129 ssize_t n = mDataSource->readAt(*offset, tmp, 8); 1130 1131 if (n < 8) { 1132 return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED; 1133 } 1134 1135 uint32_t chunkType = U32_AT(tmp); 1136 1137 if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) { 1138 return ERROR_MALFORMED; 1139 } 1140 1141 *offset += 8; 1142 *size = U32LE_AT(&tmp[4]); 1143 1144 *isKey = info.mIsKey; 1145 1146 if (track.mBytesPerSample > 0) { 1147 size_t sampleStartInBytes; 1148 if (sampleIndex == 0) { 1149 sampleStartInBytes = 0; 1150 } else { 1151 sampleStartInBytes = 1152 track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1); 1153 } 1154 1155 sampleIndex = sampleStartInBytes / track.mBytesPerSample; 1156 } 1157 1158 *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale; 1159 1160 return OK; 1161 } 1162 1163 status_t AVIExtractor::getSampleTime( 1164 size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) { 1165 off64_t offset; 1166 size_t size; 1167 bool isKey; 1168 return getSampleInfo( 1169 trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs); 1170 } 1171 1172 status_t AVIExtractor::getSampleIndexAtTime( 1173 size_t trackIndex, 1174 int64_t timeUs, MediaSource::ReadOptions::SeekMode mode, 1175 size_t *sampleIndex) const { 1176 if (trackIndex >= mTracks.size()) { 1177 return -ERANGE; 1178 } 1179 1180 const Track &track = mTracks.itemAt(trackIndex); 1181 1182 ssize_t closestSampleIndex; 1183 1184 if (track.mBytesPerSample > 0) { 1185 size_t closestByteOffset = 1186 (timeUs * track.mBytesPerSample) 1187 / track.mRate * track.mScale / 1000000ll; 1188 1189 if (closestByteOffset <= track.mFirstChunkSize) { 1190 closestSampleIndex = 0; 1191 } else { 1192 closestSampleIndex = 1193 (closestByteOffset - track.mFirstChunkSize) 1194 / track.mAvgChunkSize; 1195 } 1196 } else { 1197 // Each chunk contains a single sample. 1198 closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll; 1199 } 1200 1201 ssize_t numSamples = track.mSamples.size(); 1202 1203 if (closestSampleIndex < 0) { 1204 closestSampleIndex = 0; 1205 } else if (closestSampleIndex >= numSamples) { 1206 closestSampleIndex = numSamples - 1; 1207 } 1208 1209 if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) { 1210 *sampleIndex = closestSampleIndex; 1211 1212 return OK; 1213 } 1214 1215 ssize_t prevSyncSampleIndex = closestSampleIndex; 1216 while (prevSyncSampleIndex >= 0) { 1217 const SampleInfo &info = 1218 track.mSamples.itemAt(prevSyncSampleIndex); 1219 1220 if (info.mIsKey) { 1221 break; 1222 } 1223 1224 --prevSyncSampleIndex; 1225 } 1226 1227 ssize_t nextSyncSampleIndex = closestSampleIndex; 1228 while (nextSyncSampleIndex < numSamples) { 1229 const SampleInfo &info = 1230 track.mSamples.itemAt(nextSyncSampleIndex); 1231 1232 if (info.mIsKey) { 1233 break; 1234 } 1235 1236 ++nextSyncSampleIndex; 1237 } 1238 1239 switch (mode) { 1240 case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC: 1241 { 1242 *sampleIndex = prevSyncSampleIndex; 1243 1244 return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR; 1245 } 1246 1247 case MediaSource::ReadOptions::SEEK_NEXT_SYNC: 1248 { 1249 *sampleIndex = nextSyncSampleIndex; 1250 1251 return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR; 1252 } 1253 1254 case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC: 1255 { 1256 if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) { 1257 return UNKNOWN_ERROR; 1258 } 1259 1260 if (prevSyncSampleIndex < 0) { 1261 *sampleIndex = nextSyncSampleIndex; 1262 return OK; 1263 } 1264 1265 if (nextSyncSampleIndex >= numSamples) { 1266 *sampleIndex = prevSyncSampleIndex; 1267 return OK; 1268 } 1269 1270 size_t dist1 = closestSampleIndex - prevSyncSampleIndex; 1271 size_t dist2 = nextSyncSampleIndex - closestSampleIndex; 1272 1273 *sampleIndex = 1274 (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex; 1275 1276 return OK; 1277 } 1278 1279 default: 1280 TRESPASS(); 1281 break; 1282 } 1283 } 1284 1285 bool SniffAVI( 1286 const sp<DataSource> &source, String8 *mimeType, float *confidence, 1287 sp<AMessage> *) { 1288 char tmp[12]; 1289 if (source->readAt(0, tmp, 12) < 12) { 1290 return false; 1291 } 1292 1293 if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) { 1294 mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI); 1295 1296 // Just a tad over the mp3 extractor's confidence, since 1297 // these .avi files may contain .mp3 content that otherwise would 1298 // mistakenly lead to us identifying the entire file as a .mp3 file. 1299 *confidence = 0.21; 1300 1301 return true; 1302 } 1303 1304 return false; 1305 } 1306 1307 } // namespace android 1308