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#include "VorbisDecoder.h"
18
19#include <media/stagefright/MediaBufferGroup.h>
20#include <media/stagefright/MediaDebug.h>
21#include <media/stagefright/MediaDefs.h>
22#include <media/stagefright/MediaErrors.h>
23#include <media/stagefright/MetaData.h>
24
25extern "C" {
26    #include <Tremolo/codec_internal.h>
27
28    int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb);
29    int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb);
30    int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb);
31}
32
33namespace android {
34
35VorbisDecoder::VorbisDecoder(const sp<MediaSource> &source)
36    : mSource(source),
37      mStarted(false),
38      mBufferGroup(NULL),
39      mAnchorTimeUs(0),
40      mNumFramesOutput(0),
41      mState(NULL),
42      mVi(NULL) {
43    sp<MetaData> srcFormat = mSource->getFormat();
44    CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
45    CHECK(srcFormat->findInt32(kKeySampleRate, &mSampleRate));
46}
47
48VorbisDecoder::~VorbisDecoder() {
49    if (mStarted) {
50        stop();
51    }
52}
53
54static void makeBitReader(
55        const void *data, size_t size,
56        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
57    buf->data = (uint8_t *)data;
58    buf->size = size;
59    buf->refcount = 1;
60    buf->ptr.owner = NULL;
61
62    ref->buffer = buf;
63    ref->begin = 0;
64    ref->length = size;
65    ref->next = NULL;
66
67    oggpack_readinit(bits, ref);
68}
69
70status_t VorbisDecoder::start(MetaData *params) {
71    CHECK(!mStarted);
72
73    mBufferGroup = new MediaBufferGroup;
74    mBufferGroup->add_buffer(
75            new MediaBuffer(kMaxNumSamplesPerBuffer * sizeof(int16_t)));
76
77    mSource->start();
78
79    sp<MetaData> meta = mSource->getFormat();
80
81    mVi = new vorbis_info;
82    vorbis_info_init(mVi);
83
84    ///////////////////////////////////////////////////////////////////////////
85
86    uint32_t type;
87    const void *data;
88    size_t size;
89    CHECK(meta->findData(kKeyVorbisInfo, &type, &data, &size));
90
91    ogg_buffer buf;
92    ogg_reference ref;
93    oggpack_buffer bits;
94    makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
95    CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits));
96
97    ///////////////////////////////////////////////////////////////////////////
98
99    CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));
100
101    makeBitReader((const uint8_t *)data + 7, size - 7, &buf, &ref, &bits);
102    CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits));
103
104    ///////////////////////////////////////////////////////////////////////////
105
106    mState = new vorbis_dsp_state;
107    CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
108
109    mAnchorTimeUs = 0;
110    mNumFramesOutput = 0;
111    mStarted = true;
112
113    return OK;
114}
115
116status_t VorbisDecoder::stop() {
117    CHECK(mStarted);
118
119    vorbis_dsp_clear(mState);
120    delete mState;
121    mState = NULL;
122
123    vorbis_info_clear(mVi);
124    delete mVi;
125    mVi = NULL;
126
127    delete mBufferGroup;
128    mBufferGroup = NULL;
129
130    mSource->stop();
131
132    mStarted = false;
133
134    return OK;
135}
136
137sp<MetaData> VorbisDecoder::getFormat() {
138    sp<MetaData> srcFormat = mSource->getFormat();
139
140    sp<MetaData> meta = new MetaData;
141    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
142    meta->setInt32(kKeyChannelCount, mNumChannels);
143    meta->setInt32(kKeySampleRate, mSampleRate);
144
145    int64_t durationUs;
146    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
147        meta->setInt64(kKeyDuration, durationUs);
148    }
149
150    meta->setCString(kKeyDecoderComponent, "VorbisDecoder");
151
152    return meta;
153}
154
155int VorbisDecoder::decodePacket(MediaBuffer *packet, MediaBuffer *out) {
156    ogg_buffer buf;
157    buf.data = (uint8_t *)packet->data() + packet->range_offset();
158    buf.size = packet->range_length();
159    buf.refcount = 1;
160    buf.ptr.owner = NULL;
161
162    ogg_reference ref;
163    ref.buffer = &buf;
164    ref.begin = 0;
165    ref.length = packet->range_length();
166    ref.next = NULL;
167
168    ogg_packet pack;
169    pack.packet = &ref;
170    pack.bytes = packet->range_length();
171    pack.b_o_s = 0;
172    pack.e_o_s = 0;
173    pack.granulepos = 0;
174    pack.packetno = 0;
175
176    int numFrames = 0;
177
178    int err = vorbis_dsp_synthesis(mState, &pack, 1);
179    if (err != 0) {
180        LOGW("vorbis_dsp_synthesis returned %d", err);
181    } else {
182        numFrames = vorbis_dsp_pcmout(
183                mState, (int16_t *)out->data(), kMaxNumSamplesPerBuffer);
184
185        if (numFrames < 0) {
186            LOGE("vorbis_dsp_pcmout returned %d", numFrames);
187            numFrames = 0;
188        }
189    }
190
191    out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
192
193    return numFrames;
194}
195
196status_t VorbisDecoder::read(
197        MediaBuffer **out, const ReadOptions *options) {
198    status_t err;
199
200    *out = NULL;
201
202    int64_t seekTimeUs;
203    if (options && options->getSeekTo(&seekTimeUs)) {
204        CHECK(seekTimeUs >= 0);
205
206        mNumFramesOutput = 0;
207        vorbis_dsp_restart(mState);
208    } else {
209        seekTimeUs = -1;
210    }
211
212    MediaBuffer *inputBuffer;
213    err = mSource->read(&inputBuffer, options);
214
215    if (err != OK) {
216        return ERROR_END_OF_STREAM;
217    }
218
219    int64_t timeUs;
220    if (inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
221        mAnchorTimeUs = timeUs;
222        mNumFramesOutput = 0;
223    } else {
224        // We must have a new timestamp after seeking.
225        CHECK(seekTimeUs < 0);
226    }
227
228    MediaBuffer *outputBuffer;
229    CHECK_EQ(mBufferGroup->acquire_buffer(&outputBuffer), OK);
230
231    int numFrames = decodePacket(inputBuffer, outputBuffer);
232
233    inputBuffer->release();
234    inputBuffer = NULL;
235
236    outputBuffer->meta_data()->setInt64(
237            kKeyTime,
238            mAnchorTimeUs
239                + (mNumFramesOutput * 1000000ll) / mSampleRate);
240
241    mNumFramesOutput += numFrames;
242
243    *out = outputBuffer;
244
245    return OK;
246}
247
248}  // namespace android
249