Home | History | Annotate | Download | only in aacdec
      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 "SoftAAC"
     19 #include <utils/Log.h>
     20 
     21 #include "SoftAAC.h"
     22 
     23 #include "pvmp4audiodecoder_api.h"
     24 
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/foundation/hexdump.h>
     27 #include <media/stagefright/MediaErrors.h>
     28 
     29 namespace android {
     30 
     31 template<class T>
     32 static void InitOMXParams(T *params) {
     33     params->nSize = sizeof(T);
     34     params->nVersion.s.nVersionMajor = 1;
     35     params->nVersion.s.nVersionMinor = 0;
     36     params->nVersion.s.nRevision = 0;
     37     params->nVersion.s.nStep = 0;
     38 }
     39 
     40 SoftAAC::SoftAAC(
     41         const char *name,
     42         const OMX_CALLBACKTYPE *callbacks,
     43         OMX_PTR appData,
     44         OMX_COMPONENTTYPE **component)
     45     : SimpleSoftOMXComponent(name, callbacks, appData, component),
     46       mConfig(new tPVMP4AudioDecoderExternal),
     47       mIsADTS(false),
     48       mDecoderBuf(NULL),
     49       mInputBufferCount(0),
     50       mUpsamplingFactor(2),
     51       mAnchorTimeUs(0),
     52       mNumSamplesOutput(0),
     53       mSignalledError(false),
     54       mOutputPortSettingsChange(NONE) {
     55     initPorts();
     56     CHECK_EQ(initDecoder(), (status_t)OK);
     57 }
     58 
     59 SoftAAC::~SoftAAC() {
     60     free(mDecoderBuf);
     61     mDecoderBuf = NULL;
     62 
     63     delete mConfig;
     64     mConfig = NULL;
     65 }
     66 
     67 void SoftAAC::initPorts() {
     68     OMX_PARAM_PORTDEFINITIONTYPE def;
     69     InitOMXParams(&def);
     70 
     71     def.nPortIndex = 0;
     72     def.eDir = OMX_DirInput;
     73     def.nBufferCountMin = kNumInputBuffers;
     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 = const_cast<char *>("audio/aac");
     83     def.format.audio.pNativeRender = NULL;
     84     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
     85     def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
     86 
     87     addPort(def);
     88 
     89     def.nPortIndex = 1;
     90     def.eDir = OMX_DirOutput;
     91     def.nBufferCountMin = kNumOutputBuffers;
     92     def.nBufferCountActual = def.nBufferCountMin;
     93     def.nBufferSize = 8192;
     94     def.bEnabled = OMX_TRUE;
     95     def.bPopulated = OMX_FALSE;
     96     def.eDomain = OMX_PortDomainAudio;
     97     def.bBuffersContiguous = OMX_FALSE;
     98     def.nBufferAlignment = 2;
     99 
    100     def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
    101     def.format.audio.pNativeRender = NULL;
    102     def.format.audio.bFlagErrorConcealment = OMX_FALSE;
    103     def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
    104 
    105     addPort(def);
    106 }
    107 
    108 status_t SoftAAC::initDecoder() {
    109     memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
    110     mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
    111     mConfig->aacPlusEnabled = 1;
    112 
    113     // The software decoder doesn't properly support mono output on
    114     // AACplus files. Always output stereo.
    115     mConfig->desiredChannels = 2;
    116 
    117     UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
    118     mDecoderBuf = malloc(memRequirements);
    119 
    120     Int err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
    121     if (err != MP4AUDEC_SUCCESS) {
    122         ALOGE("Failed to initialize MP4 audio decoder");
    123         return UNKNOWN_ERROR;
    124     }
    125 
    126     return OK;
    127 }
    128 
    129 OMX_ERRORTYPE SoftAAC::internalGetParameter(
    130         OMX_INDEXTYPE index, OMX_PTR params) {
    131     switch (index) {
    132         case OMX_IndexParamAudioAac:
    133         {
    134             OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
    135                 (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
    136 
    137             if (aacParams->nPortIndex != 0) {
    138                 return OMX_ErrorUndefined;
    139             }
    140 
    141             aacParams->nBitRate = 0;
    142             aacParams->nAudioBandWidth = 0;
    143             aacParams->nAACtools = 0;
    144             aacParams->nAACERtools = 0;
    145             aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
    146 
    147             aacParams->eAACStreamFormat =
    148                 mIsADTS
    149                     ? OMX_AUDIO_AACStreamFormatMP4ADTS
    150                     : OMX_AUDIO_AACStreamFormatMP4FF;
    151 
    152             aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
    153 
    154             if (!isConfigured()) {
    155                 aacParams->nChannels = 1;
    156                 aacParams->nSampleRate = 44100;
    157                 aacParams->nFrameLength = 0;
    158             } else {
    159                 aacParams->nChannels = mConfig->encodedChannels;
    160                 aacParams->nSampleRate = mConfig->samplingRate;
    161                 aacParams->nFrameLength = mConfig->frameLength;
    162             }
    163 
    164             return OMX_ErrorNone;
    165         }
    166 
    167         case OMX_IndexParamAudioPcm:
    168         {
    169             OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    170                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    171 
    172             if (pcmParams->nPortIndex != 1) {
    173                 return OMX_ErrorUndefined;
    174             }
    175 
    176             pcmParams->eNumData = OMX_NumericalDataSigned;
    177             pcmParams->eEndian = OMX_EndianBig;
    178             pcmParams->bInterleaved = OMX_TRUE;
    179             pcmParams->nBitPerSample = 16;
    180             pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
    181             pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    182             pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    183 
    184             if (!isConfigured()) {
    185                 pcmParams->nChannels = 1;
    186                 pcmParams->nSamplingRate = 44100;
    187             } else {
    188                 pcmParams->nChannels = mConfig->desiredChannels;
    189                 pcmParams->nSamplingRate = mConfig->samplingRate;
    190             }
    191 
    192             return OMX_ErrorNone;
    193         }
    194 
    195         default:
    196             return SimpleSoftOMXComponent::internalGetParameter(index, params);
    197     }
    198 }
    199 
    200 OMX_ERRORTYPE SoftAAC::internalSetParameter(
    201         OMX_INDEXTYPE index, const OMX_PTR params) {
    202     switch (index) {
    203         case OMX_IndexParamStandardComponentRole:
    204         {
    205             const OMX_PARAM_COMPONENTROLETYPE *roleParams =
    206                 (const OMX_PARAM_COMPONENTROLETYPE *)params;
    207 
    208             if (strncmp((const char *)roleParams->cRole,
    209                         "audio_decoder.aac",
    210                         OMX_MAX_STRINGNAME_SIZE - 1)) {
    211                 return OMX_ErrorUndefined;
    212             }
    213 
    214             return OMX_ErrorNone;
    215         }
    216 
    217         case OMX_IndexParamAudioAac:
    218         {
    219             const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
    220                 (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
    221 
    222             if (aacParams->nPortIndex != 0) {
    223                 return OMX_ErrorUndefined;
    224             }
    225 
    226             if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
    227                 mIsADTS = false;
    228             } else if (aacParams->eAACStreamFormat
    229                         == OMX_AUDIO_AACStreamFormatMP4ADTS) {
    230                 mIsADTS = true;
    231             } else {
    232                 return OMX_ErrorUndefined;
    233             }
    234 
    235             return OMX_ErrorNone;
    236         }
    237 
    238         case OMX_IndexParamAudioPcm:
    239         {
    240             const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
    241                 (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
    242 
    243             if (pcmParams->nPortIndex != 1) {
    244                 return OMX_ErrorUndefined;
    245             }
    246 
    247             return OMX_ErrorNone;
    248         }
    249 
    250         default:
    251             return SimpleSoftOMXComponent::internalSetParameter(index, params);
    252     }
    253 }
    254 
    255 bool SoftAAC::isConfigured() const {
    256     return mInputBufferCount > 0;
    257 }
    258 
    259 void SoftAAC::onQueueFilled(OMX_U32 portIndex) {
    260     if (mSignalledError || mOutputPortSettingsChange != NONE) {
    261         return;
    262     }
    263 
    264     List<BufferInfo *> &inQueue = getPortQueue(0);
    265     List<BufferInfo *> &outQueue = getPortQueue(1);
    266 
    267     if (portIndex == 0 && mInputBufferCount == 0) {
    268         ++mInputBufferCount;
    269 
    270         BufferInfo *info = *inQueue.begin();
    271         OMX_BUFFERHEADERTYPE *header = info->mHeader;
    272 
    273         mConfig->pInputBuffer = header->pBuffer + header->nOffset;
    274         mConfig->inputBufferCurrentLength = header->nFilledLen;
    275         mConfig->inputBufferMaxLength = 0;
    276 
    277         Int err = PVMP4AudioDecoderConfig(mConfig, mDecoderBuf);
    278         if (err != MP4AUDEC_SUCCESS) {
    279             mSignalledError = true;
    280             notify(OMX_EventError, OMX_ErrorUndefined, err, NULL);
    281             return;
    282         }
    283 
    284         inQueue.erase(inQueue.begin());
    285         info->mOwnedByUs = false;
    286         notifyEmptyBufferDone(header);
    287 
    288         notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    289         mOutputPortSettingsChange = AWAITING_DISABLED;
    290         return;
    291     }
    292 
    293     while (!inQueue.empty() && !outQueue.empty()) {
    294         BufferInfo *inInfo = *inQueue.begin();
    295         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
    296 
    297         BufferInfo *outInfo = *outQueue.begin();
    298         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
    299 
    300         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
    301             inQueue.erase(inQueue.begin());
    302             inInfo->mOwnedByUs = false;
    303             notifyEmptyBufferDone(inHeader);
    304 
    305             outHeader->nFilledLen = 0;
    306             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
    307 
    308             outQueue.erase(outQueue.begin());
    309             outInfo->mOwnedByUs = false;
    310             notifyFillBufferDone(outHeader);
    311             return;
    312         }
    313 
    314         if (inHeader->nOffset == 0) {
    315             mAnchorTimeUs = inHeader->nTimeStamp;
    316             mNumSamplesOutput = 0;
    317         }
    318 
    319         size_t adtsHeaderSize = 0;
    320         if (mIsADTS) {
    321             // skip 30 bits, aac_frame_length follows.
    322             // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
    323 
    324             const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
    325 
    326             bool signalError = false;
    327             if (inHeader->nFilledLen < 7) {
    328                 ALOGE("Audio data too short to contain even the ADTS header. "
    329                       "Got %ld bytes.", inHeader->nFilledLen);
    330                 hexdump(adtsHeader, inHeader->nFilledLen);
    331                 signalError = true;
    332             } else {
    333                 bool protectionAbsent = (adtsHeader[1] & 1);
    334 
    335                 unsigned aac_frame_length =
    336                     ((adtsHeader[3] & 3) << 11)
    337                     | (adtsHeader[4] << 3)
    338                     | (adtsHeader[5] >> 5);
    339 
    340                 if (inHeader->nFilledLen < aac_frame_length) {
    341                     ALOGE("Not enough audio data for the complete frame. "
    342                           "Got %ld bytes, frame size according to the ADTS "
    343                           "header is %u bytes.",
    344                           inHeader->nFilledLen, aac_frame_length);
    345                     hexdump(adtsHeader, inHeader->nFilledLen);
    346                     signalError = true;
    347                 } else {
    348                     adtsHeaderSize = (protectionAbsent ? 7 : 9);
    349 
    350                     mConfig->pInputBuffer =
    351                         (UChar *)adtsHeader + adtsHeaderSize;
    352 
    353                     mConfig->inputBufferCurrentLength =
    354                         aac_frame_length - adtsHeaderSize;
    355 
    356                     inHeader->nOffset += adtsHeaderSize;
    357                     inHeader->nFilledLen -= adtsHeaderSize;
    358                 }
    359             }
    360 
    361             if (signalError) {
    362                 mSignalledError = true;
    363 
    364                 notify(OMX_EventError, OMX_ErrorStreamCorrupt,
    365                        ERROR_MALFORMED, NULL);
    366 
    367                 return;
    368             }
    369         } else {
    370             mConfig->pInputBuffer = inHeader->pBuffer + inHeader->nOffset;
    371             mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
    372         }
    373 
    374         mConfig->inputBufferMaxLength = 0;
    375         mConfig->inputBufferUsedLength = 0;
    376         mConfig->remainderBits = 0;
    377 
    378         mConfig->pOutputBuffer =
    379             reinterpret_cast<Int16 *>(outHeader->pBuffer + outHeader->nOffset);
    380 
    381         mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
    382         mConfig->repositionFlag = false;
    383 
    384         Int32 prevSamplingRate = mConfig->samplingRate;
    385         Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
    386 
    387         /*
    388          * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
    389          * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
    390          * rate system and the sampling rate in the final output is actually
    391          * doubled compared with the core AAC decoder sampling rate.
    392          *
    393          * Explicit signalling is done by explicitly defining SBR audio object
    394          * type in the bitstream. Implicit signalling is done by embedding
    395          * SBR content in AAC extension payload specific to SBR, and hence
    396          * requires an AAC decoder to perform pre-checks on actual audio frames.
    397          *
    398          * Thus, we could not say for sure whether a stream is
    399          * AAC+/eAAC+ until the first data frame is decoded.
    400          */
    401         if (decoderErr == MP4AUDEC_SUCCESS && mInputBufferCount <= 2) {
    402             ALOGV("audio/extended audio object type: %d + %d",
    403                 mConfig->audioObjectType, mConfig->extendedAudioObjectType);
    404             ALOGV("aac+ upsampling factor: %d desired channels: %d",
    405                 mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels);
    406 
    407             if (mInputBufferCount == 1) {
    408                 mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor;
    409                 // Check on the sampling rate to see whether it is changed.
    410                 if (mConfig->samplingRate != prevSamplingRate) {
    411                     ALOGW("Sample rate was %d Hz, but now is %d Hz",
    412                             prevSamplingRate, mConfig->samplingRate);
    413 
    414                     // We'll hold onto the input buffer and will decode
    415                     // it again once the output port has been reconfigured.
    416 
    417                     // We're going to want to revisit this input buffer, but
    418                     // may have already advanced the offset. Undo that if
    419                     // necessary.
    420                     inHeader->nOffset -= adtsHeaderSize;
    421                     inHeader->nFilledLen += adtsHeaderSize;
    422 
    423                     notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
    424                     mOutputPortSettingsChange = AWAITING_DISABLED;
    425                     return;
    426                 }
    427             } else {  // mInputBufferCount == 2
    428                 if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC ||
    429                     mConfig->extendedAudioObjectType == MP4AUDIO_LTP) {
    430                     if (mUpsamplingFactor == 2) {
    431                         // The stream turns out to be not aacPlus mode anyway
    432                         ALOGW("Disable AAC+/eAAC+ since extended audio object "
    433                              "type is %d",
    434                              mConfig->extendedAudioObjectType);
    435                         mConfig->aacPlusEnabled = 0;
    436                     }
    437                 } else {
    438                     if (mUpsamplingFactor == 1) {
    439                         // aacPlus mode does not buy us anything, but to cause
    440                         // 1. CPU load to increase, and
    441                         // 2. a half speed of decoding
    442                         ALOGW("Disable AAC+/eAAC+ since upsampling factor is 1");
    443                         mConfig->aacPlusEnabled = 0;
    444                     }
    445                 }
    446             }
    447         }
    448 
    449         size_t numOutBytes =
    450             mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
    451 
    452         if (decoderErr == MP4AUDEC_SUCCESS) {
    453             CHECK_LE(mConfig->inputBufferUsedLength, inHeader->nFilledLen);
    454 
    455             inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
    456             inHeader->nOffset += mConfig->inputBufferUsedLength;
    457         } else {
    458             ALOGW("AAC decoder returned error %d, substituting silence",
    459                  decoderErr);
    460 
    461             memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
    462 
    463             // Discard input buffer.
    464             inHeader->nFilledLen = 0;
    465 
    466             // fall through
    467         }
    468 
    469         if (decoderErr == MP4AUDEC_SUCCESS || mNumSamplesOutput > 0) {
    470             // We'll only output data if we successfully decoded it or
    471             // we've previously decoded valid data, in the latter case
    472             // (decode failed) we'll output a silent frame.
    473 
    474             if (mUpsamplingFactor == 2) {
    475                 if (mConfig->desiredChannels == 1) {
    476                     memcpy(&mConfig->pOutputBuffer[1024],
    477                            &mConfig->pOutputBuffer[2048],
    478                            numOutBytes * 2);
    479                 }
    480                 numOutBytes *= 2;
    481             }
    482 
    483             outHeader->nFilledLen = numOutBytes;
    484             outHeader->nFlags = 0;
    485 
    486             outHeader->nTimeStamp =
    487                 mAnchorTimeUs
    488                     + (mNumSamplesOutput * 1000000ll) / mConfig->samplingRate;
    489 
    490             mNumSamplesOutput += mConfig->frameLength * mUpsamplingFactor;
    491 
    492             outInfo->mOwnedByUs = false;
    493             outQueue.erase(outQueue.begin());
    494             outInfo = NULL;
    495             notifyFillBufferDone(outHeader);
    496             outHeader = NULL;
    497         }
    498 
    499         if (inHeader->nFilledLen == 0) {
    500             inInfo->mOwnedByUs = false;
    501             inQueue.erase(inQueue.begin());
    502             inInfo = NULL;
    503             notifyEmptyBufferDone(inHeader);
    504             inHeader = NULL;
    505         }
    506 
    507         if (decoderErr == MP4AUDEC_SUCCESS) {
    508             ++mInputBufferCount;
    509         }
    510     }
    511 }
    512 
    513 void SoftAAC::onPortFlushCompleted(OMX_U32 portIndex) {
    514     if (portIndex == 0) {
    515         // Make sure that the next buffer output does not still
    516         // depend on fragments from the last one decoded.
    517         PVMP4AudioDecoderResetBuffer(mDecoderBuf);
    518     }
    519 }
    520 
    521 void SoftAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
    522     if (portIndex != 1) {
    523         return;
    524     }
    525 
    526     switch (mOutputPortSettingsChange) {
    527         case NONE:
    528             break;
    529 
    530         case AWAITING_DISABLED:
    531         {
    532             CHECK(!enabled);
    533             mOutputPortSettingsChange = AWAITING_ENABLED;
    534             break;
    535         }
    536 
    537         default:
    538         {
    539             CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
    540             CHECK(enabled);
    541             mOutputPortSettingsChange = NONE;
    542             break;
    543         }
    544     }
    545 }
    546 
    547 }  // namespace android
    548 
    549 android::SoftOMXComponent *createSoftOMXComponent(
    550         const char *name, const OMX_CALLBACKTYPE *callbacks,
    551         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    552     return new android::SoftAAC(name, callbacks, appData, component);
    553 }
    554