Home | History | Annotate | Download | only in dec
      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 "SoftAMR"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftAMR.h"
     22 
     23 #include "gsmamr_dec.h"
     24 #include "pvamrwbdecoder.h"
     25 
     26 #include <media/stagefright/foundation/ADebug.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 SoftAMR::SoftAMR(
     40         const char *name,
     41         const OMX_CALLBACKTYPE *callbacks,
     42         OMX_PTR appData,
     43         OMX_COMPONENTTYPE **component)
     44     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     45       mMode(MODE_NARROW),
     46       mState(NULL),
     47       mDecoderBuf(NULL),
     48       mDecoderCookie(NULL),
     49       mInputBufferCount(0),
     50       mAnchorTimeUs(0),
     51       mNumSamplesOutput(0),
     52       mSignalledError(false),
     53       mOutputPortSettingsChange(NONE) {
     54     if (!strcmp(name, "OMX.google.amrwb.decoder")) {
     55         mMode = MODE_WIDE;
     56     } else {
     57         CHECK(!strcmp(name, "OMX.google.amrnb.decoder"));
     58     }
     59 
     60     initPorts();
     61     CHECK_EQ(initDecoder(), (status_t)OK);
     62 }
     63 
     64 SoftAMR::~SoftAMR() {
     65     if (mMode == MODE_NARROW) {
     66         GSMDecodeFrameExit(&mState);
     67         mState = NULL;
     68     } else {
     69         free(mDecoderBuf);
     70         mDecoderBuf = NULL;
     71 
     72         mState = NULL;
     73         mDecoderCookie = NULL;
     74     }
     75 }
     76 
     77 void SoftAMR::initPorts() {
     78     OMX_PARAM_PORTDEFINITIONTYPE def;
     79     InitOMXParams(&def);
     80 
     81     def.nPortIndex = 0;
     82     def.eDir = OMX_DirInput;
     83     def.nBufferCountMin = kNumBuffers;
     84     def.nBufferCountActual = def.nBufferCountMin;
     85     def.nBufferSize = 8192;
     86     def.bEnabled = OMX_TRUE;
     87     def.bPopulated = OMX_FALSE;
     88     def.eDomain = OMX_PortDomainAudio;
     89     def.bBuffersContiguous = OMX_FALSE;
     90     def.nBufferAlignment = 1;
     91 
     92     def.format.audio.cMIMEType =
     93         mMode == MODE_NARROW
     94             ? const_cast<char *>("audio/amr")
     95             : const_cast<char *>("audio/amrwb");
     96 
     97     def.format.audio.pNativeRender = NULL;
     98     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     99     def.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
    100 
    101     addPort(def);
    102 
    103     def.nPortIndex = 1;
    104     def.eDir = OMX_DirOutput;
    105     def.nBufferCountMin = kNumBuffers;
    106     def.nBufferCountActual = def.nBufferCountMin;
    107 
    108     def.nBufferSize =
    109         (mMode == MODE_NARROW ? kNumSamplesPerFrameNB : kNumSamplesPerFrameWB)
    110             * sizeof(int16_t);
    111 
    112     def.bEnabled = OMX_TRUE;
    113     def.bPopulated = OMX_FALSE;
    114     def.eDomain = OMX_PortDomainAudio;
    115     def.bBuffersContiguous = OMX_FALSE;
    116     def.nBufferAlignment = 2;
    117 
    118     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    119     def.format.audio.pNativeRender = NULL;
    120     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    121     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    122 
    123     addPort(def);
    124 }
    125 
    126 status_t SoftAMR::initDecoder() {
    127     if (mMode == MODE_NARROW) {
    128         Word16 err = GSMInitDecode(&mState, (Word8 *)"AMRNBDecoder");
    129 
    130         if (err != 0) {
    131             return UNKNOWN_ERROR;
    132         }
    133     } else {
    134         int32_t memReq = pvDecoder_AmrWbMemRequirements();
    135         mDecoderBuf = malloc(memReq);
    136 
    137         pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie);
    138     }
    139 
    140     return OK;
    141 }
    142 
    143 OMX_ERRORTYPE SoftAMR::internalGetParameter(
    144         OMX_INDEXTYPE index, OMX_PTR params) {
    145     switch (index) {
    146         case OMX_IndexParamAudioPortFormat:
    147         {
    148             OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
    149                 (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
    150 
    151             if (!isValidOMXParam(formatParams)) {
    152                 return OMX_ErrorBadParameter;
    153             }
    154 
    155             if (formatParams->nPortIndex > 1) {
    156                 return OMX_ErrorUndefined;
    157             }
    158 
    159             if (formatParams->nIndex > 0) {
    160                 return OMX_ErrorNoMore;
    161             }
    162 
    163             formatParams->eEncoding =
    164                 (formatParams->nPortIndex == 0)
    165                     ? OMX_AUDIO_CodingAMR : OMX_AUDIO_CodingPCM;
    166 
    167             return OMX_ErrorNone;
    168         }
    169 
    170         case OMX_IndexParamAudioAmr:
    171         {
    172             OMX_AUDIO_PARAM_AMRTYPE *amrParams =
    173                 (OMX_AUDIO_PARAM_AMRTYPE *)params;
    174 
    175             if (!isValidOMXParam(amrParams)) {
    176                 return OMX_ErrorBadParameter;
    177             }
    178 
    179             if (amrParams->nPortIndex != 0) {
    180                 return OMX_ErrorUndefined;
    181             }
    182 
    183             amrParams->nChannels = 1;
    184             amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
    185             amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
    186 
    187             if (!isConfigured()) {
    188                 amrParams->nBitRate = 0;
    189                 amrParams->eAMRBandMode = OMX_AUDIO_AMRBandModeUnused;
    190             } else {
    191                 amrParams->nBitRate = 0;
    192                 amrParams->eAMRBandMode =
    193                     mMode == MODE_NARROW
    194                         ? OMX_AUDIO_AMRBandModeNB0 : OMX_AUDIO_AMRBandModeWB0;
    195             }
    196 
    197             return OMX_ErrorNone;
    198         }
    199 
    200         case OMX_IndexParamAudioPcm:
    201         {
    202             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    203                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    204 
    205             if (!isValidOMXParam(pcmParams)) {
    206                 return OMX_ErrorBadParameter;
    207             }
    208 
    209             if (pcmParams->nPortIndex != 1) {
    210                 return OMX_ErrorUndefined;
    211             }
    212 
    213             pcmParams->nChannels = 1;
    214             pcmParams->eNumData = OMX_NumericalDataSigned;
    215             pcmParams->eEndian = OMX_EndianBig;
    216             pcmParams->bInterleaved = OMX_TRUE;
    217             pcmParams->nBitPerSample = 16;
    218 
    219             pcmParams->nSamplingRate =
    220                 (mMode == MODE_NARROW) ? kSampleRateNB : kSampleRateWB;
    221 
    222             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    223             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    224             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    225 
    226             return OMX_ErrorNone;
    227         }
    228 
    229         default:
    230             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    231     }
    232 }
    233 
    234 OMX_ERRORTYPE SoftAMR::internalSetParameter(
    235         OMX_INDEXTYPE index, const OMX_PTR params) {
    236     switch (index) {
    237         case OMX_IndexParamStandardComponentRole:
    238         {
    239             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    240                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    241 
    242             if (!isValidOMXParam(roleParams)) {
    243                 return OMX_ErrorBadParameter;
    244             }
    245 
    246             if (mMode == MODE_NARROW) {
    247                 if (strncmp((const char *)roleParams->cRole,
    248                             "audio_decoder.amrnb",
    249                             OMX_MAX_STRINGNAME_SIZE - 1)) {
    250                     return OMX_ErrorUndefined;
    251                 }
    252             } else {
    253                 if (strncmp((const char *)roleParams->cRole,
    254                             "audio_decoder.amrwb",
    255                             OMX_MAX_STRINGNAME_SIZE - 1)) {
    256                     return OMX_ErrorUndefined;
    257                 }
    258             }
    259 
    260             return OMX_ErrorNone;
    261         }
    262 
    263         case OMX_IndexParamAudioPortFormat:
    264         {
    265             const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
    266                 (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
    267 
    268             if (!isValidOMXParam(formatParams)) {
    269                 return OMX_ErrorBadParameter;
    270             }
    271 
    272             if (formatParams->nPortIndex > 1) {
    273                 return OMX_ErrorUndefined;
    274             }
    275 
    276             if ((formatParams->nPortIndex == 0
    277                         && formatParams->eEncoding != OMX_AUDIO_CodingAMR)
    278                 || (formatParams->nPortIndex == 1
    279                         && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
    280                 return OMX_ErrorUndefined;
    281             }
    282 
    283             return OMX_ErrorNone;
    284         }
    285 
    286         case OMX_IndexParamAudioAmr:
    287         {
    288             const OMX_AUDIO_PARAM_AMRTYPE *aacParams =
    289                 (const OMX_AUDIO_PARAM_AMRTYPE *)params;
    290 
    291             if (!isValidOMXParam(aacParams)) {
    292                 return OMX_ErrorBadParameter;
    293             }
    294 
    295             if (aacParams->nPortIndex != 0) {
    296                 return OMX_ErrorUndefined;
    297             }
    298 
    299             return OMX_ErrorNone;
    300         }
    301 
    302         case OMX_IndexParamAudioPcm:
    303         {
    304             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    305                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    306 
    307             if (!isValidOMXParam(pcmParams)) {
    308                 return OMX_ErrorBadParameter;
    309             }
    310 
    311             if (pcmParams->nPortIndex != 1) {
    312                 return OMX_ErrorUndefined;
    313             }
    314 
    315             return OMX_ErrorNone;
    316         }
    317 
    318         default:
    319             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    320     }
    321 }
    322 
    323 bool SoftAMR::isConfigured() const {
    324     return mInputBufferCount > 0;
    325 }
    326 
    327 static size_t getFrameSize(unsigned FT) {
    328     static const size_t kFrameSizeWB[10] = {
    329         132, 177, 253, 285, 317, 365, 397, 461, 477, 40
    330     };
    331 
    332     if (FT >= 10) {
    333         return 1;
    334     }
    335 
    336     size_t frameSize = kFrameSizeWB[FT];
    337 
    338     // Round up bits to bytes and add 1 for the header byte.
    339     frameSize = (frameSize + 7) / 8 + 1;
    340 
    341     return frameSize;
    342 }
    343 
    344 void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) {
    345     List<BufferInfo *> &inQueue = getPortQueue(0);
    346     List<BufferInfo *> &outQueue = getPortQueue(1);
    347 
    348     if (mSignalledError || mOutputPortSettingsChange != NONE) {
    349         return;
    350     }
    351 
    352     while (!inQueue.empty() && !outQueue.empty()) {
    353         BufferInfo *inInfo = *inQueue.begin();
    354         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    355 
    356         BufferInfo *outInfo = *outQueue.begin();
    357         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    358 
    359         if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && inHeader->nFilledLen == 0) {
    360             inQueue.erase(inQueue.begin());
    361             inInfo->mOwnedByUs = false;
    362             notifyEmptyBufferDone(inHeader);
    363 
    364             outHeader->nFilledLen = 0;
    365             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    366 
    367             outQueue.erase(outQueue.begin());
    368             outInfo->mOwnedByUs = false;
    369             notifyFillBufferDone(outHeader);
    370             return;
    371         }
    372 
    373         if (inHeader->nFilledLen == 0) {
    374             inInfo->mOwnedByUs = false;
    375             inQueue.erase(inQueue.begin());
    376             notifyEmptyBufferDone(inHeader);
    377             continue;
    378         }
    379 
    380         if (inHeader->nOffset == 0) {
    381             mAnchorTimeUs = inHeader->nTimeStamp;
    382             mNumSamplesOutput = 0;
    383         }
    384 
    385         const uint8_t *inputPtr = inHeader->pBuffer + inHeader->nOffset;
    386         int32_t numBytesRead;
    387 
    388         if (mMode == MODE_NARROW) {
    389             if (outHeader->nAllocLen < kNumSamplesPerFrameNB * sizeof(int16_t)) {
    390                 ALOGE("b/27662364: NB expected output buffer %zu bytes vs %u",
    391                        kNumSamplesPerFrameNB * sizeof(int16_t), outHeader->nAllocLen);
    392                 android_errorWriteLog(0x534e4554, "27662364");
    393                 notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL);
    394                 mSignalledError = true;
    395                 return;
    396             }
    397 
    398             int16 mode = ((inputPtr[0] >> 3) & 0x0f);
    399             // for WMF since MIME_IETF is used when calling AMRDecode.
    400             size_t frameSize = WmfDecBytesPerFrame[mode] + 1;
    401 
    402             if (inHeader->nFilledLen < frameSize) {
    403                 ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen);
    404                 notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL);
    405                 mSignalledError = true;
    406                 return;
    407             }
    408 
    409             numBytesRead =
    410                 AMRDecode(mState,
    411                   (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f),
    412                   (UWord8 *)&inputPtr[1],
    413                   reinterpret_cast<int16_t *>(outHeader->pBuffer),
    414                   MIME_IETF);
    415 
    416             if (numBytesRead == -1) {
    417                 ALOGE("PV AMR decoder AMRDecode() call failed");
    418 
    419                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    420                 mSignalledError = true;
    421 
    422                 return;
    423             }
    424 
    425             ++numBytesRead;  // Include the frame type header byte.
    426 
    427             if (static_cast<size_t>(numBytesRead) > inHeader->nFilledLen) {
    428                 // This is bad, should never have happened, but did. Abort now.
    429 
    430                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    431                 mSignalledError = true;
    432 
    433                 return;
    434             }
    435         } else {
    436             if (outHeader->nAllocLen < kNumSamplesPerFrameWB * sizeof(int16_t)) {
    437                 ALOGE("b/27662364: WB expected output buffer %zu bytes vs %u",
    438                        kNumSamplesPerFrameWB * sizeof(int16_t), outHeader->nAllocLen);
    439                 android_errorWriteLog(0x534e4554, "27662364");
    440                 notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL);
    441                 mSignalledError = true;
    442                 return;
    443             }
    444 
    445             int16 mode = ((inputPtr[0] >> 3) & 0x0f);
    446 
    447             if (mode >= 10 && mode <= 13) {
    448                 ALOGE("encountered illegal frame type %d in AMR WB content.",
    449                       mode);
    450 
    451                 notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
    452                 mSignalledError = true;
    453 
    454                 return;
    455             }
    456 
    457             size_t frameSize = getFrameSize(mode);
    458             if (inHeader->nFilledLen < frameSize) {
    459                 ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen);
    460                 notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL);
    461                 mSignalledError = true;
    462                 return;
    463             }
    464 
    465             int16_t *outPtr = (int16_t *)outHeader->pBuffer;
    466 
    467             if (mode >= 9) {
    468                 // Produce silence instead of comfort noise and for
    469                 // speech lost/no data.
    470                 memset(outPtr, 0, kNumSamplesPerFrameWB * sizeof(int16_t));
    471             } else if (mode < 9) {
    472                 int16 frameType;
    473                 RX_State_wb rx_state;
    474                 mime_unsorting(
    475                         const_cast<uint8_t *>(&inputPtr[1]),
    476                         mInputSampleBuffer,
    477                         &frameType, &mode, 1, &rx_state);
    478 
    479                 int16_t numSamplesOutput;
    480                 pvDecoder_AmrWb(
    481                         mode, mInputSampleBuffer,
    482                         outPtr,
    483                         &numSamplesOutput,
    484                         mDecoderBuf, frameType, mDecoderCookie);
    485 
    486                 CHECK_EQ((int)numSamplesOutput, (int)kNumSamplesPerFrameWB);
    487 
    488                 for (int i = 0; i < kNumSamplesPerFrameWB; ++i) {
    489                     /* Delete the 2 LSBs (14-bit output) */
    490                     outPtr[i] &= 0xfffC;
    491                 }
    492             }
    493 
    494             numBytesRead = frameSize;
    495         }
    496 
    497         inHeader->nOffset += numBytesRead;
    498         inHeader->nFilledLen -= numBytesRead;
    499 
    500         outHeader->nFlags = 0;
    501         outHeader->nOffset = 0;
    502 
    503         if (mMode == MODE_NARROW) {
    504             outHeader->nFilledLen = kNumSamplesPerFrameNB * sizeof(int16_t);
    505 
    506             outHeader->nTimeStamp =
    507                 mAnchorTimeUs
    508                     + (mNumSamplesOutput * 1000000ll) / kSampleRateNB;
    509 
    510             mNumSamplesOutput += kNumSamplesPerFrameNB;
    511         } else {
    512             outHeader->nFilledLen = kNumSamplesPerFrameWB * sizeof(int16_t);
    513 
    514             outHeader->nTimeStamp =
    515                 mAnchorTimeUs
    516                     + (mNumSamplesOutput * 1000000ll) / kSampleRateWB;
    517 
    518             mNumSamplesOutput += kNumSamplesPerFrameWB;
    519         }
    520 
    521         if (inHeader->nFilledLen == 0 && (inHeader->nFlags & OMX_BUFFERFLAG_EOS) == 0) {
    522             inInfo->mOwnedByUs = false;
    523             inQueue.erase(inQueue.begin());
    524             inInfo = NULL;
    525             notifyEmptyBufferDone(inHeader);
    526             inHeader = NULL;
    527         }
    528 
    529         outInfo->mOwnedByUs = false;
    530         outQueue.erase(outQueue.begin());
    531         outInfo = NULL;
    532         notifyFillBufferDone(outHeader);
    533         outHeader = NULL;
    534 
    535         ++mInputBufferCount;
    536     }
    537 }
    538 
    539 void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) {
    540     ALOGV("onPortFlushCompleted portindex %d, resetting frame ", portIndex);
    541     if (portIndex == 0) {
    542         if (mMode == MODE_NARROW) {
    543            Speech_Decode_Frame_reset(mState);
    544         } else {
    545            pvDecoder_AmrWb_Reset(mState, 0 /* reset_all */);
    546         }
    547     }
    548 }
    549 
    550 void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    551     if (portIndex != 1) {
    552         return;
    553     }
    554 
    555     switch (mOutputPortSettingsChange) {
    556         case NONE:
    557             break;
    558 
    559         case AWAITING_DISABLED:
    560         {
    561             CHECK(!enabled);
    562             mOutputPortSettingsChange = AWAITING_ENABLED;
    563             break;
    564         }
    565 
    566         default:
    567         {
    568             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    569             CHECK(enabled);
    570             mOutputPortSettingsChange = NONE;
    571             break;
    572         }
    573     }
    574 }
    575 
    576 void SoftAMR::onReset() {
    577     mSignalledError = false;
    578     mOutputPortSettingsChange = NONE;
    579 }
    580 
    581 }  // namespace android
    582 
    583 android::SoftOMXComponent *createSoftOMXComponent(
    584         const char *name, const OMX_CALLBACKTYPE *callbacks,
    585         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    586     return new android::SoftAMR(name, callbacks, appData, component);
    587 }
    588 
    589