SoftAAC2.cpp revision 1adacd921319ec52fac1a4596ab6eaf8689e6a7d
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
221adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke#include <cutils/properties.h>
23b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include <media/stagefright/foundation/ADebug.h>
24b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#include <media/stagefright/foundation/hexdump.h>
258370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber#include <media/stagefright/MediaErrors.h>
26b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
27b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke#define FILEREAD_MAX_LAYERS 2
28b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
29b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkenamespace android {
30b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
31b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burketemplate<class T>
32b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkestatic void InitOMXParams(T *params) {
33b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nSize = sizeof(T);
34b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nVersionMajor = 1;
35b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nVersionMinor = 0;
36b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nRevision = 0;
37b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    params->nVersion.s.nStep = 0;
38b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
39b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
40b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeSoftAAC2::SoftAAC2(
41b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const char *name,
42b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const OMX_CALLBACKTYPE *callbacks,
43b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_PTR appData,
44b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_COMPONENTTYPE **component)
45b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    : SimpleSoftOMXComponent(name, callbacks, appData, component),
46b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mAACDecoder(NULL),
47b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mStreamInfo(NULL),
48b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mIsADTS(false),
49b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mInputBufferCount(0),
50b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mSignalledError(false),
51b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mAnchorTimeUs(0),
52b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mNumSamplesOutput(0),
53b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke      mOutputPortSettingsChange(NONE) {
54b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    initPorts();
55b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    CHECK_EQ(initDecoder(), (status_t)OK);
56b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
57b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
58b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeSoftAAC2::~SoftAAC2() {
59b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    aacDecoder_Close(mAACDecoder);
60b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
61b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
62b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::initPorts() {
63b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    OMX_PARAM_PORTDEFINITIONTYPE def;
64b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    InitOMXParams(&def);
65b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
66b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nPortIndex = 0;
67b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDir = OMX_DirInput;
68eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    def.nBufferCountMin = kNumInputBuffers;
69b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountActual = def.nBufferCountMin;
70b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferSize = 8192;
71b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bEnabled = OMX_TRUE;
72b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bPopulated = OMX_FALSE;
73b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDomain = OMX_PortDomainAudio;
74b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bBuffersContiguous = OMX_FALSE;
75b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferAlignment = 1;
76b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
77b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
78b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.pNativeRender = NULL;
79b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
80b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
81b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
82b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    addPort(def);
83b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
84b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nPortIndex = 1;
85b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDir = OMX_DirOutput;
86eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    def.nBufferCountMin = kNumOutputBuffers;
87b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferCountActual = def.nBufferCountMin;
88095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke    def.nBufferSize = 8192 * 2;
89b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bEnabled = OMX_TRUE;
90b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bPopulated = OMX_FALSE;
91b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.eDomain = OMX_PortDomainAudio;
92b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.bBuffersContiguous = OMX_FALSE;
93b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.nBufferAlignment = 2;
94b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
95b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
96b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.pNativeRender = NULL;
97b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
98b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
99b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
100b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    addPort(def);
101b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
102b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
103b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkestatus_t SoftAAC2::initDecoder() {
104b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    status_t status = UNKNOWN_ERROR;
105e672a0eea2cdc2ed43e002f0583902f20705de57Andreas Huber    mAACDecoder = aacDecoder_Open(TT_MP4_ADIF, /* num layers */ 1);
106b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (mAACDecoder != NULL) {
107b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        mStreamInfo = aacDecoder_GetStreamInfo(mAACDecoder);
108b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (mStreamInfo != NULL) {
109b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            status = OK;
110b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
111b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
11241914becfd019c619783d875c61ef71db0e67400Marco Nelissen    mIsFirst = true;
113b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return status;
114b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
115b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
116b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeOMX_ERRORTYPE SoftAAC2::internalGetParameter(
117b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_INDEXTYPE index, OMX_PTR params) {
118b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (index) {
119b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioAac:
120b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
121b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
122b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
123b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
124b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->nPortIndex != 0) {
125b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
126b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
127b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
128b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nBitRate = 0;
129b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAudioBandWidth = 0;
130b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAACtools = 0;
131b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->nAACERtools = 0;
132b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
133b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
134b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eAACStreamFormat =
135b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS
136b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    ? OMX_AUDIO_AACStreamFormatMP4ADTS
137b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    : OMX_AUDIO_AACStreamFormatMP4FF;
138b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
139b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
140b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
141bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            if (!isConfigured()) {
142b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nChannels = 1;
143b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nSampleRate = 44100;
144b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                aacParams->nFrameLength = 0;
145b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
146f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                aacParams->nChannels = mStreamInfo->numChannels;
147f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                aacParams->nSampleRate = mStreamInfo->sampleRate;
148f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                aacParams->nFrameLength = mStreamInfo->frameSize;
149b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
150b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
151b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
152b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
153b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
154b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioPcm:
155b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
156b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
157b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
158b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
159b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (pcmParams->nPortIndex != 1) {
160b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
161b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
162b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
163b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eNumData = OMX_NumericalDataSigned;
164b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eEndian = OMX_EndianBig;
165b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->bInterleaved = OMX_TRUE;
166b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->nBitPerSample = 16;
167b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
168b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
169b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
170095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
171095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
172095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
173095c2da8d6c2058b02142c940f6e6346d6581780Dave Burke            pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
174b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
175bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            if (!isConfigured()) {
176b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nChannels = 1;
177b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nSamplingRate = 44100;
178b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
179f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                pcmParams->nChannels = mStreamInfo->numChannels;
180b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                pcmParams->nSamplingRate = mStreamInfo->sampleRate;
181b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
182b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
183b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
184b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
185b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
186b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
187b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return SimpleSoftOMXComponent::internalGetParameter(index, params);
188b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
189b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
190b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
191b7ddcc9460f488f0b032aeb27b52a423318a97eaDave BurkeOMX_ERRORTYPE SoftAAC2::internalSetParameter(
192b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_INDEXTYPE index, const OMX_PTR params) {
193b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (index) {
194b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamStandardComponentRole:
195b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
196b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
197b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (const OMX_PARAM_COMPONENTROLETYPE *)params;
198b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
199b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (strncmp((const char *)roleParams->cRole,
200b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        "audio_decoder.aac",
201b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        OMX_MAX_STRINGNAME_SIZE - 1)) {
202b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
203b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
204b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
205b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
206b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
207b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
208b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioAac:
209b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
210b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
211b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
212b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
213b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->nPortIndex != 0) {
214b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
215b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
216b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
217b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
218b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS = false;
219b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else if (aacParams->eAACStreamFormat
220b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                        == OMX_AUDIO_AACStreamFormatMP4ADTS) {
221b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mIsADTS = true;
222b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            } else {
223b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
224b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
225b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
226b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
227b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
228b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
229b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case OMX_IndexParamAudioPcm:
230b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
231b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
232b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
233b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
234b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            if (pcmParams->nPortIndex != 1) {
235b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                return OMX_ErrorUndefined;
236b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            }
237b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
238b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return OMX_ErrorNone;
239b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
240b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
241b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
242b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return SimpleSoftOMXComponent::internalSetParameter(index, params);
243b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
244b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
245b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
246b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkebool SoftAAC2::isConfigured() const {
247b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return mInputBufferCount > 0;
248b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
249b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
2501adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burkevoid SoftAAC2::maybeConfigureDownmix() const {
2511adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke    if (mStreamInfo->numChannels > 2) {
2521adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke        char value[PROPERTY_VALUE_MAX];
2531adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke        if (!(property_get("media.aac_51_output_enabled", value, NULL) &&
2541adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke                (!strcmp(value, "1") || !strcasecmp(value, "true")))) {
2551adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke            ALOGI("Downmixing multichannel AAC to stereo");
2561adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke            aacDecoder_SetParam(mAACDecoder, AAC_PCM_OUTPUT_CHANNELS, 2);
2571adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke            mStreamInfo->numChannels = 2;
2581adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke        }
2591adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke    }
2601adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke}
2611adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke
262b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
263b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (mSignalledError || mOutputPortSettingsChange != NONE) {
264b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
265b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
266b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
267b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UCHAR* inBuffer[FILEREAD_MAX_LAYERS];
268b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UINT inBufferLength[FILEREAD_MAX_LAYERS] = {0};
269b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    UINT bytesValid[FILEREAD_MAX_LAYERS] = {0};
270b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
271b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    List<BufferInfo *> &inQueue = getPortQueue(0);
272b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    List<BufferInfo *> &outQueue = getPortQueue(1);
273b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
274b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex == 0 && mInputBufferCount == 0) {
275b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        ++mInputBufferCount;
276b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *info = *inQueue.begin();
277b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *header = info->mHeader;
278b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
279b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inBuffer[0] = header->pBuffer + header->nOffset;
280b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inBufferLength[0] = header->nFilledLen;
281b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
282b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        AAC_DECODER_ERROR decoderErr =
283b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            aacDecoder_ConfigRaw(mAACDecoder,
284b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                 inBuffer,
285b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                                 inBufferLength);
286b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
287b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr != AAC_DEC_OK) {
288b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mSignalledError = true;
289b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
290b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return;
291b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
292b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        inQueue.erase(inQueue.begin());
293b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        info->mOwnedByUs = false;
294b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        notifyEmptyBufferDone(header);
295b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
2961adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke        maybeConfigureDownmix();
2971adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke        ALOGI("Initially configuring decoder: %d Hz, %d channels",
298bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke              mStreamInfo->sampleRate,
299bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke              mStreamInfo->numChannels);
300b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
301b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        mOutputPortSettingsChange = AWAITING_DISABLED;
302b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
303b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
304b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
305b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    while (!inQueue.empty() && !outQueue.empty()) {
306b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *inInfo = *inQueue.begin();
307b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
308b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
309b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        BufferInfo *outInfo = *outQueue.begin();
310b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
311b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
312b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
313b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inQueue.erase(inQueue.begin());
314b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo->mOwnedByUs = false;
315b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyEmptyBufferDone(inHeader);
316b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
31741914becfd019c619783d875c61ef71db0e67400Marco Nelissen            // flush out the decoder's delayed data by calling DecodeFrame one more time, with
31841914becfd019c619783d875c61ef71db0e67400Marco Nelissen            // the AACDEC_FLUSH flag set
31941914becfd019c619783d875c61ef71db0e67400Marco Nelissen            INT_PCM *outBuffer =
32041914becfd019c619783d875c61ef71db0e67400Marco Nelissen                    reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
321f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            AAC_DECODER_ERROR decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
322f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                                                                  outBuffer,
323f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                                                                  outHeader->nAllocLen,
324f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                                                                  AACDEC_FLUSH);
325f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            if (decoderErr != AAC_DEC_OK) {
326f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                mSignalledError = true;
327f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
328f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                return;
329f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            }
330f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
33141914becfd019c619783d875c61ef71db0e67400Marco Nelissen            outHeader->nFilledLen =
33241914becfd019c619783d875c61ef71db0e67400Marco Nelissen                    mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
333b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
334b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
335b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outQueue.erase(outQueue.begin());
336b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo->mOwnedByUs = false;
337b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyFillBufferDone(outHeader);
338b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            return;
339b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
340b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
341b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nOffset == 0) {
342b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mAnchorTimeUs = inHeader->nTimeStamp;
343b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mNumSamplesOutput = 0;
344b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
345b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3466b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber        size_t adtsHeaderSize = 0;
347b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (mIsADTS) {
348b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // skip 30 bits, aac_frame_length follows.
349b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
350b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
351b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
352b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
3538370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber            bool signalError = false;
3548370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber            if (inHeader->nFilledLen < 7) {
3558370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                ALOGE("Audio data too short to contain even the ADTS header. "
3568370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                      "Got %ld bytes.", inHeader->nFilledLen);
3578370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                hexdump(adtsHeader, inHeader->nFilledLen);
3588370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                signalError = true;
3598370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber            } else {
3608370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                bool protectionAbsent = (adtsHeader[1] & 1);
3618370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
3628370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                unsigned aac_frame_length =
3638370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    ((adtsHeader[3] & 3) << 11)
3648370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    | (adtsHeader[4] << 3)
3658370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    | (adtsHeader[5] >> 5);
3668370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
3678370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                if (inHeader->nFilledLen < aac_frame_length) {
3688370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    ALOGE("Not enough audio data for the complete frame. "
3698370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                          "Got %ld bytes, frame size according to the ADTS "
3708370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                          "header is %u bytes.",
3718370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                          inHeader->nFilledLen, aac_frame_length);
3728370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    hexdump(adtsHeader, inHeader->nFilledLen);
3738370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    signalError = true;
3748370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                } else {
3758370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    adtsHeaderSize = (protectionAbsent ? 7 : 9);
3768370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
3778370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
3788370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    inBufferLength[0] = aac_frame_length - adtsHeaderSize;
3798370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
3808370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    inHeader->nOffset += adtsHeaderSize;
3818370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                    inHeader->nFilledLen -= adtsHeaderSize;
3828370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber                }
383e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber            }
3848370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
385e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber            if (signalError) {
386e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                mSignalledError = true;
3878370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
388e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                notify(OMX_EventError,
389e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                       OMX_ErrorStreamCorrupt,
390e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                       ERROR_MALFORMED,
391e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                       NULL);
3928370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber
393e35ac2860e99d809a2ccca59bd4eb2f8c02d15adAndreas Huber                return;
3948370c7ad4136ad7e0787d5a91ccfa3d63cfbe5ccAndreas Huber            }
395b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        } else {
396b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
397b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inBufferLength[0] = inHeader->nFilledLen;
398b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
399b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
400b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // Fill and decode
401b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
402b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        bytesValid[0] = inBufferLength[0];
403b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
404b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        int prevSampleRate = mStreamInfo->sampleRate;
405f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        int prevNumChannels = mStreamInfo->numChannels;
4066b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber
407f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
408f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
409f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            aacDecoder_Fill(mAACDecoder,
410f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                            inBuffer,
411f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                            inBufferLength,
412f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                            bytesValid);
4136b7b8227cc8753fde4094ca8af2d381c2740826fAndreas Huber
414f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
415f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                                                outBuffer,
416f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                                                outHeader->nAllocLen,
4173748b71a7fe73b0365a93f1fd28ced14219f85e5Dave Burke                                                0 /* flags */);
418f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
419f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        }
4203748b71a7fe73b0365a93f1fd28ced14219f85e5Dave Burke
421bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke        /*
422bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
423bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
424bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * rate system and the sampling rate in the final output is actually
425bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * doubled compared with the core AAC decoder sampling rate.
426bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         *
427bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * Explicit signalling is done by explicitly defining SBR audio object
428bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * type in the bitstream. Implicit signalling is done by embedding
429bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * SBR content in AAC extension payload specific to SBR, and hence
430bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * requires an AAC decoder to perform pre-checks on actual audio frames.
431bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         *
432bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * Thus, we could not say for sure whether a stream is
433bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         * AAC+/eAAC+ until the first data frame is decoded.
434bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke         */
435bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke        if (mInputBufferCount <= 2) {
436bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            if (mStreamInfo->sampleRate != prevSampleRate ||
437bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                mStreamInfo->numChannels != prevNumChannels) {
4381adacd921319ec52fac1a4596ab6eaf8689e6a7dDave Burke                maybeConfigureDownmix();
439bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                ALOGI("Reconfiguring decoder: %d Hz, %d channels",
440bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                      mStreamInfo->sampleRate,
441bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                      mStreamInfo->numChannels);
442bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke
443bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                // We're going to want to revisit this input buffer, but
444bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                // may have already advanced the offset. Undo that if
445bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                // necessary.
446bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                inHeader->nOffset -= adtsHeaderSize;
447bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                inHeader->nFilledLen += adtsHeaderSize;
448bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke
449bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
450bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                mOutputPortSettingsChange = AWAITING_DISABLED;
451bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke                return;
452bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            }
453bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke        } else if (!mStreamInfo->sampleRate || !mStreamInfo->numChannels) {
454bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            ALOGW("Invalid AAC stream");
455bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            mSignalledError = true;
456bf2461ecc71c0aacf8c03fcdaf0dc46bc8285c7fDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL);
4573748b71a7fe73b0365a93f1fd28ced14219f85e5Dave Burke            return;
458b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
459b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
460b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        size_t numOutBytes =
461b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
462b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
463b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK) {
464b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
465b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nFilledLen -= inBufferUsedLength;
466b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nOffset += inBufferUsedLength;
467b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        } else {
468b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            ALOGW("AAC decoder returned error %d, substituting silence",
469b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                  decoderErr);
470b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
471b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
472b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
473b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // Discard input buffer.
474b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader->nFilledLen = 0;
475b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
476e672a0eea2cdc2ed43e002f0583902f20705de57Andreas Huber            aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
477e672a0eea2cdc2ed43e002f0583902f20705de57Andreas Huber
478b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // fall through
479b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
480b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
481b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK || mNumSamplesOutput > 0) {
482b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // We'll only output data if we successfully decoded it or
483b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // we've previously decoded valid data, in the latter case
484b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            // (decode failed) we'll output a silent frame.
48541914becfd019c619783d875c61ef71db0e67400Marco Nelissen            if (mIsFirst) {
48641914becfd019c619783d875c61ef71db0e67400Marco Nelissen                mIsFirst = false;
48741914becfd019c619783d875c61ef71db0e67400Marco Nelissen                // the first decoded frame should be discarded to account for decoder delay
48841914becfd019c619783d875c61ef71db0e67400Marco Nelissen                numOutBytes = 0;
48941914becfd019c619783d875c61ef71db0e67400Marco Nelissen            }
49041914becfd019c619783d875c61ef71db0e67400Marco Nelissen
491b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFilledLen = numOutBytes;
492b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nFlags = 0;
493b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
494b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader->nTimeStamp =
495b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                mAnchorTimeUs
496b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke                    + (mNumSamplesOutput * 1000000ll) / mStreamInfo->sampleRate;
497b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
498b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mNumSamplesOutput += mStreamInfo->frameSize;
499b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
500b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo->mOwnedByUs = false;
501b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outQueue.erase(outQueue.begin());
502b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outInfo = NULL;
503b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyFillBufferDone(outHeader);
504b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            outHeader = NULL;
505b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
506b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
507b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (inHeader->nFilledLen == 0) {
508b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo->mOwnedByUs = false;
509b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inQueue.erase(inQueue.begin());
510b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inInfo = NULL;
511b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            notifyEmptyBufferDone(inHeader);
512b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            inHeader = NULL;
513b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
514b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
515b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        if (decoderErr == AAC_DEC_OK) {
516b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            ++mInputBufferCount;
517b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
518b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
519b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
520b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
521b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
522b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex == 0) {
523b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // Make sure that the next buffer output does not still
524b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        // depend on fragments from the last one decoded.
5253748b71a7fe73b0365a93f1fd28ced14219f85e5Dave Burke        aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
52641914becfd019c619783d875c61ef71db0e67400Marco Nelissen        mIsFirst = true;
527b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
528b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
529b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
530b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkevoid SoftAAC2::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
531b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    if (portIndex != 1) {
532b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        return;
533b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
534b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
535b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    switch (mOutputPortSettingsChange) {
536b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case NONE:
537b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
538b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
539b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        case AWAITING_DISABLED:
540b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
541b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK(!enabled);
542b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mOutputPortSettingsChange = AWAITING_ENABLED;
543b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
544b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
545b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
546b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        default:
547b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        {
548b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
549b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            CHECK(enabled);
550b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            mOutputPortSettingsChange = NONE;
551b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke            break;
552b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        }
553b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    }
554b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
555b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
556b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}  // namespace android
557b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke
558b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burkeandroid::SoftOMXComponent *createSoftOMXComponent(
559b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        const char *name, const OMX_CALLBACKTYPE *callbacks,
560b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
561b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke    return new android::SoftAAC2(name, callbacks, appData, component);
562b7ddcc9460f488f0b032aeb27b52a423318a97eaDave Burke}
563