Home | History | Annotate | Download | only in aacdec
      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 "AACDecoder.h"
     18 
     19 #include "../../include/ESDS.h"
     20 
     21 #include "pvmp4audiodecoder_api.h"
     22 
     23 #include <media/stagefright/MediaBufferGroup.h>
     24 #include <media/stagefright/MediaDebug.h>
     25 #include <media/stagefright/MediaDefs.h>
     26 #include <media/stagefright/MetaData.h>
     27 
     28 namespace android {
     29 
     30 AACDecoder::AACDecoder(const sp<MediaSource> &source)
     31     : mSource(source),
     32       mStarted(false),
     33       mBufferGroup(NULL),
     34       mConfig(new tPVMP4AudioDecoderExternal),
     35       mDecoderBuf(NULL),
     36       mAnchorTimeUs(0),
     37       mNumSamplesOutput(0),
     38       mInputBuffer(NULL) {
     39 }
     40 
     41 AACDecoder::~AACDecoder() {
     42     if (mStarted) {
     43         stop();
     44     }
     45 
     46     delete mConfig;
     47     mConfig = NULL;
     48 }
     49 
     50 status_t AACDecoder::start(MetaData *params) {
     51     CHECK(!mStarted);
     52 
     53     mBufferGroup = new MediaBufferGroup;
     54     mBufferGroup->add_buffer(new MediaBuffer(2048 * 2));
     55 
     56     mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
     57     mConfig->aacPlusUpsamplingFactor = 0;
     58     mConfig->aacPlusEnabled = false;
     59 
     60     // The software decoder doesn't properly support mono output on
     61     // AACplus files. Always output stereo.
     62     mConfig->desiredChannels = 2;
     63 
     64     UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
     65     mDecoderBuf = malloc(memRequirements);
     66 
     67     CHECK_EQ(PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf),
     68              MP4AUDEC_SUCCESS);
     69 
     70     uint32_t type;
     71     const void *data;
     72     size_t size;
     73     sp<MetaData> meta = mSource->getFormat();
     74     if (meta->findData(kKeyESDS, &type, &data, &size)) {
     75         ESDS esds((const char *)data, size);
     76         CHECK_EQ(esds.InitCheck(), OK);
     77 
     78         const void *codec_specific_data;
     79         size_t codec_specific_data_size;
     80         esds.getCodecSpecificInfo(
     81                 &codec_specific_data, &codec_specific_data_size);
     82 
     83         mConfig->pInputBuffer = (UChar *)codec_specific_data;
     84         mConfig->inputBufferCurrentLength = codec_specific_data_size;
     85         mConfig->inputBufferMaxLength = 0;
     86         mConfig->inputBufferUsedLength = 0;
     87         mConfig->remainderBits = 0;
     88 
     89         mConfig->pOutputBuffer = NULL;
     90         mConfig->pOutputBuffer_plus = NULL;
     91         mConfig->repositionFlag = false;
     92 
     93         if (PVMP4AudioDecoderConfig(mConfig, mDecoderBuf)
     94                 != MP4AUDEC_SUCCESS) {
     95             return ERROR_UNSUPPORTED;
     96         }
     97     }
     98 
     99     mSource->start();
    100 
    101     mAnchorTimeUs = 0;
    102     mNumSamplesOutput = 0;
    103     mStarted = true;
    104 
    105     return OK;
    106 }
    107 
    108 status_t AACDecoder::stop() {
    109     CHECK(mStarted);
    110 
    111     if (mInputBuffer) {
    112         mInputBuffer->release();
    113         mInputBuffer = NULL;
    114     }
    115 
    116     free(mDecoderBuf);
    117     mDecoderBuf = NULL;
    118 
    119     delete mBufferGroup;
    120     mBufferGroup = NULL;
    121 
    122     mSource->stop();
    123 
    124     mStarted = false;
    125 
    126     return OK;
    127 }
    128 
    129 sp<MetaData> AACDecoder::getFormat() {
    130     sp<MetaData> srcFormat = mSource->getFormat();
    131 
    132     int32_t sampleRate;
    133     CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
    134 
    135     sp<MetaData> meta = new MetaData;
    136     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
    137 
    138     // We'll always output stereo, regardless of how many channels are
    139     // present in the input due to decoder limitations.
    140     meta->setInt32(kKeyChannelCount, 2);
    141 
    142     meta->setInt32(kKeySampleRate, sampleRate);
    143 
    144     int64_t durationUs;
    145     if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
    146         meta->setInt64(kKeyDuration, durationUs);
    147     }
    148 
    149     meta->setCString(kKeyDecoderComponent, "AACDecoder");
    150 
    151     return meta;
    152 }
    153 
    154 status_t AACDecoder::read(
    155         MediaBuffer **out, const ReadOptions *options) {
    156     status_t err;
    157 
    158     *out = NULL;
    159 
    160     int64_t seekTimeUs;
    161     if (options && options->getSeekTo(&seekTimeUs)) {
    162         CHECK(seekTimeUs >= 0);
    163 
    164         mNumSamplesOutput = 0;
    165 
    166         if (mInputBuffer) {
    167             mInputBuffer->release();
    168             mInputBuffer = NULL;
    169         }
    170     } else {
    171         seekTimeUs = -1;
    172     }
    173 
    174     if (mInputBuffer == NULL) {
    175         err = mSource->read(&mInputBuffer, options);
    176 
    177         if (err != OK) {
    178             return err;
    179         }
    180 
    181         int64_t timeUs;
    182         if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
    183             mAnchorTimeUs = timeUs;
    184             mNumSamplesOutput = 0;
    185         } else {
    186             // We must have a new timestamp after seeking.
    187             CHECK(seekTimeUs < 0);
    188         }
    189     }
    190 
    191     MediaBuffer *buffer;
    192     CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
    193 
    194     mConfig->pInputBuffer =
    195         (UChar *)mInputBuffer->data() + mInputBuffer->range_offset();
    196 
    197     mConfig->inputBufferCurrentLength = mInputBuffer->range_length();
    198     mConfig->inputBufferMaxLength = 0;
    199     mConfig->inputBufferUsedLength = 0;
    200     mConfig->remainderBits = 0;
    201 
    202     mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data());
    203     mConfig->pOutputBuffer_plus = NULL;
    204     mConfig->repositionFlag = false;
    205 
    206     Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
    207 
    208     size_t numOutBytes =
    209         mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
    210 
    211     if (decoderErr != MP4AUDEC_SUCCESS) {
    212         LOGW("AAC decoder returned error %d, substituting silence", decoderErr);
    213 
    214         memset(buffer->data(), 0, numOutBytes);
    215 
    216         // Discard input buffer.
    217         mInputBuffer->release();
    218         mInputBuffer = NULL;
    219 
    220         // fall through
    221     }
    222 
    223     buffer->set_range(0, numOutBytes);
    224 
    225     if (mInputBuffer != NULL) {
    226         mInputBuffer->set_range(
    227                 mInputBuffer->range_offset() + mConfig->inputBufferUsedLength,
    228                 mInputBuffer->range_length() - mConfig->inputBufferUsedLength);
    229 
    230         if (mInputBuffer->range_length() == 0) {
    231             mInputBuffer->release();
    232             mInputBuffer = NULL;
    233         }
    234     }
    235 
    236     buffer->meta_data()->setInt64(
    237             kKeyTime,
    238             mAnchorTimeUs
    239                 + (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
    240 
    241     mNumSamplesOutput += mConfig->frameLength;
    242 
    243     *out = buffer;
    244 
    245     return OK;
    246 }
    247 
    248 }  // namespace android
    249