1 /* 2 * Copyright (C) 2010 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 "OggExtractor" 19 #include <utils/Log.h> 20 21 #include "include/OggExtractor.h" 22 23 #include <cutils/properties.h> 24 #include <media/stagefright/foundation/ABuffer.h> 25 #include <media/stagefright/foundation/ADebug.h> 26 #include <media/stagefright/foundation/base64.h> 27 #include <media/stagefright/DataSource.h> 28 #include <media/stagefright/MediaBuffer.h> 29 #include <media/stagefright/MediaBufferGroup.h> 30 #include <media/stagefright/MediaDefs.h> 31 #include <media/stagefright/MediaErrors.h> 32 #include <media/stagefright/MediaSource.h> 33 #include <media/stagefright/MetaData.h> 34 #include <media/stagefright/Utils.h> 35 #include <utils/String8.h> 36 37 extern "C" { 38 #include <Tremolo/codec_internal.h> 39 40 int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb); 41 int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb); 42 int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); 43 long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); 44 } 45 46 namespace android { 47 48 struct OggSource : public MediaSource { 49 explicit OggSource(const sp<OggExtractor> &extractor); 50 51 virtual sp<MetaData> getFormat(); 52 53 virtual status_t start(MetaData *params = NULL); 54 virtual status_t stop(); 55 56 virtual status_t read( 57 MediaBuffer **buffer, const ReadOptions *options = NULL); 58 59 protected: 60 virtual ~OggSource(); 61 62 private: 63 sp<OggExtractor> mExtractor; 64 bool mStarted; 65 66 OggSource(const OggSource &); 67 OggSource &operator=(const OggSource &); 68 }; 69 70 struct MyOggExtractor { 71 MyOggExtractor( 72 const sp<DataSource> &source, 73 const char *mimeType, 74 size_t numHeaders, 75 int64_t seekPreRollUs); 76 virtual ~MyOggExtractor(); 77 78 sp<MetaData> getFormat() const; 79 80 // Returns an approximate bitrate in bits per second. 81 virtual uint64_t approxBitrate() const = 0; 82 83 status_t seekToTime(int64_t timeUs); 84 status_t seekToOffset(off64_t offset); 85 virtual status_t readNextPacket(MediaBuffer **buffer) = 0; 86 87 status_t init(); 88 89 sp<MetaData> getFileMetaData() { return mFileMeta; } 90 91 protected: 92 struct Page { 93 uint64_t mGranulePosition; 94 int32_t mPrevPacketSize; 95 uint64_t mPrevPacketPos; 96 uint32_t mSerialNo; 97 uint32_t mPageNo; 98 uint8_t mFlags; 99 uint8_t mNumSegments; 100 uint8_t mLace[255]; 101 }; 102 103 struct TOCEntry { 104 off64_t mPageOffset; 105 int64_t mTimeUs; 106 }; 107 108 sp<DataSource> mSource; 109 off64_t mOffset; 110 Page mCurrentPage; 111 uint64_t mCurGranulePosition; 112 uint64_t mPrevGranulePosition; 113 size_t mCurrentPageSize; 114 bool mFirstPacketInPage; 115 uint64_t mCurrentPageSamples; 116 size_t mNextLaceIndex; 117 118 const char *mMimeType; 119 size_t mNumHeaders; 120 int64_t mSeekPreRollUs; 121 122 off64_t mFirstDataOffset; 123 124 vorbis_info mVi; 125 vorbis_comment mVc; 126 127 sp<MetaData> mMeta; 128 sp<MetaData> mFileMeta; 129 130 Vector<TOCEntry> mTableOfContents; 131 132 ssize_t readPage(off64_t offset, Page *page); 133 status_t findNextPage(off64_t startOffset, off64_t *pageOffset); 134 135 virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const = 0; 136 137 // Extract codec format, metadata tags, and various codec specific data; 138 // the format and CSD's are required to setup the decoders for the enclosed media content. 139 // 140 // Valid values for `type` are: 141 // 1 - bitstream identification header 142 // 3 - comment header 143 // 5 - codec setup header (Vorbis only) 144 virtual status_t verifyHeader(MediaBuffer *buffer, uint8_t type) = 0; 145 146 // Read the next ogg packet from the underlying data source; optionally 147 // calculate the timestamp for the output packet whilst pretending 148 // that we are parsing an Ogg Vorbis stream. 149 // 150 // *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated; 151 // clients are responsible for releasing the original buffer. 152 status_t _readNextPacket(MediaBuffer **buffer, bool calcVorbisTimestamp); 153 154 int32_t getPacketBlockSize(MediaBuffer *buffer); 155 156 void parseFileMetaData(); 157 158 status_t findPrevGranulePosition(off64_t pageOffset, uint64_t *granulePos); 159 160 void buildTableOfContents(); 161 162 MyOggExtractor(const MyOggExtractor &); 163 MyOggExtractor &operator=(const MyOggExtractor &); 164 }; 165 166 struct MyVorbisExtractor : public MyOggExtractor { 167 explicit MyVorbisExtractor(const sp<DataSource> &source) 168 : MyOggExtractor(source, 169 MEDIA_MIMETYPE_AUDIO_VORBIS, 170 /* numHeaders */ 3, 171 /* seekPreRollUs */ 0) { 172 } 173 174 virtual uint64_t approxBitrate() const; 175 176 virtual status_t readNextPacket(MediaBuffer **buffer) { 177 return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true); 178 } 179 180 protected: 181 virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const { 182 if (granulePos > INT64_MAX / 1000000ll) { 183 return INT64_MAX; 184 } 185 return granulePos * 1000000ll / mVi.rate; 186 } 187 188 virtual status_t verifyHeader(MediaBuffer *buffer, uint8_t type); 189 }; 190 191 struct MyOpusExtractor : public MyOggExtractor { 192 static const int32_t kOpusSampleRate = 48000; 193 static const int64_t kOpusSeekPreRollUs = 80000; // 80 ms 194 195 explicit MyOpusExtractor(const sp<DataSource> &source) 196 : MyOggExtractor(source, MEDIA_MIMETYPE_AUDIO_OPUS, /*numHeaders*/ 2, kOpusSeekPreRollUs), 197 mChannelCount(0), 198 mCodecDelay(0), 199 mStartGranulePosition(-1) { 200 } 201 202 virtual uint64_t approxBitrate() const { 203 return 0; 204 } 205 206 virtual status_t readNextPacket(MediaBuffer **buffer); 207 208 protected: 209 virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const; 210 virtual status_t verifyHeader(MediaBuffer *buffer, uint8_t type); 211 212 private: 213 status_t verifyOpusHeader(MediaBuffer *buffer); 214 status_t verifyOpusComments(MediaBuffer *buffer); 215 uint32_t getNumSamplesInPacket(MediaBuffer *buffer) const; 216 217 uint8_t mChannelCount; 218 uint16_t mCodecDelay; 219 int64_t mStartGranulePosition; 220 }; 221 222 static void extractAlbumArt( 223 const sp<MetaData> &fileMeta, const void *data, size_t size); 224 225 //////////////////////////////////////////////////////////////////////////////// 226 227 OggSource::OggSource(const sp<OggExtractor> &extractor) 228 : mExtractor(extractor), 229 mStarted(false) { 230 } 231 232 OggSource::~OggSource() { 233 if (mStarted) { 234 stop(); 235 } 236 } 237 238 sp<MetaData> OggSource::getFormat() { 239 return mExtractor->mImpl->getFormat(); 240 } 241 242 status_t OggSource::start(MetaData * /* params */) { 243 if (mStarted) { 244 return INVALID_OPERATION; 245 } 246 247 mStarted = true; 248 249 return OK; 250 } 251 252 status_t OggSource::stop() { 253 mStarted = false; 254 255 return OK; 256 } 257 258 status_t OggSource::read( 259 MediaBuffer **out, const ReadOptions *options) { 260 *out = NULL; 261 262 int64_t seekTimeUs; 263 ReadOptions::SeekMode mode; 264 if (options && options->getSeekTo(&seekTimeUs, &mode)) { 265 status_t err = mExtractor->mImpl->seekToTime(seekTimeUs); 266 if (err != OK) { 267 return err; 268 } 269 } 270 271 MediaBuffer *packet; 272 status_t err = mExtractor->mImpl->readNextPacket(&packet); 273 274 if (err != OK) { 275 return err; 276 } 277 278 #if 0 279 int64_t timeUs; 280 if (packet->meta_data()->findInt64(kKeyTime, &timeUs)) { 281 ALOGI("found time = %lld us", timeUs); 282 } else { 283 ALOGI("NO time"); 284 } 285 #endif 286 287 packet->meta_data()->setInt32(kKeyIsSyncFrame, 1); 288 289 *out = packet; 290 291 return OK; 292 } 293 294 //////////////////////////////////////////////////////////////////////////////// 295 296 MyOggExtractor::MyOggExtractor( 297 const sp<DataSource> &source, 298 const char *mimeType, 299 size_t numHeaders, 300 int64_t seekPreRollUs) 301 : mSource(source), 302 mOffset(0), 303 mCurGranulePosition(0), 304 mPrevGranulePosition(0), 305 mCurrentPageSize(0), 306 mFirstPacketInPage(true), 307 mCurrentPageSamples(0), 308 mNextLaceIndex(0), 309 mMimeType(mimeType), 310 mNumHeaders(numHeaders), 311 mSeekPreRollUs(seekPreRollUs), 312 mFirstDataOffset(-1) { 313 mCurrentPage.mNumSegments = 0; 314 315 vorbis_info_init(&mVi); 316 vorbis_comment_init(&mVc); 317 } 318 319 MyOggExtractor::~MyOggExtractor() { 320 vorbis_comment_clear(&mVc); 321 vorbis_info_clear(&mVi); 322 } 323 324 sp<MetaData> MyOggExtractor::getFormat() const { 325 return mMeta; 326 } 327 328 status_t MyOggExtractor::findNextPage( 329 off64_t startOffset, off64_t *pageOffset) { 330 *pageOffset = startOffset; 331 332 for (;;) { 333 char signature[4]; 334 ssize_t n = mSource->readAt(*pageOffset, &signature, 4); 335 336 if (n < 4) { 337 *pageOffset = 0; 338 339 return (n < 0) ? n : (status_t)ERROR_END_OF_STREAM; 340 } 341 342 if (!memcmp(signature, "OggS", 4)) { 343 if (*pageOffset > startOffset) { 344 ALOGV("skipped %lld bytes of junk to reach next frame", 345 (long long)(*pageOffset - startOffset)); 346 } 347 348 return OK; 349 } 350 351 ++*pageOffset; 352 } 353 } 354 355 // Given the offset of the "current" page, find the page immediately preceding 356 // it (if any) and return its granule position. 357 // To do this we back up from the "current" page's offset until we find any 358 // page preceding it and then scan forward to just before the current page. 359 status_t MyOggExtractor::findPrevGranulePosition( 360 off64_t pageOffset, uint64_t *granulePos) { 361 *granulePos = 0; 362 363 off64_t prevPageOffset = 0; 364 off64_t prevGuess = pageOffset; 365 for (;;) { 366 if (prevGuess >= 5000) { 367 prevGuess -= 5000; 368 } else { 369 prevGuess = 0; 370 } 371 372 ALOGV("backing up %lld bytes", (long long)(pageOffset - prevGuess)); 373 374 status_t err = findNextPage(prevGuess, &prevPageOffset); 375 if (err == ERROR_END_OF_STREAM) { 376 // We are at the last page and didn't back off enough; 377 // back off 5000 bytes more and try again. 378 continue; 379 } else if (err != OK) { 380 return err; 381 } 382 383 if (prevPageOffset < pageOffset || prevGuess == 0) { 384 break; 385 } 386 } 387 388 if (prevPageOffset == pageOffset) { 389 // We did not find a page preceding this one. 390 return UNKNOWN_ERROR; 391 } 392 393 ALOGV("prevPageOffset at %lld, pageOffset at %lld", 394 (long long)prevPageOffset, (long long)pageOffset); 395 396 for (;;) { 397 Page prevPage; 398 ssize_t n = readPage(prevPageOffset, &prevPage); 399 400 if (n <= 0) { 401 return (status_t)n; 402 } 403 404 prevPageOffset += n; 405 406 if (prevPageOffset == pageOffset) { 407 *granulePos = prevPage.mGranulePosition; 408 return OK; 409 } 410 } 411 } 412 413 status_t MyOggExtractor::seekToTime(int64_t timeUs) { 414 timeUs -= mSeekPreRollUs; 415 if (timeUs < 0) { 416 timeUs = 0; 417 } 418 419 if (mTableOfContents.isEmpty()) { 420 // Perform approximate seeking based on avg. bitrate. 421 uint64_t bps = approxBitrate(); 422 if (bps <= 0) { 423 return INVALID_OPERATION; 424 } 425 426 off64_t pos = timeUs * bps / 8000000ll; 427 428 ALOGV("seeking to offset %lld", (long long)pos); 429 return seekToOffset(pos); 430 } 431 432 size_t left = 0; 433 size_t right_plus_one = mTableOfContents.size(); 434 while (left < right_plus_one) { 435 size_t center = left + (right_plus_one - left) / 2; 436 437 const TOCEntry &entry = mTableOfContents.itemAt(center); 438 439 if (timeUs < entry.mTimeUs) { 440 right_plus_one = center; 441 } else if (timeUs > entry.mTimeUs) { 442 left = center + 1; 443 } else { 444 left = center; 445 break; 446 } 447 } 448 449 if (left == mTableOfContents.size()) { 450 --left; 451 } 452 453 const TOCEntry &entry = mTableOfContents.itemAt(left); 454 455 ALOGV("seeking to entry %zu / %zu at offset %lld", 456 left, mTableOfContents.size(), (long long)entry.mPageOffset); 457 458 return seekToOffset(entry.mPageOffset); 459 } 460 461 status_t MyOggExtractor::seekToOffset(off64_t offset) { 462 if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) { 463 // Once we know where the actual audio data starts (past the headers) 464 // don't ever seek to anywhere before that. 465 offset = mFirstDataOffset; 466 } 467 468 off64_t pageOffset; 469 status_t err = findNextPage(offset, &pageOffset); 470 471 if (err != OK) { 472 return err; 473 } 474 475 // We found the page we wanted to seek to, but we'll also need 476 // the page preceding it to determine how many valid samples are on 477 // this page. 478 findPrevGranulePosition(pageOffset, &mPrevGranulePosition); 479 480 mOffset = pageOffset; 481 482 mCurrentPageSize = 0; 483 mFirstPacketInPage = true; 484 mCurrentPageSamples = 0; 485 mCurrentPage.mNumSegments = 0; 486 mCurrentPage.mPrevPacketSize = -1; 487 mNextLaceIndex = 0; 488 489 // XXX what if new page continues packet from last??? 490 491 return OK; 492 } 493 494 ssize_t MyOggExtractor::readPage(off64_t offset, Page *page) { 495 uint8_t header[27]; 496 ssize_t n; 497 if ((n = mSource->readAt(offset, header, sizeof(header))) 498 < (ssize_t)sizeof(header)) { 499 ALOGV("failed to read %zu bytes at offset %#016llx, got %zd bytes", 500 sizeof(header), (long long)offset, n); 501 502 if (n < 0) { 503 return n; 504 } else if (n == 0) { 505 return ERROR_END_OF_STREAM; 506 } else { 507 return ERROR_IO; 508 } 509 } 510 511 if (memcmp(header, "OggS", 4)) { 512 return ERROR_MALFORMED; 513 } 514 515 if (header[4] != 0) { 516 // Wrong version. 517 518 return ERROR_UNSUPPORTED; 519 } 520 521 page->mFlags = header[5]; 522 523 if (page->mFlags & ~7) { 524 // Only bits 0-2 are defined in version 0. 525 return ERROR_MALFORMED; 526 } 527 528 page->mGranulePosition = U64LE_AT(&header[6]); 529 530 #if 0 531 printf("granulePosition = %llu (0x%llx)\n", 532 page->mGranulePosition, page->mGranulePosition); 533 #endif 534 535 page->mSerialNo = U32LE_AT(&header[14]); 536 page->mPageNo = U32LE_AT(&header[18]); 537 538 page->mNumSegments = header[26]; 539 if (mSource->readAt( 540 offset + sizeof(header), page->mLace, page->mNumSegments) 541 < (ssize_t)page->mNumSegments) { 542 return ERROR_IO; 543 } 544 545 size_t totalSize = 0;; 546 for (size_t i = 0; i < page->mNumSegments; ++i) { 547 totalSize += page->mLace[i]; 548 } 549 550 #if 0 551 String8 tmp; 552 for (size_t i = 0; i < page->mNumSegments; ++i) { 553 char x[32]; 554 sprintf(x, "%s%u", i > 0 ? ", " : "", (unsigned)page->mLace[i]); 555 556 tmp.append(x); 557 } 558 559 ALOGV("%c %s", page->mFlags & 1 ? '+' : ' ', tmp.string()); 560 #endif 561 562 return sizeof(header) + page->mNumSegments + totalSize; 563 } 564 565 status_t MyOpusExtractor::readNextPacket(MediaBuffer **out) { 566 if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) { 567 // The first sample might not start at time 0; find out where by subtracting 568 // the number of samples on the first page from the granule position 569 // (position of last complete sample) of the first page. This happens 570 // the first time before we attempt to read a packet from the first page. 571 MediaBuffer *mBuf; 572 uint32_t numSamples = 0; 573 uint64_t curGranulePosition = 0; 574 while (true) { 575 status_t err = _readNextPacket(&mBuf, /* calcVorbisTimestamp = */false); 576 if (err != OK && err != ERROR_END_OF_STREAM) { 577 return err; 578 } 579 // First two pages are header pages. 580 if (err == ERROR_END_OF_STREAM || mCurrentPage.mPageNo > 2) { 581 if (mBuf != NULL) { 582 mBuf->release(); 583 mBuf = NULL; 584 } 585 break; 586 } 587 curGranulePosition = mCurrentPage.mGranulePosition; 588 numSamples += getNumSamplesInPacket(mBuf); 589 mBuf->release(); 590 mBuf = NULL; 591 } 592 593 if (curGranulePosition > numSamples) { 594 mStartGranulePosition = curGranulePosition - numSamples; 595 } else { 596 mStartGranulePosition = 0; 597 } 598 seekToOffset(0); 599 } 600 601 status_t err = _readNextPacket(out, /* calcVorbisTimestamp = */false); 602 if (err != OK) { 603 return err; 604 } 605 606 int32_t currentPageSamples; 607 // Calculate timestamps by accumulating durations starting from the first sample of a page; 608 // We assume that we only seek to page boundaries. 609 if ((*out)->meta_data()->findInt32(kKeyValidSamples, ¤tPageSamples)) { 610 // first packet in page 611 if (mOffset == mFirstDataOffset) { 612 currentPageSamples -= mStartGranulePosition; 613 (*out)->meta_data()->setInt32(kKeyValidSamples, currentPageSamples); 614 } 615 mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples; 616 } 617 618 int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition); 619 (*out)->meta_data()->setInt64(kKeyTime, timeUs); 620 621 uint32_t frames = getNumSamplesInPacket(*out); 622 mCurGranulePosition += frames; 623 return OK; 624 } 625 626 uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBuffer *buffer) const { 627 if (buffer == NULL || buffer->range_length() < 1) { 628 return 0; 629 } 630 631 uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset(); 632 uint8_t toc = data[0]; 633 uint8_t config = (toc >> 3) & 0x1f; 634 uint32_t frameSizesUs[] = { 635 10000, 20000, 40000, 60000, // 0...3 636 10000, 20000, 40000, 60000, // 4...7 637 10000, 20000, 40000, 60000, // 8...11 638 10000, 20000, // 12...13 639 10000, 20000, // 14...15 640 2500, 5000, 10000, 20000, // 16...19 641 2500, 5000, 10000, 20000, // 20...23 642 2500, 5000, 10000, 20000, // 24...27 643 2500, 5000, 10000, 20000 // 28...31 644 }; 645 uint32_t frameSizeUs = frameSizesUs[config]; 646 647 uint32_t numFrames; 648 uint8_t c = toc & 3; 649 switch (c) { 650 case 0: 651 numFrames = 1; 652 break; 653 case 1: 654 case 2: 655 numFrames = 2; 656 break; 657 case 3: 658 if (buffer->range_length() < 3) { 659 numFrames = 0; 660 } else { 661 numFrames = data[2] & 0x3f; 662 } 663 break; 664 default: 665 TRESPASS(); 666 } 667 668 uint32_t numSamples = frameSizeUs * numFrames * kOpusSampleRate / 1000000; 669 return numSamples; 670 } 671 672 status_t MyOggExtractor::_readNextPacket(MediaBuffer **out, bool calcVorbisTimestamp) { 673 *out = NULL; 674 675 MediaBuffer *buffer = NULL; 676 int64_t timeUs = -1; 677 678 for (;;) { 679 size_t i; 680 size_t packetSize = 0; 681 bool gotFullPacket = false; 682 for (i = mNextLaceIndex; i < mCurrentPage.mNumSegments; ++i) { 683 uint8_t lace = mCurrentPage.mLace[i]; 684 685 packetSize += lace; 686 687 if (lace < 255) { 688 gotFullPacket = true; 689 ++i; 690 break; 691 } 692 } 693 694 if (mNextLaceIndex < mCurrentPage.mNumSegments) { 695 off64_t dataOffset = mOffset + 27 + mCurrentPage.mNumSegments; 696 for (size_t j = 0; j < mNextLaceIndex; ++j) { 697 dataOffset += mCurrentPage.mLace[j]; 698 } 699 700 size_t fullSize = packetSize; 701 if (buffer != NULL) { 702 fullSize += buffer->range_length(); 703 } 704 if (fullSize > 16 * 1024 * 1024) { // arbitrary limit of 16 MB packet size 705 if (buffer != NULL) { 706 buffer->release(); 707 } 708 ALOGE("b/36592202"); 709 return ERROR_MALFORMED; 710 } 711 MediaBuffer *tmp = new (std::nothrow) MediaBuffer(fullSize); 712 if (tmp == NULL) { 713 if (buffer != NULL) { 714 buffer->release(); 715 } 716 ALOGE("b/36592202"); 717 return ERROR_MALFORMED; 718 } 719 if (buffer != NULL) { 720 memcpy(tmp->data(), buffer->data(), buffer->range_length()); 721 tmp->set_range(0, buffer->range_length()); 722 buffer->release(); 723 } else { 724 tmp->set_range(0, 0); 725 } 726 buffer = tmp; 727 728 ssize_t n = mSource->readAt( 729 dataOffset, 730 (uint8_t *)buffer->data() + buffer->range_length(), 731 packetSize); 732 733 if (n < (ssize_t)packetSize) { 734 buffer->release(); 735 ALOGV("failed to read %zu bytes at %#016llx, got %zd bytes", 736 packetSize, (long long)dataOffset, n); 737 return ERROR_IO; 738 } 739 740 buffer->set_range(0, fullSize); 741 742 mNextLaceIndex = i; 743 744 if (gotFullPacket) { 745 // We've just read the entire packet. 746 747 if (mFirstPacketInPage) { 748 buffer->meta_data()->setInt32( 749 kKeyValidSamples, mCurrentPageSamples); 750 mFirstPacketInPage = false; 751 } 752 753 if (calcVorbisTimestamp) { 754 int32_t curBlockSize = getPacketBlockSize(buffer); 755 if (mCurrentPage.mPrevPacketSize < 0) { 756 mCurrentPage.mPrevPacketSize = curBlockSize; 757 mCurrentPage.mPrevPacketPos = 758 mCurrentPage.mGranulePosition - mCurrentPageSamples; 759 timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; 760 } else { 761 // The effective block size is the average of the two overlapped blocks 762 int32_t actualBlockSize = 763 (curBlockSize + mCurrentPage.mPrevPacketSize) / 2; 764 timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate; 765 // The actual size output by the decoder will be half the effective 766 // size, due to the overlap 767 mCurrentPage.mPrevPacketPos += actualBlockSize / 2; 768 mCurrentPage.mPrevPacketSize = curBlockSize; 769 } 770 buffer->meta_data()->setInt64(kKeyTime, timeUs); 771 } 772 *out = buffer; 773 774 return OK; 775 } 776 777 // fall through, the buffer now contains the start of the packet. 778 } 779 780 CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments); 781 782 mOffset += mCurrentPageSize; 783 ssize_t n = readPage(mOffset, &mCurrentPage); 784 785 if (n <= 0) { 786 if (buffer) { 787 buffer->release(); 788 buffer = NULL; 789 } 790 791 ALOGV("readPage returned %zd", n); 792 793 return n < 0 ? n : (status_t)ERROR_END_OF_STREAM; 794 } 795 796 // Prevent a harmless unsigned integer overflow by clamping to 0 797 if (mCurrentPage.mGranulePosition >= mPrevGranulePosition) { 798 mCurrentPageSamples = 799 mCurrentPage.mGranulePosition - mPrevGranulePosition; 800 } else { 801 mCurrentPageSamples = 0; 802 } 803 mFirstPacketInPage = true; 804 805 mPrevGranulePosition = mCurrentPage.mGranulePosition; 806 807 mCurrentPageSize = n; 808 mNextLaceIndex = 0; 809 810 if (buffer != NULL) { 811 if ((mCurrentPage.mFlags & 1) == 0) { 812 // This page does not continue the packet, i.e. the packet 813 // is already complete. 814 815 if (timeUs >= 0) { 816 buffer->meta_data()->setInt64(kKeyTime, timeUs); 817 } 818 819 buffer->meta_data()->setInt32( 820 kKeyValidSamples, mCurrentPageSamples); 821 mFirstPacketInPage = false; 822 823 *out = buffer; 824 825 return OK; 826 } 827 } 828 } 829 } 830 831 status_t MyOggExtractor::init() { 832 mMeta = new MetaData; 833 mMeta->setCString(kKeyMIMEType, mMimeType); 834 835 status_t err; 836 MediaBuffer *packet; 837 for (size_t i = 0; i < mNumHeaders; ++i) { 838 // ignore timestamp for configuration packets 839 if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != OK) { 840 return err; 841 } 842 ALOGV("read packet of size %zu\n", packet->range_length()); 843 err = verifyHeader(packet, /* type = */ i * 2 + 1); 844 packet->release(); 845 packet = NULL; 846 if (err != OK) { 847 return err; 848 } 849 } 850 851 mFirstDataOffset = mOffset + mCurrentPageSize; 852 853 off64_t size; 854 uint64_t lastGranulePosition; 855 if (!(mSource->flags() & DataSource::kIsCachingDataSource) 856 && mSource->getSize(&size) == OK 857 && findPrevGranulePosition(size, &lastGranulePosition) == OK) { 858 // Let's assume it's cheap to seek to the end. 859 // The granule position of the final page in the stream will 860 // give us the exact duration of the content, something that 861 // we can only approximate using avg. bitrate if seeking to 862 // the end is too expensive or impossible (live streaming). 863 864 int64_t durationUs = getTimeUsOfGranule(lastGranulePosition); 865 866 mMeta->setInt64(kKeyDuration, durationUs); 867 868 buildTableOfContents(); 869 } 870 871 return OK; 872 } 873 874 void MyOggExtractor::buildTableOfContents() { 875 off64_t offset = mFirstDataOffset; 876 Page page; 877 ssize_t pageSize; 878 while ((pageSize = readPage(offset, &page)) > 0) { 879 mTableOfContents.push(); 880 881 TOCEntry &entry = 882 mTableOfContents.editItemAt(mTableOfContents.size() - 1); 883 884 entry.mPageOffset = offset; 885 entry.mTimeUs = getTimeUsOfGranule(page.mGranulePosition); 886 887 offset += (size_t)pageSize; 888 } 889 890 // Limit the maximum amount of RAM we spend on the table of contents, 891 // if necessary thin out the table evenly to trim it down to maximum 892 // size. 893 894 static const size_t kMaxTOCSize = 8192; 895 static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry); 896 897 size_t numerator = mTableOfContents.size(); 898 899 if (numerator > kMaxNumTOCEntries) { 900 size_t denom = numerator - kMaxNumTOCEntries; 901 902 size_t accum = 0; 903 for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) { 904 accum += denom; 905 if (accum >= numerator) { 906 mTableOfContents.removeAt(i); 907 accum -= numerator; 908 } 909 } 910 } 911 } 912 913 int32_t MyOggExtractor::getPacketBlockSize(MediaBuffer *buffer) { 914 const uint8_t *data = 915 (const uint8_t *)buffer->data() + buffer->range_offset(); 916 917 size_t size = buffer->range_length(); 918 919 ogg_buffer buf; 920 buf.data = (uint8_t *)data; 921 buf.size = size; 922 buf.refcount = 1; 923 buf.ptr.owner = NULL; 924 925 ogg_reference ref; 926 ref.buffer = &buf; 927 ref.begin = 0; 928 ref.length = size; 929 ref.next = NULL; 930 931 ogg_packet pack; 932 pack.packet = &ref; 933 pack.bytes = ref.length; 934 pack.b_o_s = 0; 935 pack.e_o_s = 0; 936 pack.granulepos = 0; 937 pack.packetno = 0; 938 939 return vorbis_packet_blocksize(&mVi, &pack); 940 } 941 942 int64_t MyOpusExtractor::getTimeUsOfGranule(uint64_t granulePos) const { 943 uint64_t pcmSamplePosition = 0; 944 if (granulePos > mCodecDelay) { 945 pcmSamplePosition = granulePos - mCodecDelay; 946 } 947 if (pcmSamplePosition > INT64_MAX / 1000000ll) { 948 return INT64_MAX; 949 } 950 return pcmSamplePosition * 1000000ll / kOpusSampleRate; 951 } 952 953 status_t MyOpusExtractor::verifyHeader(MediaBuffer *buffer, uint8_t type) { 954 switch (type) { 955 // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean 956 // header and comments such that we can share code with MyVorbisExtractor. 957 case 1: 958 return verifyOpusHeader(buffer); 959 case 3: 960 return verifyOpusComments(buffer); 961 default: 962 return INVALID_OPERATION; 963 } 964 } 965 966 status_t MyOpusExtractor::verifyOpusHeader(MediaBuffer *buffer) { 967 const size_t kOpusHeaderSize = 19; 968 const uint8_t *data = 969 (const uint8_t *)buffer->data() + buffer->range_offset(); 970 971 size_t size = buffer->range_length(); 972 973 if (size < kOpusHeaderSize 974 || memcmp(data, "OpusHead", 8) 975 || /* version = */ data[8] != 1) { 976 return ERROR_MALFORMED; 977 } 978 979 mChannelCount = data[9]; 980 mCodecDelay = U16LE_AT(&data[10]); 981 982 mMeta->setData(kKeyOpusHeader, 0, data, size); 983 mMeta->setInt32(kKeySampleRate, kOpusSampleRate); 984 mMeta->setInt32(kKeyChannelCount, mChannelCount); 985 mMeta->setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/); 986 mMeta->setInt64(kKeyOpusCodecDelay /* ns */, 987 mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate); 988 989 return OK; 990 } 991 992 status_t MyOpusExtractor::verifyOpusComments(MediaBuffer *buffer) { 993 // add artificial framing bit so we can reuse _vorbis_unpack_comment 994 int32_t commentSize = buffer->range_length() + 1; 995 sp<ABuffer> aBuf = new ABuffer(commentSize); 996 if (aBuf->capacity() <= buffer->range_length()) { 997 return ERROR_MALFORMED; 998 } 999 1000 uint8_t* commentData = aBuf->data(); 1001 memcpy(commentData, 1002 (uint8_t *)buffer->data() + buffer->range_offset(), 1003 buffer->range_length()); 1004 1005 ogg_buffer buf; 1006 buf.data = commentData; 1007 buf.size = commentSize; 1008 buf.refcount = 1; 1009 buf.ptr.owner = NULL; 1010 1011 ogg_reference ref; 1012 ref.buffer = &buf; 1013 ref.begin = 0; 1014 ref.length = commentSize; 1015 ref.next = NULL; 1016 1017 oggpack_buffer bits; 1018 oggpack_readinit(&bits, &ref); 1019 1020 // skip 'OpusTags' 1021 const char *OpusTags = "OpusTags"; 1022 const int32_t headerLen = strlen(OpusTags); 1023 int32_t framingBitOffset = headerLen; 1024 for (int i = 0; i < headerLen; ++i) { 1025 char chr = oggpack_read(&bits, 8); 1026 if (chr != OpusTags[i]) { 1027 return ERROR_MALFORMED; 1028 } 1029 } 1030 1031 int32_t vendorLen = oggpack_read(&bits, 32); 1032 framingBitOffset += 4; 1033 if (vendorLen < 0 || vendorLen > commentSize - 8) { 1034 return ERROR_MALFORMED; 1035 } 1036 // skip vendor string 1037 framingBitOffset += vendorLen; 1038 for (int i = 0; i < vendorLen; ++i) { 1039 oggpack_read(&bits, 8); 1040 } 1041 1042 int32_t n = oggpack_read(&bits, 32); 1043 framingBitOffset += 4; 1044 if (n < 0 || n > ((commentSize - oggpack_bytes(&bits)) >> 2)) { 1045 return ERROR_MALFORMED; 1046 } 1047 for (int i = 0; i < n; ++i) { 1048 int32_t len = oggpack_read(&bits, 32); 1049 framingBitOffset += 4; 1050 if (len < 0 || len > (commentSize - oggpack_bytes(&bits))) { 1051 return ERROR_MALFORMED; 1052 } 1053 framingBitOffset += len; 1054 for (int j = 0; j < len; ++j) { 1055 oggpack_read(&bits, 8); 1056 } 1057 } 1058 if (framingBitOffset < 0 || framingBitOffset >= commentSize) { 1059 return ERROR_MALFORMED; 1060 } 1061 commentData[framingBitOffset] = 1; 1062 1063 buf.data = commentData + headerLen; 1064 buf.size = commentSize - headerLen; 1065 buf.refcount = 1; 1066 buf.ptr.owner = NULL; 1067 1068 ref.buffer = &buf; 1069 ref.begin = 0; 1070 ref.length = commentSize - headerLen; 1071 ref.next = NULL; 1072 1073 oggpack_readinit(&bits, &ref); 1074 int err = _vorbis_unpack_comment(&mVc, &bits); 1075 if (0 != err) { 1076 return ERROR_MALFORMED; 1077 } 1078 1079 parseFileMetaData(); 1080 return OK; 1081 } 1082 1083 status_t MyVorbisExtractor::verifyHeader( 1084 MediaBuffer *buffer, uint8_t type) { 1085 const uint8_t *data = 1086 (const uint8_t *)buffer->data() + buffer->range_offset(); 1087 1088 size_t size = buffer->range_length(); 1089 1090 if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) { 1091 return ERROR_MALFORMED; 1092 } 1093 1094 ogg_buffer buf; 1095 buf.data = (uint8_t *)data; 1096 buf.size = size; 1097 buf.refcount = 1; 1098 buf.ptr.owner = NULL; 1099 1100 ogg_reference ref; 1101 ref.buffer = &buf; 1102 ref.begin = 0; 1103 ref.length = size; 1104 ref.next = NULL; 1105 1106 oggpack_buffer bits; 1107 oggpack_readinit(&bits, &ref); 1108 1109 if (oggpack_read(&bits, 8) != type) { 1110 return ERROR_MALFORMED; 1111 } 1112 for (size_t i = 0; i < 6; ++i) { 1113 oggpack_read(&bits, 8); // skip 'vorbis' 1114 } 1115 1116 switch (type) { 1117 case 1: 1118 { 1119 if (0 != _vorbis_unpack_info(&mVi, &bits)) { 1120 return ERROR_MALFORMED; 1121 } 1122 1123 mMeta->setData(kKeyVorbisInfo, 0, data, size); 1124 mMeta->setInt32(kKeySampleRate, mVi.rate); 1125 mMeta->setInt32(kKeyChannelCount, mVi.channels); 1126 1127 ALOGV("lower-bitrate = %ld", mVi.bitrate_lower); 1128 ALOGV("upper-bitrate = %ld", mVi.bitrate_upper); 1129 ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal); 1130 ALOGV("window-bitrate = %ld", mVi.bitrate_window); 1131 ALOGV("blocksizes: %d/%d", 1132 vorbis_info_blocksize(&mVi, 0), 1133 vorbis_info_blocksize(&mVi, 1) 1134 ); 1135 1136 off64_t size; 1137 if (mSource->getSize(&size) == OK) { 1138 uint64_t bps = approxBitrate(); 1139 if (bps != 0) { 1140 mMeta->setInt64(kKeyDuration, size * 8000000ll / bps); 1141 } 1142 } 1143 break; 1144 } 1145 1146 case 3: 1147 { 1148 if (0 != _vorbis_unpack_comment(&mVc, &bits)) { 1149 return ERROR_MALFORMED; 1150 } 1151 1152 parseFileMetaData(); 1153 break; 1154 } 1155 1156 case 5: 1157 { 1158 if (0 != _vorbis_unpack_books(&mVi, &bits)) { 1159 return ERROR_MALFORMED; 1160 } 1161 1162 mMeta->setData(kKeyVorbisBooks, 0, data, size); 1163 break; 1164 } 1165 } 1166 1167 return OK; 1168 } 1169 1170 uint64_t MyVorbisExtractor::approxBitrate() const { 1171 if (mVi.bitrate_nominal != 0) { 1172 return mVi.bitrate_nominal; 1173 } 1174 1175 return (mVi.bitrate_lower + mVi.bitrate_upper) / 2; 1176 } 1177 1178 void MyOggExtractor::parseFileMetaData() { 1179 mFileMeta = new MetaData; 1180 mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG); 1181 1182 for (int i = 0; i < mVc.comments; ++i) { 1183 const char *comment = mVc.user_comments[i]; 1184 size_t commentLength = mVc.comment_lengths[i]; 1185 parseVorbisComment(mFileMeta, comment, commentLength); 1186 //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]); 1187 } 1188 } 1189 1190 void parseVorbisComment( 1191 const sp<MetaData> &fileMeta, const char *comment, size_t commentLength) 1192 { 1193 struct { 1194 const char *const mTag; 1195 uint32_t mKey; 1196 } kMap[] = { 1197 { "TITLE", kKeyTitle }, 1198 { "ARTIST", kKeyArtist }, 1199 { "ALBUMARTIST", kKeyAlbumArtist }, 1200 { "ALBUM ARTIST", kKeyAlbumArtist }, 1201 { "COMPILATION", kKeyCompilation }, 1202 { "ALBUM", kKeyAlbum }, 1203 { "COMPOSER", kKeyComposer }, 1204 { "GENRE", kKeyGenre }, 1205 { "AUTHOR", kKeyAuthor }, 1206 { "TRACKNUMBER", kKeyCDTrackNumber }, 1207 { "DISCNUMBER", kKeyDiscNumber }, 1208 { "DATE", kKeyDate }, 1209 { "YEAR", kKeyYear }, 1210 { "LYRICIST", kKeyWriter }, 1211 { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, 1212 { "ANDROID_LOOP", kKeyAutoLoop }, 1213 }; 1214 1215 for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { 1216 size_t tagLen = strlen(kMap[j].mTag); 1217 if (!strncasecmp(kMap[j].mTag, comment, tagLen) 1218 && comment[tagLen] == '=') { 1219 if (kMap[j].mKey == kKeyAlbumArt) { 1220 extractAlbumArt( 1221 fileMeta, 1222 &comment[tagLen + 1], 1223 commentLength - tagLen - 1); 1224 } else if (kMap[j].mKey == kKeyAutoLoop) { 1225 if (!strcasecmp(&comment[tagLen + 1], "true")) { 1226 fileMeta->setInt32(kKeyAutoLoop, true); 1227 } 1228 } else { 1229 fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); 1230 } 1231 } 1232 } 1233 1234 } 1235 1236 static void extractAlbumArt( 1237 const sp<MetaData> &fileMeta, const void *data, size_t size) { 1238 ALOGV("extractAlbumArt from '%s'", (const char *)data); 1239 1240 sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size)); 1241 if (flacBuffer == NULL) { 1242 ALOGE("malformed base64 encoded data."); 1243 return; 1244 } 1245 1246 size_t flacSize = flacBuffer->size(); 1247 uint8_t *flac = flacBuffer->data(); 1248 ALOGV("got flac of size %zu", flacSize); 1249 1250 uint32_t picType; 1251 uint32_t typeLen; 1252 uint32_t descLen; 1253 uint32_t dataLen; 1254 char type[128]; 1255 1256 if (flacSize < 8) { 1257 return; 1258 } 1259 1260 picType = U32_AT(flac); 1261 1262 if (picType != 3) { 1263 // This is not a front cover. 1264 return; 1265 } 1266 1267 typeLen = U32_AT(&flac[4]); 1268 if (typeLen > sizeof(type) - 1) { 1269 return; 1270 } 1271 1272 // we've already checked above that flacSize >= 8 1273 if (flacSize - 8 < typeLen) { 1274 return; 1275 } 1276 1277 memcpy(type, &flac[8], typeLen); 1278 type[typeLen] = '\0'; 1279 1280 ALOGV("picType = %d, type = '%s'", picType, type); 1281 1282 if (!strcmp(type, "-->")) { 1283 // This is not inline cover art, but an external url instead. 1284 return; 1285 } 1286 1287 if (flacSize < 32 || flacSize - 32 < typeLen) { 1288 return; 1289 } 1290 1291 descLen = U32_AT(&flac[8 + typeLen]); 1292 if (flacSize - 32 - typeLen < descLen) { 1293 return; 1294 } 1295 1296 dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); 1297 1298 // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0 1299 if (flacSize - 32 - typeLen - descLen < dataLen) { 1300 return; 1301 } 1302 1303 ALOGV("got image data, %zu trailing bytes", 1304 flacSize - 32 - typeLen - descLen - dataLen); 1305 1306 fileMeta->setData( 1307 kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); 1308 1309 fileMeta->setCString(kKeyAlbumArtMIME, type); 1310 } 1311 1312 //////////////////////////////////////////////////////////////////////////////// 1313 1314 OggExtractor::OggExtractor(const sp<DataSource> &source) 1315 : mDataSource(source), 1316 mInitCheck(NO_INIT), 1317 mImpl(NULL) { 1318 for (int i = 0; i < 2; ++i) { 1319 if (mImpl != NULL) { 1320 delete mImpl; 1321 } 1322 if (i == 0) { 1323 mImpl = new MyVorbisExtractor(mDataSource); 1324 } else { 1325 mImpl = new MyOpusExtractor(mDataSource); 1326 } 1327 mInitCheck = mImpl->seekToOffset(0); 1328 1329 if (mInitCheck == OK) { 1330 mInitCheck = mImpl->init(); 1331 if (mInitCheck == OK) { 1332 break; 1333 } 1334 } 1335 } 1336 } 1337 1338 OggExtractor::~OggExtractor() { 1339 delete mImpl; 1340 mImpl = NULL; 1341 } 1342 1343 size_t OggExtractor::countTracks() { 1344 return mInitCheck != OK ? 0 : 1; 1345 } 1346 1347 sp<IMediaSource> OggExtractor::getTrack(size_t index) { 1348 if (index >= 1) { 1349 return NULL; 1350 } 1351 1352 return new OggSource(this); 1353 } 1354 1355 sp<MetaData> OggExtractor::getTrackMetaData( 1356 size_t index, uint32_t /* flags */) { 1357 if (index >= 1) { 1358 return NULL; 1359 } 1360 1361 return mImpl->getFormat(); 1362 } 1363 1364 sp<MetaData> OggExtractor::getMetaData() { 1365 return mImpl->getFileMetaData(); 1366 } 1367 1368 bool SniffOgg( 1369 const sp<DataSource> &source, String8 *mimeType, float *confidence, 1370 sp<AMessage> *) { 1371 char tmp[4]; 1372 if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) { 1373 return false; 1374 } 1375 1376 mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_OGG); 1377 *confidence = 0.2f; 1378 1379 return true; 1380 } 1381 1382 } // namespace android 1383