SoftAAC2.cpp revision 6b7b8227cc8753fde4094ca8af2d381c2740826f
1b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke/*
2b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * Copyright (C) 2012 The Android Open Source Project
3b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke *
4b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * Licensed under the Apache License, Version 2.0 (the "License");
5b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * you may not use this file except in compliance with the License.
6b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * You may obtain a copy of the License at
7b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke *
8b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke *      http://www.apache.org/licenses/LICENSE-2.0
9b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke *
10b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * Unless required by applicable law or agreed to in writing, software
11b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * distributed under the License is distributed on an "AS IS" BASIS,
12b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * See the License for the specific language governing permissions and
14b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke * limitations under the License.
15b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke */
16b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
17b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#define LOG_TAG "SoftAAC2"
18b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include <utils/Log.h>
19b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
20b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include "SoftAAC2.h"
21b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
22b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include <media/stagefright/foundation/ADebug.h>
23b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include <media/stagefright/foundation/hexdump.h>
24b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
25b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#define FILEREAD_MAX_LAYERS 2
26b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
27b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkenamespace android {
28b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
29b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burketemplate<class T>
30b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkestatic void InitOMXParams(T *params) {
31b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nSize = sizeof(T);
32b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nVersionMajor = 1;
33b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nVersionMinor = 0;
34b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nRevision = 0;
35b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nStep = 0;
36b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
37b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
38b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeSoftAAC2::SoftAAC2(
39b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const char *name,
40b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const OMX_CALLBACKTYPE *callbacks,
41b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_PTR appData,
42b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_COMPONENTTYPE **component)
43b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    : SimpleSoftOMXComponent(name, callbacks, appData, component),
44b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mAACDecoder(NULL),
45b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mStreamInfo(NULL),
46b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mIsADTS(false),
47b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mInputBufferCount(0),
48b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mSignalledError(false),
49095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke      mInputDiscontinuity(false),
50b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mAnchorTimeUs(0),
51b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mNumSamplesOutput(0),
52b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mOutputPortSettingsChange(NONE) {
53b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    initPorts();
54b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    CHECK_EQ(initDecoder(), (status_t)OK);
55b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
56b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
57b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeSoftAAC2::~SoftAAC2() {
58b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    aacDecoder_Close(mAACDecoder);
59b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
60b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
61b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::initPorts() {
62b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    OMX_PARAM_PORTDEFINITIONTYPE def;
63b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    InitOMXParams(&def);
64b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
65b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nPortIndex = 0;
66b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDir = OMX_DirInput;
67b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountMin = kNumBuffers;
68b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountActual = def.nBufferCountMin;
69b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferSize = 8192;
70b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bEnabled = OMX_TRUE;
71b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bPopulated = OMX_FALSE;
72b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDomain = OMX_PortDomainAudio;
73b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bBuffersContiguous = OMX_FALSE;
74b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferAlignment = 1;
75b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
76b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
77b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.pNativeRender = NULL;
78b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
79b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
80b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
81b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    addPort(def);
82b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
83b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nPortIndex = 1;
84b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDir = OMX_DirOutput;
85b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountMin = kNumBuffers;
86b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountActual = def.nBufferCountMin;
87095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke    def.nBufferSize = 8192 * 2;
88b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bEnabled = OMX_TRUE;
89b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bPopulated = OMX_FALSE;
90b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDomain = OMX_PortDomainAudio;
91b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bBuffersContiguous = OMX_FALSE;
92b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferAlignment = 2;
93b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
94b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
95b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.pNativeRender = NULL;
96b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
97b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
98b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
99b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    addPort(def);
100b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
101b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
102b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkestatus_t SoftAAC2::initDecoder() {
103b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    status_t status = UNKNOWN_ERROR;
104b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    mAACDecoder = aacDecoder_Open(TT_MP4_RAW, /* num layers */ 1);
105b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (mAACDecoder != NULL) {
106b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
107b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (mStreamInfo != NULL) {
108b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            status = OK;
109b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
110b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
111b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return status;
112b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
113b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
114b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeOMX_ERRORTYPE SoftAAC2::internalGetParameter(
115b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_INDEXTYPE index, OMX_PTR params) {
116b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (index) {
117b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioAac:
118b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
119b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
120b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
121b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
122b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->nPortIndex != 0) {
123b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
124b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
125b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
126b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nBitRate = 0;
127b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAudioBandWidth = 0;
128b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAACtools = 0;
129b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAACERtools = 0;
130b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
131b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
132b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eAACStreamFormat =
133b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS
134b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    ? OMX_AUDIO_AACStreamFormatMP4ADTS
135b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    : OMX_AUDIO_AACStreamFormatMP4FF;
136b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
137b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
138b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
139b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (!isConfigured()) {
140b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nChannels = 1;
141b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nSampleRate = 44100;
142b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nFrameLength = 0;
143b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
144b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nChannels = mStreamInfo->channelConfig;
145b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nSampleRate = mStreamInfo->aacSampleRate;
146b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nFrameLength = mStreamInfo->aacSamplesPerFrame;
147b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
148b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
149b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
150b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
151b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
152b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioPcm:
153b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
154b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
155b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
156b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
157b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (pcmParams->nPortIndex != 1) {
158b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
159b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
160b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
161b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eNumData = OMX_NumericalDataSigned;
162b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eEndian = OMX_EndianBig;
163b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->bInterleaved = OMX_TRUE;
164b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->nBitPerSample = 16;
165b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
166b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
167b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
168095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
169095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
170095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
171095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
172b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
173b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (!isConfigured()) {
174b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nChannels = 1;
175b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nSamplingRate = 44100;
176b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
177b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nChannels = mStreamInfo->channelConfig;
178b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nSamplingRate = mStreamInfo->sampleRate;
179b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
180b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
181b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
182b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
183b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
184b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
185b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return SimpleSoftOMXComponent::internalGetParameter(index, params);
186b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
187b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
188b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
189b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeOMX_ERRORTYPE SoftAAC2::internalSetParameter(
190b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_INDEXTYPE index, const OMX_PTR params) {
191b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (index) {
192b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamStandardComponentRole:
193b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
194b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
195b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (const OMX_PARAM_COMPONENTROLETYPE *)params;
196b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
197b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (strncmp((const char *)roleParams->cRole,
198b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        "audio_decoder.aac",
199b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        OMX_MAX_STRINGNAME_SIZE - 1)) {
200b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
201b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
202b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
203b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
204b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
205b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
206b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioAac:
207b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
208b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
209b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
210b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
211b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->nPortIndex != 0) {
212b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
213b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
214b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
215b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
216b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS = false;
217b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else if (aacParams->eAACStreamFormat
218b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        == OMX_AUDIO_AACStreamFormatMP4ADTS) {
219b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS = true;
220b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
221b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
222b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
223b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
224b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
225b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
226b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
227b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioPcm:
228b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
229b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
230b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
231b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
232b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (pcmParams->nPortIndex != 1) {
233b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
234b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
235b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
236b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
237b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
238b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
239b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
240b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return SimpleSoftOMXComponent::internalSetParameter(index, params);
241b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
242b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
243b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
244b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkebool SoftAAC2::isConfigured() const {
245b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return mInputBufferCount > 0;
246b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
247b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
248b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
249b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (mSignalledError || mOutputPortSettingsChange != NONE) {
250b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
251b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
252b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
253b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
254b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
255b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
256b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    AAC_DECODER_ERROR decoderErr;
257b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
258b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    List<BufferInfo *> &inQueue = getPortQueue(0);
259b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    List<BufferInfo *> &outQueue = getPortQueue(1);
260b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
261b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex == 0 && mInputBufferCount == 0) {
262b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        ++mInputBufferCount;
263b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *info = *inQueue.begin();
264b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *header = info->mHeader;
265b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
266b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inBuffer[0] = header->pBuffer + header->nOffset;
267b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inBufferLength[0] = header->nFilledLen;
268b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
269b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        AAC_DECODER_ERROR decoderErr =
270b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacDecoder_ConfigRaw(mAACDecoder,
271b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                 inBuffer,
272b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                 inBufferLength);
273b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
274b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr != AAC_DEC_OK) {
275b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mSignalledError = true;
276b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
277b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return;
278b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
279b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
280b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inQueue.erase(inQueue.begin());
281b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        info->mOwnedByUs = false;
282b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        notifyEmptyBufferDone(header);
283b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
284b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
285b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        mOutputPortSettingsChange = AWAITING_DISABLED;
286b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
287b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
288b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
289b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    while (!inQueue.empty() && !outQueue.empty()) {
290b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *inInfo = *inQueue.begin();
291b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
292b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
293b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *outInfo = *outQueue.begin();
294b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
295b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
296b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
297b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inQueue.erase(inQueue.begin());
298b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo->mOwnedByUs = false;
299b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyEmptyBufferDone(inHeader);
300b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
301b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFilledLen = 0;
302b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
303b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
304b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outQueue.erase(outQueue.begin());
305b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo->mOwnedByUs = false;
306b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyFillBufferDone(outHeader);
307b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return;
308b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
309b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
310b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nOffset == 0) {
311b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mAnchorTimeUs = inHeader->nTimeStamp;
312b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mNumSamplesOutput = 0;
313b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
314b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3156b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber        size_t adtsHeaderSize = 0;
316b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (mIsADTS) {
317b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // skip 30 bits, aac_frame_length follows.
318b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
319b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
320b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
321b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
322b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK_GE(inHeader->nFilledLen, 7);
323b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
324b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            bool protectionAbsent = (adtsHeader[1] & 1);
325b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
326b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            unsigned aac_frame_length =
327b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                ((adtsHeader[3] & 3) << 11)
328b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                | (adtsHeader[4] << 3)
329b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                | (adtsHeader[5] >> 5);
330b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
331b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK_GE(inHeader->nFilledLen, aac_frame_length);
332b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3336b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber            adtsHeaderSize = (protectionAbsent ? 7 : 9);
334b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3356b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber            inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
3366b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber            inBufferLength[0] = aac_frame_length - adtsHeaderSize;
337b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3386b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber            inHeader->nOffset += adtsHeaderSize;
3396b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber            inHeader->nFilledLen -= adtsHeaderSize;
340b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        } else {
341b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
342b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inBufferLength[0] = inHeader->nFilledLen;
343b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
344b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
345b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
346b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // Fill and decode
347b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
348b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        bytesValid[0] = inBufferLength[0];
349b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
350095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke        int flags = mInputDiscontinuity ? AACDEC_INTR : 0;
351b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        int prevSampleRate = mStreamInfo->sampleRate;
352b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        decoderErr = aacDecoder_Fill(mAACDecoder,
353095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke                                     inBuffer,
354095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke                                     inBufferLength,
355095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke                                     bytesValid);
3566b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber
357b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
358b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                            outBuffer,
359b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                            outHeader->nAllocLen,
360095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke                                            flags);
3616b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber
362095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke        mInputDiscontinuity = false;
363b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
364b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        /*
365b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
366b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
367b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * rate system and the sampling rate in the final output is actually
368b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * doubled compared with the core AAC decoder sampling rate.
369b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         *
370b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * Explicit signalling is done by explicitly defining SBR audio object
371b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * type in the bitstream. Implicit signalling is done by embedding
372b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * SBR content in AAC extension payload specific to SBR, and hence
373b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * requires an AAC decoder to perform pre-checks on actual audio frames.
374b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         *
375b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * Thus, we could not say for sure whether a stream is
376b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         * AAC+/eAAC+ until the first data frame is decoded.
377b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke         */
378b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK && mInputBufferCount <= 2) {
379b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (mStreamInfo->sampleRate != prevSampleRate) {
3806b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber                // We're going to want to revisit this input buffer, but
3816b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber                // may have already advanced the offset. Undo that if
3826b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber                // necessary.
3836b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber                inHeader->nOffset -= adtsHeaderSize;
3846b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber                inHeader->nFilledLen += adtsHeaderSize;
3856b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber
386b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
387b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mOutputPortSettingsChange = AWAITING_DISABLED;
388b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return;
389b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
390b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
391b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
392b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        size_t numOutBytes =
393b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
394b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
395b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK) {
396b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
397b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nFilledLen -= inBufferUsedLength;
398b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nOffset += inBufferUsedLength;
399b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        } else {
400b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            ALOGW("AAC decoder returned error %d, substituting silence",
401b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                  decoderErr);
402b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
403b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
404b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
405b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // Discard input buffer.
406b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nFilledLen = 0;
407b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
408b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // fall through
409b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
410b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
411b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
412b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // We'll only output data if we successfully decoded it or
413b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // we've previously decoded valid data, in the latter case
414b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // (decode failed) we'll output a silent frame.
415b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFilledLen = numOutBytes;
416b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFlags = 0;
417b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
418b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nTimeStamp =
419b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mAnchorTimeUs
420b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
421b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
422b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mNumSamplesOutput += mStreamInfo->frameSize;
423b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
424b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo->mOwnedByUs = false;
425b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outQueue.erase(outQueue.begin());
426b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo = NULL;
427b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyFillBufferDone(outHeader);
428b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader = NULL;
429b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
430b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
431b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nFilledLen == 0) {
432b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo->mOwnedByUs = false;
433b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inQueue.erase(inQueue.begin());
434b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo = NULL;
435b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyEmptyBufferDone(inHeader);
436b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader = NULL;
437b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
438b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
439b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK) {
440b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            ++mInputBufferCount;
441b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
442b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
443b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
444b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
445b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
446b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex == 0) {
447b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // Make sure that the next buffer output does not still
448b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // depend on fragments from the last one decoded.
449095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke        mInputDiscontinuity = true;
450b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
451b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
452b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
453b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
454b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex != 1) {
455b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
456b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
457b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
458b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (mOutputPortSettingsChange) {
459b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case NONE:
460b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
461b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
462b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case AWAITING_DISABLED:
463b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
464b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK(!enabled);
465b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mOutputPortSettingsChange = AWAITING_ENABLED;
466b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
467b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
468b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
469b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
470b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
471b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
472b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK(enabled);
473b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mOutputPortSettingsChange = NONE;
474b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
475b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
476b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
477b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
478b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
479b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}  // namespace android
480b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
481b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkeandroid::SoftOMXComponent *createSoftOMXComponent(
482b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const char *name, const OMX_CALLBACKTYPE *callbacks,
483b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
484b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return new android::SoftAAC2(name, callbacks, appData, component);
485b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
486