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
37extern "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
46namespace android {
47
48struct 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
59protected:
60    virtual ~OggSource();
61
62private:
63    sp<OggExtractor> mExtractor;
64    bool mStarted;
65
66    OggSource(const OggSource &);
67    OggSource &operator=(const OggSource &);
68};
69
70struct 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
91protected:
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
166struct 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
180protected:
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
191struct 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
208protected:
209    virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const;
210    virtual status_t verifyHeader(MediaBuffer *buffer, uint8_t type);
211
212private:
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
222static void extractAlbumArt(
223        const sp<MetaData> &fileMeta, const void *data, size_t size);
224
225////////////////////////////////////////////////////////////////////////////////
226
227OggSource::OggSource(const sp<OggExtractor> &extractor)
228    : mExtractor(extractor),
229      mStarted(false) {
230}
231
232OggSource::~OggSource() {
233    if (mStarted) {
234        stop();
235    }
236}
237
238sp<MetaData> OggSource::getFormat() {
239    return mExtractor->mImpl->getFormat();
240}
241
242status_t OggSource::start(MetaData * /* params */) {
243    if (mStarted) {
244        return INVALID_OPERATION;
245    }
246
247    mStarted = true;
248
249    return OK;
250}
251
252status_t OggSource::stop() {
253    mStarted = false;
254
255    return OK;
256}
257
258status_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
296MyOggExtractor::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
319MyOggExtractor::~MyOggExtractor() {
320    vorbis_comment_clear(&mVc);
321    vorbis_info_clear(&mVi);
322}
323
324sp<MetaData> MyOggExtractor::getFormat() const {
325    return mMeta;
326}
327
328status_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.
359status_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
413status_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
461status_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
494ssize_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
565status_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                break;
582            }
583            curGranulePosition = mCurrentPage.mGranulePosition;
584            numSamples += getNumSamplesInPacket(mBuf);
585            mBuf->release();
586            mBuf = NULL;
587        }
588
589        if (curGranulePosition > numSamples) {
590            mStartGranulePosition = curGranulePosition - numSamples;
591        } else {
592            mStartGranulePosition = 0;
593        }
594        seekToOffset(0);
595    }
596
597    status_t err = _readNextPacket(out, /* calcVorbisTimestamp = */false);
598    if (err != OK) {
599        return err;
600    }
601
602    int32_t currentPageSamples;
603    // Calculate timestamps by accumulating durations starting from the first sample of a page;
604    // We assume that we only seek to page boundaries.
605    if ((*out)->meta_data()->findInt32(kKeyValidSamples, &currentPageSamples)) {
606        // first packet in page
607        if (mOffset == mFirstDataOffset) {
608            currentPageSamples -= mStartGranulePosition;
609            (*out)->meta_data()->setInt32(kKeyValidSamples, currentPageSamples);
610        }
611        mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples;
612    }
613
614    int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition);
615    (*out)->meta_data()->setInt64(kKeyTime, timeUs);
616
617    uint32_t frames = getNumSamplesInPacket(*out);
618    mCurGranulePosition += frames;
619    return OK;
620}
621
622uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBuffer *buffer) const {
623    if (buffer == NULL || buffer->range_length() < 1) {
624        return 0;
625    }
626
627    uint8_t *data = (uint8_t *)buffer->data() + buffer->range_offset();
628    uint8_t toc = data[0];
629    uint8_t config = (toc >> 3) & 0x1f;
630    uint32_t frameSizesUs[] = {
631        10000, 20000, 40000, 60000, // 0...3
632        10000, 20000, 40000, 60000, // 4...7
633        10000, 20000, 40000, 60000, // 8...11
634        10000, 20000,               // 12...13
635        10000, 20000,               // 14...15
636        2500, 5000, 10000, 20000,   // 16...19
637        2500, 5000, 10000, 20000,   // 20...23
638        2500, 5000, 10000, 20000,   // 24...27
639        2500, 5000, 10000, 20000    // 28...31
640    };
641    uint32_t frameSizeUs = frameSizesUs[config];
642
643    uint32_t numFrames;
644    uint8_t c = toc & 3;
645    switch (c) {
646    case 0:
647        numFrames = 1;
648        break;
649    case 1:
650    case 2:
651        numFrames = 2;
652        break;
653    case 3:
654        if (buffer->range_length() < 3) {
655            numFrames = 0;
656        } else {
657            numFrames = data[2] & 0x3f;
658        }
659        break;
660    default:
661        TRESPASS();
662    }
663
664    uint32_t numSamples = frameSizeUs * numFrames * kOpusSampleRate / 1000000;
665    return numSamples;
666}
667
668status_t MyOggExtractor::_readNextPacket(MediaBuffer **out, bool calcVorbisTimestamp) {
669    *out = NULL;
670
671    MediaBuffer *buffer = NULL;
672    int64_t timeUs = -1;
673
674    for (;;) {
675        size_t i;
676        size_t packetSize = 0;
677        bool gotFullPacket = false;
678        for (i = mNextLaceIndex; i < mCurrentPage.mNumSegments; ++i) {
679            uint8_t lace = mCurrentPage.mLace[i];
680
681            packetSize += lace;
682
683            if (lace < 255) {
684                gotFullPacket = true;
685                ++i;
686                break;
687            }
688        }
689
690        if (mNextLaceIndex < mCurrentPage.mNumSegments) {
691            off64_t dataOffset = mOffset + 27 + mCurrentPage.mNumSegments;
692            for (size_t j = 0; j < mNextLaceIndex; ++j) {
693                dataOffset += mCurrentPage.mLace[j];
694            }
695
696            size_t fullSize = packetSize;
697            if (buffer != NULL) {
698                fullSize += buffer->range_length();
699            }
700            if (fullSize > 16 * 1024 * 1024) { // arbitrary limit of 16 MB packet size
701                if (buffer != NULL) {
702                    buffer->release();
703                }
704                ALOGE("b/36592202");
705                return ERROR_MALFORMED;
706            }
707            MediaBuffer *tmp = new (std::nothrow) MediaBuffer(fullSize);
708            if (tmp == NULL) {
709                if (buffer != NULL) {
710                    buffer->release();
711                }
712                ALOGE("b/36592202");
713                return ERROR_MALFORMED;
714            }
715            if (buffer != NULL) {
716                memcpy(tmp->data(), buffer->data(), buffer->range_length());
717                tmp->set_range(0, buffer->range_length());
718                buffer->release();
719            } else {
720                tmp->set_range(0, 0);
721            }
722            buffer = tmp;
723
724            ssize_t n = mSource->readAt(
725                    dataOffset,
726                    (uint8_t *)buffer->data() + buffer->range_length(),
727                    packetSize);
728
729            if (n < (ssize_t)packetSize) {
730                buffer->release();
731                ALOGV("failed to read %zu bytes at %#016llx, got %zd bytes",
732                        packetSize, (long long)dataOffset, n);
733                return ERROR_IO;
734            }
735
736            buffer->set_range(0, fullSize);
737
738            mNextLaceIndex = i;
739
740            if (gotFullPacket) {
741                // We've just read the entire packet.
742
743                if (mFirstPacketInPage) {
744                    buffer->meta_data()->setInt32(
745                            kKeyValidSamples, mCurrentPageSamples);
746                    mFirstPacketInPage = false;
747                }
748
749                if (calcVorbisTimestamp) {
750                    int32_t curBlockSize = getPacketBlockSize(buffer);
751                    if (mCurrentPage.mPrevPacketSize < 0) {
752                        mCurrentPage.mPrevPacketSize = curBlockSize;
753                        mCurrentPage.mPrevPacketPos =
754                                mCurrentPage.mGranulePosition - mCurrentPageSamples;
755                        timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate;
756                    } else {
757                        // The effective block size is the average of the two overlapped blocks
758                        int32_t actualBlockSize =
759                                (curBlockSize + mCurrentPage.mPrevPacketSize) / 2;
760                        timeUs = mCurrentPage.mPrevPacketPos * 1000000ll / mVi.rate;
761                        // The actual size output by the decoder will be half the effective
762                        // size, due to the overlap
763                        mCurrentPage.mPrevPacketPos += actualBlockSize / 2;
764                        mCurrentPage.mPrevPacketSize = curBlockSize;
765                    }
766                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
767                }
768                *out = buffer;
769
770                return OK;
771            }
772
773            // fall through, the buffer now contains the start of the packet.
774        }
775
776        CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
777
778        mOffset += mCurrentPageSize;
779        ssize_t n = readPage(mOffset, &mCurrentPage);
780
781        if (n <= 0) {
782            if (buffer) {
783                buffer->release();
784                buffer = NULL;
785            }
786
787            ALOGV("readPage returned %zd", n);
788
789            return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
790        }
791
792        // Prevent a harmless unsigned integer overflow by clamping to 0
793        if (mCurrentPage.mGranulePosition >= mPrevGranulePosition) {
794            mCurrentPageSamples =
795                    mCurrentPage.mGranulePosition - mPrevGranulePosition;
796        } else {
797            mCurrentPageSamples = 0;
798        }
799        mFirstPacketInPage = true;
800
801        mPrevGranulePosition = mCurrentPage.mGranulePosition;
802
803        mCurrentPageSize = n;
804        mNextLaceIndex = 0;
805
806        if (buffer != NULL) {
807            if ((mCurrentPage.mFlags & 1) == 0) {
808                // This page does not continue the packet, i.e. the packet
809                // is already complete.
810
811                if (timeUs >= 0) {
812                    buffer->meta_data()->setInt64(kKeyTime, timeUs);
813                }
814
815                buffer->meta_data()->setInt32(
816                        kKeyValidSamples, mCurrentPageSamples);
817                mFirstPacketInPage = false;
818
819                *out = buffer;
820
821                return OK;
822            }
823        }
824    }
825}
826
827status_t MyOggExtractor::init() {
828    mMeta = new MetaData;
829    mMeta->setCString(kKeyMIMEType, mMimeType);
830
831    status_t err;
832    MediaBuffer *packet;
833    for (size_t i = 0; i < mNumHeaders; ++i) {
834        // ignore timestamp for configuration packets
835        if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != OK) {
836            return err;
837        }
838        ALOGV("read packet of size %zu\n", packet->range_length());
839        err = verifyHeader(packet, /* type = */ i * 2 + 1);
840        packet->release();
841        packet = NULL;
842        if (err != OK) {
843            return err;
844        }
845    }
846
847    mFirstDataOffset = mOffset + mCurrentPageSize;
848
849    off64_t size;
850    uint64_t lastGranulePosition;
851    if (!(mSource->flags() & DataSource::kIsCachingDataSource)
852            && mSource->getSize(&size) == OK
853            && findPrevGranulePosition(size, &lastGranulePosition) == OK) {
854        // Let's assume it's cheap to seek to the end.
855        // The granule position of the final page in the stream will
856        // give us the exact duration of the content, something that
857        // we can only approximate using avg. bitrate if seeking to
858        // the end is too expensive or impossible (live streaming).
859
860        int64_t durationUs = getTimeUsOfGranule(lastGranulePosition);
861
862        mMeta->setInt64(kKeyDuration, durationUs);
863
864        buildTableOfContents();
865    }
866
867    return OK;
868}
869
870void MyOggExtractor::buildTableOfContents() {
871    off64_t offset = mFirstDataOffset;
872    Page page;
873    ssize_t pageSize;
874    while ((pageSize = readPage(offset, &page)) > 0) {
875        mTableOfContents.push();
876
877        TOCEntry &entry =
878            mTableOfContents.editItemAt(mTableOfContents.size() - 1);
879
880        entry.mPageOffset = offset;
881        entry.mTimeUs = getTimeUsOfGranule(page.mGranulePosition);
882
883        offset += (size_t)pageSize;
884    }
885
886    // Limit the maximum amount of RAM we spend on the table of contents,
887    // if necessary thin out the table evenly to trim it down to maximum
888    // size.
889
890    static const size_t kMaxTOCSize = 8192;
891    static const size_t kMaxNumTOCEntries = kMaxTOCSize / sizeof(TOCEntry);
892
893    size_t numerator = mTableOfContents.size();
894
895    if (numerator > kMaxNumTOCEntries) {
896        size_t denom = numerator - kMaxNumTOCEntries;
897
898        size_t accum = 0;
899        for (ssize_t i = mTableOfContents.size() - 1; i >= 0; --i) {
900            accum += denom;
901            if (accum >= numerator) {
902                mTableOfContents.removeAt(i);
903                accum -= numerator;
904            }
905        }
906    }
907}
908
909int32_t MyOggExtractor::getPacketBlockSize(MediaBuffer *buffer) {
910    const uint8_t *data =
911        (const uint8_t *)buffer->data() + buffer->range_offset();
912
913    size_t size = buffer->range_length();
914
915    ogg_buffer buf;
916    buf.data = (uint8_t *)data;
917    buf.size = size;
918    buf.refcount = 1;
919    buf.ptr.owner = NULL;
920
921    ogg_reference ref;
922    ref.buffer = &buf;
923    ref.begin = 0;
924    ref.length = size;
925    ref.next = NULL;
926
927    ogg_packet pack;
928    pack.packet = &ref;
929    pack.bytes = ref.length;
930    pack.b_o_s = 0;
931    pack.e_o_s = 0;
932    pack.granulepos = 0;
933    pack.packetno = 0;
934
935    return vorbis_packet_blocksize(&mVi, &pack);
936}
937
938int64_t MyOpusExtractor::getTimeUsOfGranule(uint64_t granulePos) const {
939    uint64_t pcmSamplePosition = 0;
940    if (granulePos > mCodecDelay) {
941        pcmSamplePosition = granulePos - mCodecDelay;
942    }
943    if (pcmSamplePosition > INT64_MAX / 1000000ll) {
944        return INT64_MAX;
945    }
946    return pcmSamplePosition * 1000000ll / kOpusSampleRate;
947}
948
949status_t MyOpusExtractor::verifyHeader(MediaBuffer *buffer, uint8_t type) {
950    switch (type) {
951        // there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean
952        // header and comments such that we can share code with MyVorbisExtractor.
953        case 1:
954            return verifyOpusHeader(buffer);
955        case 3:
956            return verifyOpusComments(buffer);
957        default:
958            return INVALID_OPERATION;
959    }
960}
961
962status_t MyOpusExtractor::verifyOpusHeader(MediaBuffer *buffer) {
963    const size_t kOpusHeaderSize = 19;
964    const uint8_t *data =
965        (const uint8_t *)buffer->data() + buffer->range_offset();
966
967    size_t size = buffer->range_length();
968
969    if (size < kOpusHeaderSize
970            || memcmp(data, "OpusHead", 8)
971            || /* version = */ data[8] != 1) {
972        return ERROR_MALFORMED;
973    }
974
975    mChannelCount = data[9];
976    mCodecDelay = U16LE_AT(&data[10]);
977
978    mMeta->setData(kKeyOpusHeader, 0, data, size);
979    mMeta->setInt32(kKeySampleRate, kOpusSampleRate);
980    mMeta->setInt32(kKeyChannelCount, mChannelCount);
981    mMeta->setInt64(kKeyOpusSeekPreRoll /* ns */, kOpusSeekPreRollUs * 1000 /* = 80 ms*/);
982    mMeta->setInt64(kKeyOpusCodecDelay /* ns */,
983            mCodecDelay /* sample/s */ * 1000000000ll / kOpusSampleRate);
984
985    return OK;
986}
987
988status_t MyOpusExtractor::verifyOpusComments(MediaBuffer *buffer) {
989    // add artificial framing bit so we can reuse _vorbis_unpack_comment
990    int32_t commentSize = buffer->range_length() + 1;
991    sp<ABuffer> aBuf = new ABuffer(commentSize);
992    if (aBuf->capacity() <= buffer->range_length()) {
993        return ERROR_MALFORMED;
994    }
995
996    uint8_t* commentData = aBuf->data();
997    memcpy(commentData,
998            (uint8_t *)buffer->data() + buffer->range_offset(),
999            buffer->range_length());
1000
1001    ogg_buffer buf;
1002    buf.data = commentData;
1003    buf.size = commentSize;
1004    buf.refcount = 1;
1005    buf.ptr.owner = NULL;
1006
1007    ogg_reference ref;
1008    ref.buffer = &buf;
1009    ref.begin = 0;
1010    ref.length = commentSize;
1011    ref.next = NULL;
1012
1013    oggpack_buffer bits;
1014    oggpack_readinit(&bits, &ref);
1015
1016    // skip 'OpusTags'
1017    const char *OpusTags = "OpusTags";
1018    const int32_t headerLen = strlen(OpusTags);
1019    int32_t framingBitOffset = headerLen;
1020    for (int i = 0; i < headerLen; ++i) {
1021        char chr = oggpack_read(&bits, 8);
1022        if (chr != OpusTags[i]) {
1023            return ERROR_MALFORMED;
1024        }
1025    }
1026
1027    int32_t vendorLen = oggpack_read(&bits, 32);
1028    framingBitOffset += 4;
1029    if (vendorLen < 0 || vendorLen > commentSize - 8) {
1030        return ERROR_MALFORMED;
1031    }
1032    // skip vendor string
1033    framingBitOffset += vendorLen;
1034    for (int i = 0; i < vendorLen; ++i) {
1035        oggpack_read(&bits, 8);
1036    }
1037
1038    int32_t n = oggpack_read(&bits, 32);
1039    framingBitOffset += 4;
1040    if (n < 0 || n > ((commentSize - oggpack_bytes(&bits)) >> 2)) {
1041        return ERROR_MALFORMED;
1042    }
1043    for (int i = 0; i < n; ++i) {
1044        int32_t len = oggpack_read(&bits, 32);
1045        framingBitOffset += 4;
1046        if (len  < 0 || len  > (commentSize - oggpack_bytes(&bits))) {
1047            return ERROR_MALFORMED;
1048        }
1049        framingBitOffset += len;
1050        for (int j = 0; j < len; ++j) {
1051            oggpack_read(&bits, 8);
1052        }
1053    }
1054    if (framingBitOffset < 0 || framingBitOffset >= commentSize) {
1055        return ERROR_MALFORMED;
1056    }
1057    commentData[framingBitOffset] = 1;
1058
1059    buf.data = commentData + headerLen;
1060    buf.size = commentSize - headerLen;
1061    buf.refcount = 1;
1062    buf.ptr.owner = NULL;
1063
1064    ref.buffer = &buf;
1065    ref.begin = 0;
1066    ref.length = commentSize - headerLen;
1067    ref.next = NULL;
1068
1069    oggpack_readinit(&bits, &ref);
1070    int err = _vorbis_unpack_comment(&mVc, &bits);
1071    if (0 != err) {
1072        return ERROR_MALFORMED;
1073    }
1074
1075    parseFileMetaData();
1076    return OK;
1077}
1078
1079status_t MyVorbisExtractor::verifyHeader(
1080        MediaBuffer *buffer, uint8_t type) {
1081    const uint8_t *data =
1082        (const uint8_t *)buffer->data() + buffer->range_offset();
1083
1084    size_t size = buffer->range_length();
1085
1086    if (size < 7 || data[0] != type || memcmp(&data[1], "vorbis", 6)) {
1087        return ERROR_MALFORMED;
1088    }
1089
1090    ogg_buffer buf;
1091    buf.data = (uint8_t *)data;
1092    buf.size = size;
1093    buf.refcount = 1;
1094    buf.ptr.owner = NULL;
1095
1096    ogg_reference ref;
1097    ref.buffer = &buf;
1098    ref.begin = 0;
1099    ref.length = size;
1100    ref.next = NULL;
1101
1102    oggpack_buffer bits;
1103    oggpack_readinit(&bits, &ref);
1104
1105    if (oggpack_read(&bits, 8) != type) {
1106        return ERROR_MALFORMED;
1107    }
1108    for (size_t i = 0; i < 6; ++i) {
1109        oggpack_read(&bits, 8);  // skip 'vorbis'
1110    }
1111
1112    switch (type) {
1113        case 1:
1114        {
1115            if (0 != _vorbis_unpack_info(&mVi, &bits)) {
1116                return ERROR_MALFORMED;
1117            }
1118
1119            mMeta->setData(kKeyVorbisInfo, 0, data, size);
1120            mMeta->setInt32(kKeySampleRate, mVi.rate);
1121            mMeta->setInt32(kKeyChannelCount, mVi.channels);
1122
1123            ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
1124            ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
1125            ALOGV("nominal-bitrate = %ld", mVi.bitrate_nominal);
1126            ALOGV("window-bitrate = %ld", mVi.bitrate_window);
1127            ALOGV("blocksizes: %d/%d",
1128                    vorbis_info_blocksize(&mVi, 0),
1129                    vorbis_info_blocksize(&mVi, 1)
1130                    );
1131
1132            off64_t size;
1133            if (mSource->getSize(&size) == OK) {
1134                uint64_t bps = approxBitrate();
1135                if (bps != 0) {
1136                    mMeta->setInt64(kKeyDuration, size * 8000000ll / bps);
1137                }
1138            }
1139            break;
1140        }
1141
1142        case 3:
1143        {
1144            if (0 != _vorbis_unpack_comment(&mVc, &bits)) {
1145                return ERROR_MALFORMED;
1146            }
1147
1148            parseFileMetaData();
1149            break;
1150        }
1151
1152        case 5:
1153        {
1154            if (0 != _vorbis_unpack_books(&mVi, &bits)) {
1155                return ERROR_MALFORMED;
1156            }
1157
1158            mMeta->setData(kKeyVorbisBooks, 0, data, size);
1159            break;
1160        }
1161    }
1162
1163    return OK;
1164}
1165
1166uint64_t MyVorbisExtractor::approxBitrate() const {
1167    if (mVi.bitrate_nominal != 0) {
1168        return mVi.bitrate_nominal;
1169    }
1170
1171    return (mVi.bitrate_lower + mVi.bitrate_upper) / 2;
1172}
1173
1174void MyOggExtractor::parseFileMetaData() {
1175    mFileMeta = new MetaData;
1176    mFileMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_OGG);
1177
1178    for (int i = 0; i < mVc.comments; ++i) {
1179        const char *comment = mVc.user_comments[i];
1180        size_t commentLength = mVc.comment_lengths[i];
1181        parseVorbisComment(mFileMeta, comment, commentLength);
1182        //ALOGI("comment #%d: '%s'", i + 1, mVc.user_comments[i]);
1183    }
1184}
1185
1186void parseVorbisComment(
1187        const sp<MetaData> &fileMeta, const char *comment, size_t commentLength)
1188{
1189    struct {
1190        const char *const mTag;
1191        uint32_t mKey;
1192    } kMap[] = {
1193        { "TITLE", kKeyTitle },
1194        { "ARTIST", kKeyArtist },
1195        { "ALBUMARTIST", kKeyAlbumArtist },
1196        { "ALBUM ARTIST", kKeyAlbumArtist },
1197        { "COMPILATION", kKeyCompilation },
1198        { "ALBUM", kKeyAlbum },
1199        { "COMPOSER", kKeyComposer },
1200        { "GENRE", kKeyGenre },
1201        { "AUTHOR", kKeyAuthor },
1202        { "TRACKNUMBER", kKeyCDTrackNumber },
1203        { "DISCNUMBER", kKeyDiscNumber },
1204        { "DATE", kKeyDate },
1205        { "YEAR", kKeyYear },
1206        { "LYRICIST", kKeyWriter },
1207        { "METADATA_BLOCK_PICTURE", kKeyAlbumArt },
1208        { "ANDROID_LOOP", kKeyAutoLoop },
1209    };
1210
1211        for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) {
1212            size_t tagLen = strlen(kMap[j].mTag);
1213            if (!strncasecmp(kMap[j].mTag, comment, tagLen)
1214                    && comment[tagLen] == '=') {
1215                if (kMap[j].mKey == kKeyAlbumArt) {
1216                    extractAlbumArt(
1217                            fileMeta,
1218                            &comment[tagLen + 1],
1219                            commentLength - tagLen - 1);
1220                } else if (kMap[j].mKey == kKeyAutoLoop) {
1221                    if (!strcasecmp(&comment[tagLen + 1], "true")) {
1222                        fileMeta->setInt32(kKeyAutoLoop, true);
1223                    }
1224                } else {
1225                    fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]);
1226                }
1227            }
1228        }
1229
1230}
1231
1232static void extractAlbumArt(
1233        const sp<MetaData> &fileMeta, const void *data, size_t size) {
1234    ALOGV("extractAlbumArt from '%s'", (const char *)data);
1235
1236    sp<ABuffer> flacBuffer = decodeBase64(AString((const char *)data, size));
1237    if (flacBuffer == NULL) {
1238        ALOGE("malformed base64 encoded data.");
1239        return;
1240    }
1241
1242    size_t flacSize = flacBuffer->size();
1243    uint8_t *flac = flacBuffer->data();
1244    ALOGV("got flac of size %zu", flacSize);
1245
1246    uint32_t picType;
1247    uint32_t typeLen;
1248    uint32_t descLen;
1249    uint32_t dataLen;
1250    char type[128];
1251
1252    if (flacSize < 8) {
1253        return;
1254    }
1255
1256    picType = U32_AT(flac);
1257
1258    if (picType != 3) {
1259        // This is not a front cover.
1260        return;
1261    }
1262
1263    typeLen = U32_AT(&flac[4]);
1264    if (typeLen > sizeof(type) - 1) {
1265        return;
1266    }
1267
1268    // we've already checked above that flacSize >= 8
1269    if (flacSize - 8 < typeLen) {
1270        return;
1271    }
1272
1273    memcpy(type, &flac[8], typeLen);
1274    type[typeLen] = '\0';
1275
1276    ALOGV("picType = %d, type = '%s'", picType, type);
1277
1278    if (!strcmp(type, "-->")) {
1279        // This is not inline cover art, but an external url instead.
1280        return;
1281    }
1282
1283    if (flacSize < 32 || flacSize - 32 < typeLen) {
1284        return;
1285    }
1286
1287    descLen = U32_AT(&flac[8 + typeLen]);
1288    if (flacSize - 32 - typeLen < descLen) {
1289        return;
1290    }
1291
1292    dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]);
1293
1294    // we've already checked above that (flacSize - 32 - typeLen - descLen) >= 0
1295    if (flacSize - 32 - typeLen - descLen < dataLen) {
1296        return;
1297    }
1298
1299    ALOGV("got image data, %zu trailing bytes",
1300         flacSize - 32 - typeLen - descLen - dataLen);
1301
1302    fileMeta->setData(
1303            kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen);
1304
1305    fileMeta->setCString(kKeyAlbumArtMIME, type);
1306}
1307
1308////////////////////////////////////////////////////////////////////////////////
1309
1310OggExtractor::OggExtractor(const sp<DataSource> &source)
1311    : mDataSource(source),
1312      mInitCheck(NO_INIT),
1313      mImpl(NULL) {
1314    for (int i = 0; i < 2; ++i) {
1315        if (mImpl != NULL) {
1316            delete mImpl;
1317        }
1318        if (i == 0) {
1319            mImpl = new MyVorbisExtractor(mDataSource);
1320        } else {
1321            mImpl = new MyOpusExtractor(mDataSource);
1322        }
1323        mInitCheck = mImpl->seekToOffset(0);
1324
1325        if (mInitCheck == OK) {
1326            mInitCheck = mImpl->init();
1327            if (mInitCheck == OK) {
1328                break;
1329            }
1330        }
1331    }
1332}
1333
1334OggExtractor::~OggExtractor() {
1335    delete mImpl;
1336    mImpl = NULL;
1337}
1338
1339size_t OggExtractor::countTracks() {
1340    return mInitCheck != OK ? 0 : 1;
1341}
1342
1343sp<IMediaSource> OggExtractor::getTrack(size_t index) {
1344    if (index >= 1) {
1345        return NULL;
1346    }
1347
1348    return new OggSource(this);
1349}
1350
1351sp<MetaData> OggExtractor::getTrackMetaData(
1352        size_t index, uint32_t /* flags */) {
1353    if (index >= 1) {
1354        return NULL;
1355    }
1356
1357    return mImpl->getFormat();
1358}
1359
1360sp<MetaData> OggExtractor::getMetaData() {
1361    return mImpl->getFileMetaData();
1362}
1363
1364bool SniffOgg(
1365        const sp<DataSource> &source, String8 *mimeType, float *confidence,
1366        sp<AMessage> *) {
1367    char tmp[4];
1368    if (source->readAt(0, tmp, 4) < 4 || memcmp(tmp, "OggS", 4)) {
1369        return false;
1370    }
1371
1372    mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_OGG);
1373    *confidence = 0.2f;
1374
1375    return true;
1376}
1377
1378}  // namespace android
1379