14b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber/*
24b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Copyright (C) 2011 The Android Open Source Project
34b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
44b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
54b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * you may not use this file except in compliance with the License.
64b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * You may obtain a copy of the License at
74b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
84b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
94b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber *
104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * Unless required by applicable law or agreed to in writing, software
114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * See the License for the specific language governing permissions and
144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber * limitations under the License.
154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber */
164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber//#define LOG_NDEBUG 0
184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#define LOG_TAG "SoftAAC"
194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <utils/Log.h>
204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include "SoftAAC.h"
224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include "pvmp4audiodecoder_api.h"
244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber#include <media/stagefright/foundation/ADebug.h>
264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubernamespace android {
284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubertemplate<class T>
304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huberstatic void InitOMXParams(T *params) {
314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    params->nSize = sizeof(T);
324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    params->nVersion.s.nVersionMajor = 1;
334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    params->nVersion.s.nVersionMinor = 0;
344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    params->nVersion.s.nRevision = 0;
354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    params->nVersion.s.nStep = 0;
364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
384b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberSoftAAC::SoftAAC(
394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        const char *name,
404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        const OMX_CALLBACKTYPE *callbacks,
414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_PTR appData,
424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_COMPONENTTYPE **component)
434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    : SimpleSoftOMXComponent(name, callbacks, appData, component),
444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mConfig(new tPVMP4AudioDecoderExternal),
454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mDecoderBuf(NULL),
464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mInputBufferCount(0),
474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mUpsamplingFactor(2),
484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mAnchorTimeUs(0),
494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mNumSamplesOutput(0),
504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mSignalledError(false),
514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber      mOutputPortSettingsChange(NONE) {
524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    initPorts();
534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
564b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberSoftAAC::~SoftAAC() {
574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    free(mDecoderBuf);
584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mDecoderBuf = NULL;
594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    delete mConfig;
614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mConfig = NULL;
624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SoftAAC::initPorts() {
654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    InitOMXParams(&def);
674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nPortIndex = 0;
694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.eDir = OMX_DirInput;
704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferCountMin = kNumBuffers;
714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferSize = 8192;
734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bEnabled = OMX_TRUE;
744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bPopulated = OMX_FALSE;
754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.eDomain = OMX_PortDomainAudio;
764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bBuffersContiguous = OMX_FALSE;
774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferAlignment = 1;
784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.pNativeRender = NULL;
814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    addPort(def);
854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nPortIndex = 1;
874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.eDir = OMX_DirOutput;
884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferCountMin = kNumBuffers;
894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferCountActual = def.nBufferCountMin;
904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferSize = 8192;
914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bEnabled = OMX_TRUE;
924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bPopulated = OMX_FALSE;
934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.eDomain = OMX_PortDomainAudio;
944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.bBuffersContiguous = OMX_FALSE;
954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.nBufferAlignment = 2;
964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.pNativeRender = NULL;
994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
1004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    addPort(def);
1034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huberstatus_t SoftAAC::initDecoder() {
1064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    memset(mConfig, 0, sizeof(tPVMP4AudioDecoderExternal));
1074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mConfig->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED;
1084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mConfig->aacPlusEnabled = 1;
1094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    // The software decoder doesn't properly support mono output on
1114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    // AACplus files. Always output stereo.
1124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mConfig->desiredChannels = 2;
1134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    UInt32 memRequirements = PVMP4AudioDecoderGetMemRequirements();
1154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    mDecoderBuf = malloc(memRequirements);
1164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    Int err = PVMP4AudioDecoderInitLibrary(mConfig, mDecoderBuf);
1184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (err != MP4AUDEC_SUCCESS) {
1194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        LOGE("Failed to initialize MP4 audio decoder");
1204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return UNKNOWN_ERROR;
1214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
1224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return OK;
1244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1264b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SoftAAC::internalGetParameter(
1274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
1284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (index) {
1294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamAudioAac:
1304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
1314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
1324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
1334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (aacParams->nPortIndex != 0) {
1354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
1364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->nBitRate = 0;
1394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->nAudioBandWidth = 0;
1404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->nAACtools = 0;
1414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->nAACERtools = 0;
1424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
1434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
1444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
1454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (!isConfigured()) {
1474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nChannels = 1;
1484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nSampleRate = 44100;
1494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nFrameLength = 0;
1504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            } else {
1514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nChannels = mConfig->encodedChannels;
1524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nSampleRate = mConfig->samplingRate;
1534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                aacParams->nFrameLength = mConfig->frameLength;
1544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
1574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
1584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamAudioPcm:
1604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
1614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
1624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
1634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (pcmParams->nPortIndex != 1) {
1654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
1664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->eNumData = OMX_NumericalDataSigned;
1694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->eEndian = OMX_EndianBig;
1704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->bInterleaved = OMX_TRUE;
1714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->nBitPerSample = 16;
1724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
1734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
1744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
1754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (!isConfigured()) {
1774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                pcmParams->nChannels = 1;
1784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                pcmParams->nSamplingRate = 44100;
1794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            } else {
1804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                pcmParams->nChannels = mConfig->desiredChannels;
1814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                pcmParams->nSamplingRate = mConfig->samplingRate;
1824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
1834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
1854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
1864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
1884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return SimpleSoftOMXComponent::internalGetParameter(index, params);
1894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
1904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
1914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
1924b3913a3e43d3180b21d77cc2f717b446350354fAndreas HuberOMX_ERRORTYPE SoftAAC::internalSetParameter(
1934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
1944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (index) {
1954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamStandardComponentRole:
1964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
1974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
1984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (const OMX_PARAM_COMPONENTROLETYPE *)params;
1994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (strncmp((const char *)roleParams->cRole,
2014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        "audio_decoder.aac",
2024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        OMX_MAX_STRINGNAME_SIZE - 1)) {
2034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
2044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
2054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
2074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
2084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case OMX_IndexParamAudioAac:
2104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
2114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
2124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
2134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (aacParams->nPortIndex != 0) {
2154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                return OMX_ErrorUndefined;
2164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
2174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return OMX_ErrorNone;
2194b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
2204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
2224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return SimpleSoftOMXComponent::internalSetParameter(index, params);
2234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
2244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
2254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huberbool SoftAAC::isConfigured() const {
2274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return mInputBufferCount > 0;
2284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
2294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SoftAAC::onQueueFilled(OMX_U32 portIndex) {
2314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (mSignalledError || mOutputPortSettingsChange != NONE) {
2324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return;
2334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
2344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
2364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
2374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (portIndex == 0 && mInputBufferCount == 0) {
2394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        ++mInputBufferCount;
2404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        BufferInfo *info = *inQueue.begin();
2424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *header = info->mHeader;
2434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->pInputBuffer = header->pBuffer + header->nOffset;
2454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->inputBufferCurrentLength = header->nFilledLen;
2464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->inputBufferMaxLength = 0;
2474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        Int err = PVMP4AudioDecoderConfig(mConfig, mDecoderBuf);
2494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (err != MP4AUDEC_SUCCESS) {
2504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mSignalledError = true;
2514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notify(OMX_EventError, OMX_ErrorUndefined, err, NULL);
2524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return;
2534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
2544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        inQueue.erase(inQueue.begin());
2564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        info->mOwnedByUs = false;
2574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        notifyEmptyBufferDone(header);
2584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
2604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mOutputPortSettingsChange = AWAITING_DISABLED;
2614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return;
2624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
2634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    while (!inQueue.empty() && !outQueue.empty()) {
2654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        BufferInfo *inInfo = *inQueue.begin();
2664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
2674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        BufferInfo *outInfo = *outQueue.begin();
2694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
2704b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2714b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
2724b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inQueue.erase(inQueue.begin());
2734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inInfo->mOwnedByUs = false;
2744b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notifyEmptyBufferDone(inHeader);
2754b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2764b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            outHeader->nFilledLen = 0;
2774b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
2784b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            outQueue.erase(outQueue.begin());
2804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            outInfo->mOwnedByUs = false;
2814b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notifyFillBufferDone(outHeader);
2824b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            return;
2834b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
2844b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2854b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (inHeader->nOffset == 0) {
2864b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mAnchorTimeUs = inHeader->nTimeStamp;
2874b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mNumSamplesOutput = 0;
2884b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
2894b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2904b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->pInputBuffer = inHeader->pBuffer + inHeader->nOffset;
2914b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
2924b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->inputBufferMaxLength = 0;
2934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->inputBufferUsedLength = 0;
2944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->remainderBits = 0;
2954b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2964b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->pOutputBuffer =
2974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            reinterpret_cast<Int16 *>(outHeader->pBuffer + outHeader->nOffset);
2984b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
2994b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048];
3004b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        mConfig->repositionFlag = false;
3014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3024b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        Int32 prevSamplingRate = mConfig->samplingRate;
3034b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        Int decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf);
3044b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3054b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        /*
3064b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
3074b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
3084b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * rate system and the sampling rate in the final output is actually
3094b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * doubled compared with the core AAC decoder sampling rate.
3104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         *
3114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * Explicit signalling is done by explicitly defining SBR audio object
3124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * type in the bitstream. Implicit signalling is done by embedding
3134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * SBR content in AAC extension payload specific to SBR, and hence
3144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * requires an AAC decoder to perform pre-checks on actual audio frames.
3154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         *
3164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * Thus, we could not say for sure whether a stream is
3174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         * AAC+/eAAC+ until the first data frame is decoded.
3184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber         */
319f77493e6560765882e09f4199e7f295564bede05Andreas Huber        if (decoderErr == MP4AUDEC_SUCCESS && mInputBufferCount <= 2) {
3204b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            LOGV("audio/extended audio object type: %d + %d",
3214b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                mConfig->audioObjectType, mConfig->extendedAudioObjectType);
3224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            LOGV("aac+ upsampling factor: %d desired channels: %d",
3234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels);
3244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            if (mInputBufferCount == 1) {
3264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor;
3274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                // Check on the sampling rate to see whether it is changed.
3284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (mConfig->samplingRate != prevSamplingRate) {
3294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    LOGW("Sample rate was %d Hz, but now is %d Hz",
3304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                            prevSamplingRate, mConfig->samplingRate);
3314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    // We'll hold onto the input buffer and will decode
3334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    // it again once the output port has been reconfigured.
3344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
3364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    mOutputPortSettingsChange = AWAITING_DISABLED;
3374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    return;
3384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
3394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            } else {  // mInputBufferCount == 2
3404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC ||
3414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    mConfig->extendedAudioObjectType == MP4AUDIO_LTP) {
3424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    if (mUpsamplingFactor == 2) {
3434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        // The stream turns out to be not aacPlus mode anyway
3444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        LOGW("Disable AAC+/eAAC+ since extended audio object "
3454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                             "type is %d",
3464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                             mConfig->extendedAudioObjectType);
3474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        mConfig->aacPlusEnabled = 0;
3484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    }
3494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                } else {
3504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    if (mUpsamplingFactor == 1) {
3514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        // aacPlus mode does not buy us anything, but to cause
3524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        // 1. CPU load to increase, and
3534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        // 2. a half speed of decoding
3544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        LOGW("Disable AAC+/eAAC+ since upsampling factor is 1");
3554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                        mConfig->aacPlusEnabled = 0;
3564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                    }
3574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber                }
3584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
3594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        size_t numOutBytes =
3624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels;
3634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (decoderErr == MP4AUDEC_SUCCESS) {
3654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_LE(mConfig->inputBufferUsedLength, inHeader->nFilledLen);
3664b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
3674b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
3684b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inHeader->nOffset += mConfig->inputBufferUsedLength;
3694b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        } else {
370dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber            LOGW("AAC decoder returned error %d, substituting silence",
371dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber                 decoderErr);
372dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber
3734b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
374dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber
375dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber            // Discard input buffer.
376dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber            inHeader->nFilledLen = 0;
377dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber
378dabf22181d912de9f32b51b023ac4c0ee6ec7a17Andreas Huber            // fall through
3794b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
3804b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
381887b7295dae903b7859026f0c14e642347aa934aAndreas Huber        if (decoderErr == MP4AUDEC_SUCCESS || mNumSamplesOutput > 0) {
382887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            // We'll only output data if we successfully decoded it or
383887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            // we've previously decoded valid data, in the latter case
384887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            // (decode failed) we'll output a silent frame.
385887b7295dae903b7859026f0c14e642347aa934aAndreas Huber
386887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            if (mUpsamplingFactor == 2) {
387887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                if (mConfig->desiredChannels == 1) {
388887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                    memcpy(&mConfig->pOutputBuffer[1024],
389887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                           &mConfig->pOutputBuffer[2048],
390887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                           numOutBytes * 2);
391887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                }
392887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                numOutBytes *= 2;
3934b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            }
3944b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
395887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outHeader->nFilledLen = numOutBytes;
396887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outHeader->nFlags = 0;
3974b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
398887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outHeader->nTimeStamp =
399887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                mAnchorTimeUs
400887b7295dae903b7859026f0c14e642347aa934aAndreas Huber                    + (mNumSamplesOutput * 1000000ll) / mConfig->samplingRate;
4014b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
402887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            mNumSamplesOutput += mConfig->frameLength * mUpsamplingFactor;
403887b7295dae903b7859026f0c14e642347aa934aAndreas Huber
404887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outInfo->mOwnedByUs = false;
405887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outQueue.erase(outQueue.begin());
406887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outInfo = NULL;
407887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            notifyFillBufferDone(outHeader);
408887b7295dae903b7859026f0c14e642347aa934aAndreas Huber            outHeader = NULL;
409887b7295dae903b7859026f0c14e642347aa934aAndreas Huber        }
4104b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4114b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        if (inHeader->nFilledLen == 0) {
4124b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inInfo->mOwnedByUs = false;
4134b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inQueue.erase(inQueue.begin());
4144b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inInfo = NULL;
4154b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            notifyEmptyBufferDone(inHeader);
4164b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            inHeader = NULL;
4174b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4184b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
419f77493e6560765882e09f4199e7f295564bede05Andreas Huber        if (decoderErr == MP4AUDEC_SUCCESS) {
420f77493e6560765882e09f4199e7f295564bede05Andreas Huber            ++mInputBufferCount;
421f77493e6560765882e09f4199e7f295564bede05Andreas Huber        }
4224b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4234b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4244b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4254b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SoftAAC::onPortFlushCompleted(OMX_U32 portIndex) {
4264b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (portIndex == 0) {
4274b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        // Make sure that the next buffer output does not still
4284b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        // depend on fragments from the last one decoded.
4294b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        PVMP4AudioDecoderResetBuffer(mDecoderBuf);
4304b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4314b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4324b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4334b3913a3e43d3180b21d77cc2f717b446350354fAndreas Hubervoid SoftAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
4344b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    if (portIndex != 1) {
4354b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        return;
4364b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4374b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4384b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    switch (mOutputPortSettingsChange) {
4394b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case NONE:
4404b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4414b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4424b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        case AWAITING_DISABLED:
4434b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
4444b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(!enabled);
4454b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mOutputPortSettingsChange = AWAITING_ENABLED;
4464b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4474b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4484b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4494b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        default:
4504b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        {
4514b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
4524b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            CHECK(enabled);
4534b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            mOutputPortSettingsChange = NONE;
4544b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber            break;
4554b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        }
4564b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    }
4574b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
4584b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4594b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}  // namespace android
4604b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber
4614b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
4624b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
4634b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
4644b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber    return new android::SoftAAC(name, callbacks, appData, component);
4654b3913a3e43d3180b21d77cc2f717b446350354fAndreas Huber}
466