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