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 void *SoftMP3::memsetSafe(OMX_BUFFERHEADERTYPE *outHeader, int c, size_t len) {
    124     if (len > outHeader->nAllocLen) {
    125         ALOGE("memset buffer too small: got %u, expected %zu", outHeader->nAllocLen, len);
    126         android_errorWriteLog(0x534e4554, "29422022");
    127         notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL);
    128         mSignalledError = true;
    129         return NULL;
    130     }
    131     return memset(outHeader->pBuffer, c, len);
    132 }
    133 
    134 OMX_ERRORTYPE SoftMP3::internalGetParameter(
    135         OMX_INDEXTYPE index, OMX_PTR params) {
    136     switch (index) {
    137         case OMX_IndexParamAudioPortFormat:
    138         {
    139             OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
    140                 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
    141 
    142             if (!isValidOMXParam(formatParams)) {
    143                 return OMX_ErrorBadParameter;
    144             }
    145 
    146             if (formatParams->nPortIndex > 1) {
    147                 return OMX_ErrorUndefined;
    148             }
    149 
    150             if (formatParams->nIndex > 0) {
    151                 return OMX_ErrorNoMore;
    152             }
    153 
    154             formatParams->eEncoding =
    155                 (formatParams->nPortIndex == 0)
    156                     ? OMX_AUDIO_CodingMP3 : OMX_AUDIO_CodingPCM;
    157 
    158             return OMX_ErrorNone;
    159         }
    160 
    161         case OMX_IndexParamAudioPcm:
    162         {
    163             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    164                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    165 
    166             if (!isValidOMXParam(pcmParams)) {
    167                 return OMX_ErrorBadParameter;
    168             }
    169 
    170             if (pcmParams->nPortIndex > 1) {
    171                 return OMX_ErrorUndefined;
    172             }
    173 
    174             pcmParams->eNumData = OMX_NumericalDataSigned;
    175             pcmParams->eEndian = OMX_EndianBig;
    176             pcmParams->bInterleaved = OMX_TRUE;
    177             pcmParams->nBitPerSample = 16;
    178             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    179             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    180             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    181 
    182             pcmParams->nChannels = mNumChannels;
    183             pcmParams->nSamplingRate = mSamplingRate;
    184 
    185             return OMX_ErrorNone;
    186         }
    187 
    188         case OMX_IndexParamAudioMp3:
    189         {
    190             OMX_AUDIO_PARAM_MP3TYPE *mp3Params =
    191                 (OMX_AUDIO_PARAM_MP3TYPE *)params;
    192 
    193             if (!isValidOMXParam(mp3Params)) {
    194                 return OMX_ErrorBadParameter;
    195             }
    196 
    197             if (mp3Params->nPortIndex > 1) {
    198                 return OMX_ErrorUndefined;
    199             }
    200 
    201             mp3Params->nChannels = mNumChannels;
    202             mp3Params->nBitRate = 0 /* unknown */;
    203             mp3Params->nSampleRate = mSamplingRate;
    204             // other fields are encoder-only
    205 
    206             return OMX_ErrorNone;
    207         }
    208 
    209         default:
    210             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    211     }
    212 }
    213 
    214 OMX_ERRORTYPE SoftMP3::internalSetParameter(
    215         OMX_INDEXTYPE index, const OMX_PTR params) {
    216     switch (index) {
    217         case OMX_IndexParamStandardComponentRole:
    218         {
    219             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    220                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    221 
    222             if (!isValidOMXParam(roleParams)) {
    223                 return OMX_ErrorBadParameter;
    224             }
    225 
    226             if (strncmp((const char *)roleParams->cRole,
    227                         "audio_decoder.mp3",
    228                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    229                 return OMX_ErrorUndefined;
    230             }
    231 
    232             return OMX_ErrorNone;
    233         }
    234 
    235         case OMX_IndexParamAudioPortFormat:
    236         {
    237             const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
    238                 (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
    239 
    240             if (!isValidOMXParam(formatParams)) {
    241                 return OMX_ErrorBadParameter;
    242             }
    243 
    244             if (formatParams->nPortIndex > 1) {
    245                 return OMX_ErrorUndefined;
    246             }
    247 
    248             if ((formatParams->nPortIndex == 0
    249                         && formatParams->eEncoding != OMX_AUDIO_CodingMP3)
    250                 || (formatParams->nPortIndex == 1
    251                         && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
    252                 return OMX_ErrorUndefined;
    253             }
    254 
    255             return OMX_ErrorNone;
    256         }
    257 
    258         case OMX_IndexParamAudioPcm:
    259         {
    260             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    261                 (const OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    262 
    263             if (!isValidOMXParam(pcmParams)) {
    264                 return OMX_ErrorBadParameter;
    265             }
    266 
    267             if (pcmParams->nPortIndex != 1) {
    268                 return OMX_ErrorUndefined;
    269             }
    270 
    271             mNumChannels = pcmParams->nChannels;
    272             mSamplingRate = pcmParams->nSamplingRate;
    273 
    274             return OMX_ErrorNone;
    275         }
    276 
    277         default:
    278             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    279     }
    280 }
    281 
    282 void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
    283     if (mSignalledError || mOutputPortSettingsChange != NONE) {
    284         return;
    285     }
    286 
    287     List<BufferInfo *> &inQueue = getPortQueue(0);
    288     List<BufferInfo *> &outQueue = getPortQueue(1);
    289 
    290     while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
    291         BufferInfo *inInfo = NULL;
    292         OMX_BUFFERHEADERTYPE *inHeader = NULL;
    293         if (!inQueue.empty()) {
    294             inInfo = *inQueue.begin();
    295             inHeader = inInfo->mHeader;
    296         }
    297 
    298         BufferInfo *outInfo = *outQueue.begin();
    299         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    300         outHeader->nFlags = 0;
    301 
    302         if (inHeader) {
    303             if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
    304                 mAnchorTimeUs = inHeader->nTimeStamp;
    305                 mNumFramesOutput = 0;
    306             }
    307 
    308             if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
    309                 mSawInputEos = true;
    310             }
    311 
    312             mConfig->pInputBuffer =
    313                 inHeader->pBuffer + inHeader->nOffset;
    314 
    315             mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
    316         } else {
    317             mConfig->pInputBuffer = NULL;
    318             mConfig->inputBufferCurrentLength = 0;
    319         }
    320         mConfig->inputBufferMaxLength = 0;
    321         mConfig->inputBufferUsedLength = 0;
    322 
    323         mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
    324         if ((int32_t)outHeader->nAllocLen < mConfig->outputFrameSize) {
    325             ALOGE("input buffer too small: got %u, expected %u",
    326                 outHeader->nAllocLen, mConfig->outputFrameSize);
    327             android_errorWriteLog(0x534e4554, "27793371");
    328             notify(OMX_EventError, OMX_ErrorUndefined, OUTPUT_BUFFER_TOO_SMALL, NULL);
    329             mSignalledError = true;
    330             return;
    331         }
    332 
    333         mConfig->pOutputBuffer =
    334             reinterpret_cast<int16_t *>(outHeader->pBuffer);
    335 
    336         ERROR_CODE decoderErr;
    337         if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf))
    338                 != NO_DECODING_ERROR) {
    339             ALOGV("mp3 decoder returned error %d", decoderErr);
    340 
    341             if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR
    342                         && decoderErr != SIDE_INFO_ERROR) {
    343                 ALOGE("mp3 decoder returned error %d", decoderErr);
    344 
    345                 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
    346                 mSignalledError = true;
    347                 return;
    348             }
    349 
    350             if (mConfig->outputFrameSize == 0) {
    351                 mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
    352             }
    353 
    354             if (decoderErr == NO_ENOUGH_MAIN_DATA_ERROR && mSawInputEos) {
    355                 if (!mIsFirst) {
    356                     // pad the end of the stream with 529 samples, since that many samples
    357                     // were trimmed off the beginning when decoding started
    358                     outHeader->nOffset = 0;
    359                     outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
    360 
    361                     if (!memsetSafe(outHeader, 0, outHeader->nFilledLen)) {
    362                         return;
    363                     }
    364 
    365                 }
    366                 outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    367                 mSignalledOutputEos = true;
    368             } else {
    369                 // This is recoverable, just ignore the current frame and
    370                 // play silence instead.
    371 
    372                 // TODO: should we skip silence (and consume input data)
    373                 // if mIsFirst is true as we may not have a valid
    374                 // mConfig->samplingRate and mConfig->num_channels?
    375                 ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence");
    376                 if (!memsetSafe(outHeader, 0, mConfig->outputFrameSize * sizeof(int16_t))) {
    377                     return;
    378                 }
    379 
    380                 if (inHeader) {
    381                     mConfig->inputBufferUsedLength = inHeader->nFilledLen;
    382                 }
    383             }
    384         } else if (mConfig->samplingRate != mSamplingRate
    385                 || mConfig->num_channels != mNumChannels) {
    386             mSamplingRate = mConfig->samplingRate;
    387             mNumChannels = mConfig->num_channels;
    388 
    389             notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    390             mOutputPortSettingsChange = AWAITING_DISABLED;
    391             return;
    392         }
    393 
    394         if (mIsFirst) {
    395             mIsFirst = false;
    396             // The decoder delay is 529 samples, so trim that many samples off
    397             // the start of the first output buffer. This essentially makes this
    398             // decoder have zero delay, which the rest of the pipeline assumes.
    399             outHeader->nOffset =
    400                 kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
    401 
    402             outHeader->nFilledLen =
    403                 mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
    404         } else if (!mSignalledOutputEos) {
    405             outHeader->nOffset = 0;
    406             outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
    407         }
    408 
    409         outHeader->nTimeStamp =
    410             mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
    411 
    412         if (inHeader) {
    413             CHECK_GE((int32_t)inHeader->nFilledLen, mConfig->inputBufferUsedLength);
    414 
    415             inHeader->nOffset += mConfig->inputBufferUsedLength;
    416             inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
    417 
    418 
    419             if (inHeader->nFilledLen == 0) {
    420                 inInfo->mOwnedByUs = false;
    421                 inQueue.erase(inQueue.begin());
    422                 inInfo = NULL;
    423                 notifyEmptyBufferDone(inHeader);
    424                 inHeader = NULL;
    425             }
    426         }
    427 
    428         mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
    429 
    430         outInfo->mOwnedByUs = false;
    431         outQueue.erase(outQueue.begin());
    432         outInfo = NULL;
    433         notifyFillBufferDone(outHeader);
    434         outHeader = NULL;
    435     }
    436 }
    437 
    438 void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) {
    439     if (portIndex == 0) {
    440         // Make sure that the next buffer output does not still
    441         // depend on fragments from the last one decoded.
    442         pvmp3_InitDecoder(mConfig, mDecoderBuf);
    443         mIsFirst = true;
    444         mSignalledError = false;
    445         mSawInputEos = false;
    446         mSignalledOutputEos = false;
    447     }
    448 }
    449 
    450 void SoftMP3::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    451     if (portIndex != 1) {
    452         return;
    453     }
    454 
    455     switch (mOutputPortSettingsChange) {
    456         case NONE:
    457             break;
    458 
    459         case AWAITING_DISABLED:
    460         {
    461             CHECK(!enabled);
    462             mOutputPortSettingsChange = AWAITING_ENABLED;
    463             break;
    464         }
    465 
    466         default:
    467         {
    468             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    469             CHECK(enabled);
    470             mOutputPortSettingsChange = NONE;
    471             break;
    472         }
    473     }
    474 }
    475 
    476 void SoftMP3::onReset() {
    477     pvmp3_InitDecoder(mConfig, mDecoderBuf);
    478     mIsFirst = true;
    479     mSignalledError = false;
    480     mSawInputEos = false;
    481     mSignalledOutputEos = false;
    482     mOutputPortSettingsChange = NONE;
    483 }
    484 
    485 }  // namespace android
    486 
    487 android::SoftOMXComponent *createSoftOMXComponent(
    488         const char *name, const OMX_CALLBACKTYPE *callbacks,
    489         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    490     return new android::SoftMP3(name, callbacks, appData, component);
    491 }
    492