Home | History | Annotate | Download | only in mp3dec
      1 /*
      2  * Copyright (C) 2011 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 "SoftMP3"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftMP3.h"
     22 
     23 #include <media/stagefright/foundation/ADebug.h>
     24 #include <media/stagefright/MediaDefs.h>
     25 
     26 #include "include/pvmp3decoder_api.h"
     27 
     28 namespace android {
     29 
     30 template<class T>
     31 static void InitOMXParams(T *params) {
     32     params->nSize = sizeof(T);
     33     params->nVersion.s.nVersionMajor = 1;
     34     params->nVersion.s.nVersionMinor = 0;
     35     params->nVersion.s.nRevision = 0;
     36     params->nVersion.s.nStep = 0;
     37 }
     38 
     39 SoftMP3::SoftMP3(
     40         const char *name,
     41         const OMX_CALLBACKTYPE *callbacks,
     42         OMX_PTR appData,
     43         OMX_COMPONENTTYPE **component)
     44     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     45       mConfig(new tPVMP3DecoderExternal),
     46       mDecoderBuf(NULL),
     47       mAnchorTimeUs(0),
     48       mNumFramesOutput(0),
     49       mNumChannels(2),
     50       mSamplingRate(44100),
     51       mSignalledError(false),
     52       mOutputPortSettingsChange(NONE) {
     53     initPorts();
     54     initDecoder();
     55 }
     56 
     57 SoftMP3::~SoftMP3() {
     58     if (mDecoderBuf != NULL) {
     59         free(mDecoderBuf);
     60         mDecoderBuf = NULL;
     61     }
     62 
     63     delete mConfig;
     64     mConfig = NULL;
     65 }
     66 
     67 void SoftMP3::initPorts() {
     68     OMX_PARAM_PORTDEFINITIONTYPE def;
     69     InitOMXParams(&def);
     70 
     71     def.nPortIndex = 0;
     72     def.eDir = OMX_DirInput;
     73     def.nBufferCountMin = kNumBuffers;
     74     def.nBufferCountActual = def.nBufferCountMin;
     75     def.nBufferSize = 8192;
     76     def.bEnabled = OMX_TRUE;
     77     def.bPopulated = OMX_FALSE;
     78     def.eDomain = OMX_PortDomainAudio;
     79     def.bBuffersContiguous = OMX_FALSE;
     80     def.nBufferAlignment = 1;
     81 
     82     def.format.audio.cMIMEType =
     83         const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG);
     84 
     85     def.format.audio.pNativeRender = NULL;
     86     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     87     def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
     88 
     89     addPort(def);
     90 
     91     def.nPortIndex = 1;
     92     def.eDir = OMX_DirOutput;
     93     def.nBufferCountMin = kNumBuffers;
     94     def.nBufferCountActual = def.nBufferCountMin;
     95     def.nBufferSize = kOutputBufferSize;
     96     def.bEnabled = OMX_TRUE;
     97     def.bPopulated = OMX_FALSE;
     98     def.eDomain = OMX_PortDomainAudio;
     99     def.bBuffersContiguous = OMX_FALSE;
    100     def.nBufferAlignment = 2;
    101 
    102     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    103     def.format.audio.pNativeRender = NULL;
    104     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    105     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    106 
    107     addPort(def);
    108 }
    109 
    110 void SoftMP3::initDecoder() {
    111     mConfig->equalizerType = flat;
    112     mConfig->crcEnabled = false;
    113 
    114     uint32_t memRequirements = pvmp3_decoderMemRequirements();
    115     mDecoderBuf = malloc(memRequirements);
    116 
    117     pvmp3_InitDecoder(mConfig, mDecoderBuf);
    118     mIsFirst = true;
    119 }
    120 
    121 OMX_ERRORTYPE SoftMP3::internalGetParameter(
    122         OMX_INDEXTYPE index, OMX_PTR params) {
    123     switch (index) {
    124         case OMX_IndexParamAudioPcm:
    125         {
    126             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    127                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    128 
    129             if (pcmParams->nPortIndex > 1) {
    130                 return OMX_ErrorUndefined;
    131             }
    132 
    133             pcmParams->eNumData = OMX_NumericalDataSigned;
    134             pcmParams->eEndian = OMX_EndianBig;
    135             pcmParams->bInterleaved = OMX_TRUE;
    136             pcmParams->nBitPerSample = 16;
    137             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    138             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    139             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    140 
    141             pcmParams->nChannels = mNumChannels;
    142             pcmParams->nSamplingRate = mSamplingRate;
    143 
    144             return OMX_ErrorNone;
    145         }
    146 
    147         default:
    148             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    149     }
    150 }
    151 
    152 OMX_ERRORTYPE SoftMP3::internalSetParameter(
    153         OMX_INDEXTYPE index, const OMX_PTR params) {
    154     switch (index) {
    155         case OMX_IndexParamStandardComponentRole:
    156         {
    157             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    158                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    159 
    160             if (strncmp((const char *)roleParams->cRole,
    161                         "audio_decoder.mp3",
    162                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    163                 return OMX_ErrorUndefined;
    164             }
    165 
    166             return OMX_ErrorNone;
    167         }
    168 
    169         case OMX_IndexParamAudioPcm:
    170         {
    171             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    172                 (const OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    173 
    174             if (pcmParams->nPortIndex != 1) {
    175                 return OMX_ErrorUndefined;
    176             }
    177 
    178             mNumChannels = pcmParams->nChannels;
    179             mSamplingRate = pcmParams->nSamplingRate;
    180 
    181             return OMX_ErrorNone;
    182         }
    183 
    184         default:
    185             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    186     }
    187 }
    188 
    189 void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
    190     if (mSignalledError || mOutputPortSettingsChange != NONE) {
    191         return;
    192     }
    193 
    194     List<BufferInfo *> &inQueue = getPortQueue(0);
    195     List<BufferInfo *> &outQueue = getPortQueue(1);
    196 
    197     while (!inQueue.empty() && !outQueue.empty()) {
    198         BufferInfo *inInfo = *inQueue.begin();
    199         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    200 
    201         BufferInfo *outInfo = *outQueue.begin();
    202         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    203 
    204         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
    205             inQueue.erase(inQueue.begin());
    206             inInfo->mOwnedByUs = false;
    207             notifyEmptyBufferDone(inHeader);
    208 
    209             if (!mIsFirst) {
    210                 // pad the end of the stream with 529 samples, since that many samples
    211                 // were trimmed off the beginning when decoding started
    212                 outHeader->nFilledLen =
    213                     kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
    214 
    215                 memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
    216             } else {
    217                 // Since we never discarded frames from the start, we won't have
    218                 // to add any padding at the end either.
    219                 outHeader->nFilledLen = 0;
    220             }
    221 
    222             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    223 
    224             outQueue.erase(outQueue.begin());
    225             outInfo->mOwnedByUs = false;
    226             notifyFillBufferDone(outHeader);
    227             return;
    228         }
    229 
    230         if (inHeader->nOffset == 0) {
    231             mAnchorTimeUs = inHeader->nTimeStamp;
    232             mNumFramesOutput = 0;
    233         }
    234 
    235         mConfig->pInputBuffer =
    236             inHeader->pBuffer + inHeader->nOffset;
    237 
    238         mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
    239         mConfig->inputBufferMaxLength = 0;
    240         mConfig->inputBufferUsedLength = 0;
    241 
    242         mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
    243 
    244         mConfig->pOutputBuffer =
    245             reinterpret_cast<int16_t *>(outHeader->pBuffer);
    246 
    247         ERROR_CODE decoderErr;
    248         if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
    249                 != NO_DECODING_ERROR) {
    250             ALOGV("mp3 decoder returned error %d", decoderErr);
    251 
    252             if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
    253                         && decoderErr != SIDE_INFO_ERROR) {
    254                 ALOGE("mp3 decoder returned error %d", decoderErr);
    255 
    256                 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
    257                 mSignalledError = true;
    258                 return;
    259             }
    260 
    261             if (mConfig->outputFrameSize == 0) {
    262                 mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
    263             }
    264 
    265             // This is recoverable, just ignore the current frame and
    266             // play silence instead.
    267             memset(outHeader->pBuffer,
    268                    0,
    269                    mConfig->outputFrameSize * sizeof(int16_t));
    270 
    271             mConfig->inputBufferUsedLength = inHeader->nFilledLen;
    272         } else if (mConfig->samplingRate != mSamplingRate
    273                 || mConfig->num_channels != mNumChannels) {
    274             mSamplingRate = mConfig->samplingRate;
    275             mNumChannels = mConfig->num_channels;
    276 
    277             notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    278             mOutputPortSettingsChange = AWAITING_DISABLED;
    279             return;
    280         }
    281 
    282         if (mIsFirst) {
    283             mIsFirst = false;
    284             // The decoder delay is 529 samples, so trim that many samples off
    285             // the start of the first output buffer. This essentially makes this
    286             // decoder have zero delay, which the rest of the pipeline assumes.
    287             outHeader->nOffset =
    288                 kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
    289 
    290             outHeader->nFilledLen =
    291                 mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
    292         } else {
    293             outHeader->nOffset = 0;
    294             outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
    295         }
    296 
    297         outHeader->nTimeStamp =
    298             mAnchorTimeUs
    299                 + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;
    300 
    301         outHeader->nFlags = 0;
    302 
    303         CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
    304 
    305         inHeader->nOffset += mConfig->inputBufferUsedLength;
    306         inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
    307 
    308         mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
    309 
    310         if (inHeader->nFilledLen == 0) {
    311             inInfo->mOwnedByUs = false;
    312             inQueue.erase(inQueue.begin());
    313             inInfo = NULL;
    314             notifyEmptyBufferDone(inHeader);
    315             inHeader = NULL;
    316         }
    317 
    318         outInfo->mOwnedByUs = false;
    319         outQueue.erase(outQueue.begin());
    320         outInfo = NULL;
    321         notifyFillBufferDone(outHeader);
    322         outHeader = NULL;
    323     }
    324 }
    325 
    326 void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
    327     if (portIndex == 0) {
    328         // Make sure that the next buffer output does not still
    329         // depend on fragments from the last one decoded.
    330         pvmp3_InitDecoder(mConfig, mDecoderBuf);
    331         mIsFirst = true;
    332     }
    333 }
    334 
    335 void SoftMP3::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    336     if (portIndex != 1) {
    337         return;
    338     }
    339 
    340     switch (mOutputPortSettingsChange) {
    341         case NONE:
    342             break;
    343 
    344         case AWAITING_DISABLED:
    345         {
    346             CHECK(!enabled);
    347             mOutputPortSettingsChange = AWAITING_ENABLED;
    348             break;
    349         }
    350 
    351         default:
    352         {
    353             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    354             CHECK(enabled);
    355             mOutputPortSettingsChange = NONE;
    356             break;
    357         }
    358     }
    359 }
    360 
    361 void SoftMP3::onReset() {
    362     pvmp3_InitDecoder(mConfig, mDecoderBuf);
    363     mIsFirst = true;
    364     mSignalledError = false;
    365     mOutputPortSettingsChange = NONE;
    366 }
    367 
    368 }  // namespace android
    369 
    370 android::SoftOMXComponent *createSoftOMXComponent(
    371         const char *name, const OMX_CALLBACKTYPE *callbacks,
    372         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    373     return new android::SoftMP3(name, callbacks, appData, component);
    374 }
    375