Home | History | Annotate | Download | only in mp3dec
      1 /*
      2  * Copyright (C) 2009 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 "MP3Decoder.h"
     18 
     19 #include "include/pvmp3decoder_api.h"
     20 
     21 #include <media/stagefright/MediaBufferGroup.h>
     22 #include <media/stagefright/MediaDebug.h>
     23 #include <media/stagefright/MediaDefs.h>
     24 #include <media/stagefright/MetaData.h>
     25 
     26 namespace android {
     27 
     28 MP3Decoder::MP3Decoder(const sp<MediaSource> &source)
     29     : mSource(source),
     30       mNumChannels(0),
     31       mStarted(false),
     32       mBufferGroup(NULL),
     33       mConfig(new tPVMP3DecoderExternal),
     34       mDecoderBuf(NULL),
     35       mAnchorTimeUs(0),
     36       mNumFramesOutput(0),
     37       mInputBuffer(NULL) {
     38     init();
     39 }
     40 
     41 void MP3Decoder::init() {
     42     sp<MetaData> srcFormat = mSource->getFormat();
     43 
     44     int32_t sampleRate;
     45     CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
     46     CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
     47 
     48     mMeta = new MetaData;
     49     mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     50     mMeta->setInt32(kKeyChannelCount, mNumChannels);
     51     mMeta->setInt32(kKeySampleRate, sampleRate);
     52 
     53     int64_t durationUs;
     54     if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
     55         mMeta->setInt64(kKeyDuration, durationUs);
     56     }
     57 
     58     mMeta->setCString(kKeyDecoderComponent, "MP3Decoder");
     59 }
     60 
     61 MP3Decoder::~MP3Decoder() {
     62     if (mStarted) {
     63         stop();
     64     }
     65 
     66     delete mConfig;
     67     mConfig = NULL;
     68 }
     69 
     70 status_t MP3Decoder::start(MetaData *params) {
     71     CHECK(!mStarted);
     72 
     73     mBufferGroup = new MediaBufferGroup;
     74     mBufferGroup->add_buffer(new MediaBuffer(4608 * 2));
     75 
     76     mConfig->equalizerType = flat;
     77     mConfig->crcEnabled = false;
     78 
     79     uint32_t memRequirements = pvmp3_decoderMemRequirements();
     80     mDecoderBuf = malloc(memRequirements);
     81 
     82     pvmp3_InitDecoder(mConfig, mDecoderBuf);
     83 
     84     mSource->start();
     85 
     86     mAnchorTimeUs = 0;
     87     mNumFramesOutput = 0;
     88     mStarted = true;
     89 
     90     return OK;
     91 }
     92 
     93 status_t MP3Decoder::stop() {
     94     CHECK(mStarted);
     95 
     96     if (mInputBuffer) {
     97         mInputBuffer->release();
     98         mInputBuffer = NULL;
     99     }
    100 
    101     free(mDecoderBuf);
    102     mDecoderBuf = NULL;
    103 
    104     delete mBufferGroup;
    105     mBufferGroup = NULL;
    106 
    107     mSource->stop();
    108 
    109     mStarted = false;
    110 
    111     return OK;
    112 }
    113 
    114 sp<MetaData> MP3Decoder::getFormat() {
    115     return mMeta;
    116 }
    117 
    118 status_t MP3Decoder::read(
    119         MediaBuffer **out, const ReadOptions *options) {
    120     status_t err;
    121 
    122     *out = NULL;
    123 
    124     int64_t seekTimeUs;
    125     ReadOptions::SeekMode mode;
    126     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
    127         CHECK(seekTimeUs >= 0);
    128 
    129         mNumFramesOutput = 0;
    130 
    131         if (mInputBuffer) {
    132             mInputBuffer->release();
    133             mInputBuffer = NULL;
    134         }
    135 
    136         // Make sure that the next buffer output does not still
    137         // depend on fragments from the last one decoded.
    138         pvmp3_InitDecoder(mConfig, mDecoderBuf);
    139     } else {
    140         seekTimeUs = -1;
    141     }
    142 
    143     if (mInputBuffer == NULL) {
    144         err = mSource->read(&mInputBuffer, options);
    145 
    146         if (err != OK) {
    147             return err;
    148         }
    149 
    150         int64_t timeUs;
    151         if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
    152             mAnchorTimeUs = timeUs;
    153             mNumFramesOutput = 0;
    154         } else {
    155             // We must have a new timestamp after seeking.
    156             CHECK(seekTimeUs < 0);
    157         }
    158     }
    159 
    160     MediaBuffer *buffer;
    161     CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
    162 
    163     mConfig->pInputBuffer =
    164         (uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
    165 
    166     mConfig->inputBufferCurrentLength = mInputBuffer->range_length();
    167     mConfig->inputBufferMaxLength = 0;
    168     mConfig->inputBufferUsedLength = 0;
    169 
    170     mConfig->outputFrameSize = buffer->size() / sizeof(int16_t);
    171     mConfig->pOutputBuffer = static_cast<int16_t *>(buffer->data());
    172 
    173     ERROR_CODE decoderErr;
    174     if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
    175             != NO_DECODING_ERROR) {
    176         LOGV("mp3 decoder returned error %d", decoderErr);
    177 
    178         if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR) {
    179             buffer->release();
    180             buffer = NULL;
    181 
    182             mInputBuffer->release();
    183             mInputBuffer = NULL;
    184 
    185             return UNKNOWN_ERROR;
    186         }
    187 
    188         // This is recoverable, just ignore the current frame and
    189         // play silence instead.
    190         memset(buffer->data(), 0, mConfig->outputFrameSize * sizeof(int16_t));
    191         mConfig->inputBufferUsedLength = mInputBuffer->range_length();
    192     }
    193 
    194     buffer->set_range(
    195             0, mConfig->outputFrameSize * sizeof(int16_t));
    196 
    197     mInputBuffer->set_range(
    198             mInputBuffer->range_offset() + mConfig->inputBufferUsedLength,
    199             mInputBuffer->range_length() - mConfig->inputBufferUsedLength);
    200 
    201     if (mInputBuffer->range_length() == 0) {
    202         mInputBuffer->release();
    203         mInputBuffer = NULL;
    204     }
    205 
    206     buffer->meta_data()->setInt64(
    207             kKeyTime,
    208             mAnchorTimeUs
    209                 + (mNumFramesOutput * 1000000) / mConfig->samplingRate);
    210 
    211     mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
    212 
    213     *out = buffer;
    214 
    215     return OK;
    216 }
    217 
    218 }  // namespace android
    219