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