Home | History | Annotate | Download | only in amrwb
      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 "AMRWBDecoder.h"
     18 
     19 #include "pvamrwbdecoder.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 static const int32_t kNumSamplesPerFrame = 320;
     29 static const int32_t kSampleRate = 16000;
     30 
     31 AMRWBDecoder::AMRWBDecoder(const sp<MediaSource> &source)
     32     : mSource(source),
     33       mStarted(false),
     34       mBufferGroup(NULL),
     35       mState(NULL),
     36       mDecoderBuf(NULL),
     37       mDecoderCookie(NULL),
     38       mAnchorTimeUs(0),
     39       mNumSamplesOutput(0),
     40       mInputBuffer(NULL) {
     41 }
     42 
     43 AMRWBDecoder::~AMRWBDecoder() {
     44     if (mStarted) {
     45         stop();
     46     }
     47 }
     48 
     49 status_t AMRWBDecoder::start(MetaData *params) {
     50     CHECK(!mStarted);
     51 
     52     mBufferGroup = new MediaBufferGroup;
     53     mBufferGroup->add_buffer(
     54             new MediaBuffer(kNumSamplesPerFrame * sizeof(int16_t)));
     55 
     56     int32_t memReq = pvDecoder_AmrWbMemRequirements();
     57     mDecoderBuf = malloc(memReq);
     58 
     59     pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie);
     60 
     61     mSource->start();
     62 
     63     mAnchorTimeUs = 0;
     64     mNumSamplesOutput = 0;
     65     mStarted = true;
     66 
     67     return OK;
     68 }
     69 
     70 status_t AMRWBDecoder::stop() {
     71     CHECK(mStarted);
     72 
     73     if (mInputBuffer) {
     74         mInputBuffer->release();
     75         mInputBuffer = NULL;
     76     }
     77 
     78     delete mBufferGroup;
     79     mBufferGroup = NULL;
     80 
     81     free(mDecoderBuf);
     82     mDecoderBuf = NULL;
     83 
     84     mSource->stop();
     85 
     86     mStarted = false;
     87 
     88     return OK;
     89 }
     90 
     91 sp<MetaData> AMRWBDecoder::getFormat() {
     92     sp<MetaData> srcFormat = mSource->getFormat();
     93 
     94     int32_t numChannels;
     95     int32_t sampleRate;
     96 
     97     CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
     98     CHECK_EQ(numChannels, 1);
     99 
    100     CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
    101     CHECK_EQ(sampleRate, kSampleRate);
    102 
    103     sp<MetaData> meta = new MetaData;
    104     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
    105     meta->setInt32(kKeyChannelCount, numChannels);
    106     meta->setInt32(kKeySampleRate, sampleRate);
    107 
    108     int64_t durationUs;
    109     if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
    110         meta->setInt64(kKeyDuration, durationUs);
    111     }
    112 
    113     meta->setCString(kKeyDecoderComponent, "AMRWBDecoder");
    114 
    115     return meta;
    116 }
    117 
    118 static size_t getFrameSize(unsigned FT) {
    119     static const size_t kFrameSizeWB[9] = {
    120         132, 177, 253, 285, 317, 365, 397, 461, 477
    121     };
    122 
    123     size_t frameSize = kFrameSizeWB[FT];
    124 
    125     // Round up bits to bytes and add 1 for the header byte.
    126     frameSize = (frameSize + 7) / 8 + 1;
    127 
    128     return frameSize;
    129 }
    130 
    131 status_t AMRWBDecoder::read(
    132         MediaBuffer **out, const ReadOptions *options) {
    133     status_t err;
    134 
    135     *out = NULL;
    136 
    137     int64_t seekTimeUs;
    138     if (options && options->getSeekTo(&seekTimeUs)) {
    139         CHECK(seekTimeUs >= 0);
    140 
    141         mNumSamplesOutput = 0;
    142 
    143         if (mInputBuffer) {
    144             mInputBuffer->release();
    145             mInputBuffer = NULL;
    146         }
    147     } else {
    148         seekTimeUs = -1;
    149     }
    150 
    151     if (mInputBuffer == NULL) {
    152         err = mSource->read(&mInputBuffer, options);
    153 
    154         if (err != OK) {
    155             return err;
    156         }
    157 
    158         int64_t timeUs;
    159         if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
    160             mAnchorTimeUs = timeUs;
    161             mNumSamplesOutput = 0;
    162         } else {
    163             // We must have a new timestamp after seeking.
    164             CHECK(seekTimeUs < 0);
    165         }
    166     }
    167 
    168     MediaBuffer *buffer;
    169     CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
    170 
    171     const uint8_t *inputPtr =
    172         (const uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
    173 
    174     int16 mode = ((inputPtr[0] >> 3) & 0x0f);
    175     size_t frameSize = getFrameSize(mode);
    176     CHECK(mInputBuffer->range_length() >= frameSize);
    177 
    178     int16 frameType;
    179     RX_State rx_state;
    180     mime_unsorting(
    181             const_cast<uint8_t *>(&inputPtr[1]),
    182             mInputSampleBuffer,
    183             &frameType, &mode, 1, &rx_state);
    184 
    185     int16_t *outPtr = (int16_t *)buffer->data();
    186 
    187     int16_t numSamplesOutput;
    188     pvDecoder_AmrWb(
    189             mode, mInputSampleBuffer,
    190             outPtr,
    191             &numSamplesOutput,
    192             mDecoderBuf, frameType, mDecoderCookie);
    193 
    194     CHECK_EQ(numSamplesOutput, kNumSamplesPerFrame);
    195 
    196     for (int i = 0; i < kNumSamplesPerFrame; ++i) {
    197         /* Delete the 2 LSBs (14-bit output) */
    198         outPtr[i] &= 0xfffC;
    199     }
    200 
    201     buffer->set_range(0, numSamplesOutput * sizeof(int16_t));
    202 
    203     mInputBuffer->set_range(
    204             mInputBuffer->range_offset() + frameSize,
    205             mInputBuffer->range_length() - frameSize);
    206 
    207     if (mInputBuffer->range_length() == 0) {
    208         mInputBuffer->release();
    209         mInputBuffer = NULL;
    210     }
    211 
    212     buffer->meta_data()->setInt64(
    213             kKeyTime,
    214             mAnchorTimeUs
    215                 + (mNumSamplesOutput * 1000000) / kSampleRate);
    216 
    217     mNumSamplesOutput += kNumSamplesPerFrame;
    218 
    219     *out = buffer;
    220 
    221     return OK;
    222 }
    223 
    224 }  // namespace android
    225