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