1aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke/*
2aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * Copyright (C) 2012 The Android Open Source Project
3aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke *
4aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * Licensed under the Apache License, Version 2.0 (the "License");
5aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * you may not use this file except in compliance with the License.
6aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * You may obtain a copy of the License at
7aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke *
8aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke *      http://www.apache.org/licenses/LICENSE-2.0
9aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke *
10aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * Unless required by applicable law or agreed to in writing, software
11aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * distributed under the License is distributed on an "AS IS" BASIS,
12aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * See the License for the specific language governing permissions and
14aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke * limitations under the License.
15aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke */
16aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
17aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke//#define LOG_NDEBUG 0
18aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#define LOG_TAG "SoftAACEncoder2"
19aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <utils/Log.h>
20aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
21aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include "SoftAACEncoder2.h"
22b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi#include <OMX_AudioExt.h>
23ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim#include <OMX_IndexExt.h>
24aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
25aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ADebug.h>
26aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/hexdump.h>
27ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim#include <utils/misc.h>
28aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
29aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkenamespace android {
30aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
31aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burketemplate<class T>
32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatic void InitOMXParams(T *params) {
33aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nSize = sizeof(T);
34aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nVersionMajor = 1;
35aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nVersionMinor = 0;
36aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nRevision = 0;
37aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nStep = 0;
38aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
39aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
40ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kimstatic const OMX_U32 kSupportedProfiles[] = {
41ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    OMX_AUDIO_AACObjectLC,
42ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    OMX_AUDIO_AACObjectHE,
43ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    OMX_AUDIO_AACObjectHE_PS,
44ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    OMX_AUDIO_AACObjectLD,
45ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    OMX_AUDIO_AACObjectELD,
46ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim};
47ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
48aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeSoftAACEncoder2::SoftAACEncoder2(
49aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const char *name,
50aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const OMX_CALLBACKTYPE *callbacks,
51aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_PTR appData,
52aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_COMPONENTTYPE **component)
53aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    : SimpleSoftOMXComponent(name, callbacks, appData, component),
54aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mAACEncoder(NULL),
55aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mNumChannels(1),
56aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSampleRate(44100),
57aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mBitRate(0),
58b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi      mSBRMode(-1),
59b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi      mSBRRatio(0),
60aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mAACProfile(OMX_AUDIO_AACObjectLC),
61aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSentCodecSpecificData(false),
62aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputSize(0),
63aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputFrame(NULL),
64aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputTimeUs(-1ll),
65aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSawInputEOS(false),
66aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSignalledError(false) {
67aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    initPorts();
68aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    CHECK_EQ(initEncoder(), (status_t)OK);
69aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    setAudioParams();
70aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
71aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
72aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeSoftAACEncoder2::~SoftAACEncoder2() {
73aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    aacEncClose(&mAACEncoder);
74aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
75aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    delete[] mInputFrame;
76aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    mInputFrame = NULL;
77aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
78aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
79aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkevoid SoftAACEncoder2::initPorts() {
80aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    OMX_PARAM_PORTDEFINITIONTYPE def;
81aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    InitOMXParams(&def);
82aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
83aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nPortIndex = 0;
84aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDir = OMX_DirInput;
85aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountMin = kNumBuffers;
86aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountActual = def.nBufferCountMin;
87aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t) * 2;
88aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bEnabled = OMX_TRUE;
89aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bPopulated = OMX_FALSE;
90aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDomain = OMX_PortDomainAudio;
91aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bBuffersContiguous = OMX_FALSE;
92aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferAlignment = 1;
93aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
94aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
95aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.pNativeRender = NULL;
96aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
97aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
98aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
99aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    addPort(def);
100aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
101aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nPortIndex = 1;
102aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDir = OMX_DirOutput;
103aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountMin = kNumBuffers;
104aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountActual = def.nBufferCountMin;
105aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferSize = 8192;
106aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bEnabled = OMX_TRUE;
107aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bPopulated = OMX_FALSE;
108aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDomain = OMX_PortDomainAudio;
109aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bBuffersContiguous = OMX_FALSE;
110aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferAlignment = 2;
111aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
112aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
113aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.pNativeRender = NULL;
114aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
115aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
116aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
117aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    addPort(def);
118aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
119aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
120aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatus_t SoftAACEncoder2::initEncoder() {
121aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) {
122aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to init AAC encoder");
123aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
124aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
125aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return OK;
126aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
127aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
128aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeOMX_ERRORTYPE SoftAACEncoder2::internalGetParameter(
129aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_INDEXTYPE index, OMX_PTR params) {
130ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim    switch ((OMX_U32) index) {
131aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPortFormat:
132aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
133aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
134aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
135aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
1362720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(formatParams)) {
1372720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
1382720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
1392720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
140aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nPortIndex > 1) {
141aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
142aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
143aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
144aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nIndex > 0) {
145aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorNoMore;
146aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
147aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
148aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            formatParams->eEncoding =
149aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (formatParams->nPortIndex == 0)
150aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAAC;
151aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
152aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
153aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
154aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
155aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioAac:
156aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
157aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
158aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
159aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
1602720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(aacParams)) {
1612720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
1622720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
1632720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
164aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->nPortIndex != 1) {
165aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
166aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
167aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
168aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nBitRate = mBitRate;
169aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAudioBandWidth = 0;
170aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAACtools = 0;
171aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAACERtools = 0;
172aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eAACProfile = (OMX_AUDIO_AACPROFILETYPE) mAACProfile;
173aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
174aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
175aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
176aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nChannels = mNumChannels;
177aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nSampleRate = mSampleRate;
178aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nFrameLength = 0;
179aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
180b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            switch (mSBRMode) {
181b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            case 1: // sbr on
182b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                switch (mSBRRatio) {
183b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                case 0:
184b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    // set both OMX AAC tool flags
185b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
186b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
187b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    break;
188b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                case 1:
189b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    // set single-rate SBR active
190b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
191b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
192b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    break;
193b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                case 2:
194b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    // set dual-rate SBR active
195b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
196b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    aacParams->nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
197b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    break;
198b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                default:
199b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    ALOGE("invalid SBR ratio %d", mSBRRatio);
200b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    TRESPASS();
201b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                }
202b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                break;
203b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            case 0:  // sbr off
204b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            case -1: // sbr undefined
205b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
206b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                aacParams->nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
207b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                break;
208b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            default:
209b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                ALOGE("invalid SBR mode %d", mSBRMode);
210b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                TRESPASS();
211b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
212b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
213b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
214b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
215aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
216aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
217aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
218aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPcm:
219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
220aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
221aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
222aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
2232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(pcmParams)) {
2242720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
2252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
2262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
227aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (pcmParams->nPortIndex != 0) {
228aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
229aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
230aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
231aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eNumData = OMX_NumericalDataSigned;
232aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eEndian = OMX_EndianBig;
233aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->bInterleaved = OMX_TRUE;
234aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nBitPerSample = 16;
235aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
236aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
237aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
238aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
239aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nChannels = mNumChannels;
240aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nSamplingRate = mSampleRate;
241aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
242aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
243aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
244aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
245ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim        case OMX_IndexParamAudioProfileQuerySupported:
246ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim        {
247ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *profileParams =
248ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim                (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *)params;
249ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
2502720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(profileParams)) {
2512720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
2522720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
2532720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
254ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            if (profileParams->nPortIndex != 1) {
255ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim                return OMX_ErrorUndefined;
256ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            }
257ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
258ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            if (profileParams->nProfileIndex >= NELEM(kSupportedProfiles)) {
259ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim                return OMX_ErrorNoMore;
260ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            }
261ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
262ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            profileParams->eProfile =
263ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim                kSupportedProfiles[profileParams->nProfileIndex];
264ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
265ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim            return OMX_ErrorNone;
266ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim        }
267ed2a94af7d53374d40c346cd4771ca168924e1e2Wonsik Kim
268aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default:
269aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return SimpleSoftOMXComponent::internalGetParameter(index, params);
270aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
271aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
272aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
273aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeOMX_ERRORTYPE SoftAACEncoder2::internalSetParameter(
274aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_INDEXTYPE index, const OMX_PTR params) {
275aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    switch (index) {
276aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamStandardComponentRole:
277aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
278aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
279aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (const OMX_PARAM_COMPONENTROLETYPE *)params;
280aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
2812720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(roleParams)) {
2822720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
2832720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
2842720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
285aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (strncmp((const char *)roleParams->cRole,
286aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        "audio_encoder.aac",
287aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        OMX_MAX_STRINGNAME_SIZE - 1)) {
288aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
289aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
290aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
291aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
292aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
293aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
294aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPortFormat:
295aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
296aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
297aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
298aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
2992720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(formatParams)) {
3002720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
3012720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3022720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
303aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nPortIndex > 1) {
304aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
305aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
306aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
307aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nIndex > 0) {
308aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorNoMore;
309aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
310aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
311aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if ((formatParams->nPortIndex == 0
312aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)
313aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                || (formatParams->nPortIndex == 1
314aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        && formatParams->eEncoding != OMX_AUDIO_CodingAAC)) {
315aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
316aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
317aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
318aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
319aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
320aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
321aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioAac:
322aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
323aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
324aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
325aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
3262720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(aacParams)) {
3272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
3282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
330aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->nPortIndex != 1) {
331aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
332aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
333aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
334aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mBitRate = aacParams->nBitRate;
335aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mNumChannels = aacParams->nChannels;
336aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSampleRate = aacParams->nSampleRate;
337aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->eAACProfile != OMX_AUDIO_AACObjectNull) {
338aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                mAACProfile = aacParams->eAACProfile;
339aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
340aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
341b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
342b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
343b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRMode = 0;
344b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRRatio = 0;
345b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            } else if ((aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
346b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    && !(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
347b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRMode = 1;
348b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRRatio = 1;
349b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            } else if (!(aacParams->nAACtools & OMX_AUDIO_AACToolAndroidSSBR)
350b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                    && (aacParams->nAACtools & OMX_AUDIO_AACToolAndroidDSBR)) {
351b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRMode = 1;
352b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRRatio = 2;
353b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            } else {
354b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRMode = -1; // codec default sbr mode
355b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                mSBRRatio = 0;
356b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
357b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
358aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (setAudioParams() != OK) {
359aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
360aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
361aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
362aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
363aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
364aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
365aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPcm:
366aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
367aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
368aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
369aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
3702720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(pcmParams)) {
3712720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
3722720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
3732720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
374aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (pcmParams->nPortIndex != 0) {
375aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
376aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
377aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
378aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mNumChannels = pcmParams->nChannels;
379aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSampleRate = pcmParams->nSamplingRate;
380aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (setAudioParams() != OK) {
381aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
382aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
383aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
384aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
385aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
386aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
387aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default:
388aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return SimpleSoftOMXComponent::internalSetParameter(index, params);
389aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
390aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
391aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
392f60c660f048d5f5e2458cff243c20400d73757a7Dave Burkestatic CHANNEL_MODE getChannelMode(OMX_U32 nChannels) {
393aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    CHANNEL_MODE chMode = MODE_INVALID;
394aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    switch (nChannels) {
395aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 1: chMode = MODE_1; break;
396aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 2: chMode = MODE_2; break;
397aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 3: chMode = MODE_1_2; break;
398aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 4: chMode = MODE_1_2_1; break;
399aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 5: chMode = MODE_1_2_2; break;
400aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 6: chMode = MODE_1_2_2_1; break;
401aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default: chMode = MODE_INVALID;
402aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
403aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return chMode;
404aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
405aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
406f60c660f048d5f5e2458cff243c20400d73757a7Dave Burkestatic AUDIO_OBJECT_TYPE getAOTFromProfile(OMX_U32 profile) {
407f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    if (profile == OMX_AUDIO_AACObjectLC) {
408f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        return AOT_AAC_LC;
409f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    } else if (profile == OMX_AUDIO_AACObjectHE) {
410f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        return AOT_SBR;
4111b02586f0f41d82c80619cfc0d16cd3feb5eaec7Jean-Michel Trivi    } else if (profile == OMX_AUDIO_AACObjectHE_PS) {
4121b02586f0f41d82c80619cfc0d16cd3feb5eaec7Jean-Michel Trivi        return AOT_PS;
4131b02586f0f41d82c80619cfc0d16cd3feb5eaec7Jean-Michel Trivi    } else if (profile == OMX_AUDIO_AACObjectLD) {
4141b02586f0f41d82c80619cfc0d16cd3feb5eaec7Jean-Michel Trivi        return AOT_ER_AAC_LD;
415f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    } else if (profile == OMX_AUDIO_AACObjectELD) {
416f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        return AOT_ER_AAC_ELD;
417f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    } else {
418f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        ALOGW("Unsupported AAC profile - defaulting to AAC-LC");
419f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        return AOT_AAC_LC;
420f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    }
421f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke}
422f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
423aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatus_t SoftAACEncoder2::setAudioParams() {
424b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    // We call this whenever sample rate, number of channels, bitrate or SBR mode change
425aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    // in reponse to setParameter calls.
426aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
427b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    ALOGV("setAudioParams: %u Hz, %u channels, %u bps, %i sbr mode, %i sbr ratio",
428b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi         mSampleRate, mNumChannels, mBitRate, mSBRMode, mSBRRatio);
429aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
430aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT,
431f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            getAOTFromProfile(mAACProfile))) {
432aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
433aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
434aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
435aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
436aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mSampleRate)) {
437aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
438aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
439aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
440aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mBitRate)) {
441aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
442aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
443aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
444aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE,
445aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            getChannelMode(mNumChannels))) {
446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
447aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
448aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
449aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) {
450aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
451aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
452aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
453aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
454b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    if (mSBRMode != -1 && mAACProfile == OMX_AUDIO_AACObjectELD) {
455b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_MODE, mSBRMode)) {
456b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            ALOGE("Failed to set AAC encoder parameters");
457b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return UNKNOWN_ERROR;
458b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
459b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    }
460b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
461b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    /* SBR ratio parameter configurations:
462b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi       0: Default configuration wherein SBR ratio is configured depending on audio object type by
463b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi          the FDK.
464b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi       1: Downsampled SBR (default for ELD)
465b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi       2: Dualrate SBR (default for HE-AAC)
466b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi     */
467b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SBR_RATIO, mSBRRatio)) {
468b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        ALOGE("Failed to set AAC encoder parameters");
469b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        return UNKNOWN_ERROR;
470b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi    }
471b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
472aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return OK;
473aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
474aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
47584333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftAACEncoder2::onQueueFilled(OMX_U32 /* portIndex */) {
476aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (mSignalledError) {
477aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return;
478aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
479aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
480aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    List<BufferInfo *> &inQueue = getPortQueue(0);
481aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    List<BufferInfo *> &outQueue = getPortQueue(1);
482aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
483aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (!mSentCodecSpecificData) {
484aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // The very first thing we want to output is the codec specific
485aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // data. It does not require any input data but we will need an
486aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // output buffer to store it in.
487aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
488aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (outQueue.empty()) {
489aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
490aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
491aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
492aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (AACENC_OK != aacEncEncode(mAACEncoder, NULL, NULL, NULL, NULL)) {
493f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke            ALOGE("Unable to initialize encoder for profile / sample-rate / bit-rate / channels");
494aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
495aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSignalledError = true;
496aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
497aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
498aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
499f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        OMX_U32 actualBitRate  = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE);
500f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        if (mBitRate != actualBitRate) {
50166fe2e9ee30bcb4161bc487ec63d2ae4a05f4051Glenn Kasten            ALOGW("Requested bitrate %u unsupported, using %u", mBitRate, actualBitRate);
502f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke        }
503f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
504aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_InfoStruct encInfo;
505aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) {
506aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            ALOGE("Failed to get AAC encoder info");
507aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
508aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSignalledError = true;
509aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
510aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
511aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
512aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        BufferInfo *outInfo = *outQueue.begin();
513aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
514aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFilledLen = encInfo.confSize;
515aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
516aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
517aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        uint8_t *out = outHeader->pBuffer + outHeader->nOffset;
518aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memcpy(out, encInfo.confBuf, encInfo.confSize);
519aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
520aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outQueue.erase(outQueue.begin());
521aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo->mOwnedByUs = false;
522aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        notifyFillBufferDone(outHeader);
523aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
524aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mSentCodecSpecificData = true;
525aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
526aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
527aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    size_t numBytesPerInputFrame =
528aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mNumChannels * kNumSamplesPerFrame * sizeof(int16_t);
529aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
530f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke    // Limit input size so we only get one ELD frame
531aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (mAACProfile == OMX_AUDIO_AACObjectELD && numBytesPerInputFrame > 512) {
532aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        numBytesPerInputFrame = 512;
533aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
534aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
535aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    for (;;) {
536aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // We do the following until we run out of buffers.
537aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
538aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        while (mInputSize < numBytesPerInputFrame) {
539aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // As long as there's still input data to be read we
540aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // will drain "kNumSamplesPerFrame * mNumChannels" samples
541aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // into the "mInputFrame" buffer and then encode those
542aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // as a unit into an output buffer.
543aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
544aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mSawInputEOS || inQueue.empty()) {
545aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return;
546aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
547aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
548aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            BufferInfo *inInfo = *inQueue.begin();
549aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
550aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
551aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const void *inData = inHeader->pBuffer + inHeader->nOffset;
552aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
553aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            size_t copy = numBytesPerInputFrame - mInputSize;
554aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (copy > inHeader->nFilledLen) {
555aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                copy = inHeader->nFilledLen;
556aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
557aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
558aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mInputFrame == NULL) {
559f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke                mInputFrame = new int16_t[numBytesPerInputFrame / sizeof(int16_t)];
560aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
561aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
562aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mInputSize == 0) {
563aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                mInputTimeUs = inHeader->nTimeStamp;
564aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
565aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
566aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy);
567aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mInputSize += copy;
568aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
569aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nOffset += copy;
570aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nFilledLen -= copy;
571aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
572aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // "Time" on the input buffer has in effect advanced by the
573aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // number of audio frames we just advanced nOffset by.
574aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nTimeStamp +=
575aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (copy * 1000000ll / mSampleRate)
576aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    / (mNumChannels * sizeof(int16_t));
577aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
578aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (inHeader->nFilledLen == 0) {
579aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
580aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    mSawInputEOS = true;
581aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
582aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    // Pad any remaining data with zeroes.
583aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    memset((uint8_t *)mInputFrame + mInputSize,
584aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                           0,
585aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                           numBytesPerInputFrame - mInputSize);
586aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
587aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    mInputSize = numBytesPerInputFrame;
588aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                }
589aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
590aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inQueue.erase(inQueue.begin());
591aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inInfo->mOwnedByUs = false;
592aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                notifyEmptyBufferDone(inHeader);
593aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
594aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inData = NULL;
595aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inHeader = NULL;
596aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inInfo = NULL;
597aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
598aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
599aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
600aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // At this  point we have all the input data necessary to encode
601aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // a single frame, all we need is an output buffer to store the result
602aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // in.
603aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
604aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (outQueue.empty()) {
605aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
606aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
607aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
608aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        BufferInfo *outInfo = *outQueue.begin();
609aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
610aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
611aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        uint8_t *outPtr = (uint8_t *)outHeader->pBuffer + outHeader->nOffset;
612aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset;
613aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
614aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_InArgs inargs;
615aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_OutArgs outargs;
616aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memset(&inargs, 0, sizeof(inargs));
617aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memset(&outargs, 0, sizeof(outargs));
618aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inargs.numInSamples = numBytesPerInputFrame / sizeof(int16_t);
619aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
620aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        void* inBuffer[]        = { (unsigned char *)mInputFrame };
621aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   inBufferIds[]     = { IN_AUDIO_DATA };
622a5761dcb5f9f017ca9b83ec868565d7ce54a92acAndreas Huber        INT   inBufferSize[]    = { (INT)numBytesPerInputFrame };
623aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   inBufferElSize[]  = { sizeof(int16_t) };
624aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
625aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_BufDesc inBufDesc;
626aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.numBufs           = sizeof(inBuffer) / sizeof(void*);
627aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufs              = (void**)&inBuffer;
628aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufferIdentifiers = inBufferIds;
629aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufSizes          = inBufferSize;
630aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufElSizes        = inBufferElSize;
631aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
632aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        void* outBuffer[]       = { outPtr };
633aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferIds[]    = { OUT_BITSTREAM_DATA };
634aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferSize[]   = { 0 };
635aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferElSize[] = { sizeof(UCHAR) };
636aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
637aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_BufDesc outBufDesc;
638aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.numBufs           = sizeof(outBuffer) / sizeof(void*);
639aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufs              = (void**)&outBuffer;
640aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufferIdentifiers = outBufferIds;
641aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufSizes          = outBufferSize;
642aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufElSizes        = outBufferElSize;
643aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
644aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // Encode the mInputFrame, which is treated as a modulo buffer
645aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_ERROR encoderErr = AACENC_OK;
646aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        size_t nOutputBytes = 0;
647f60c660f048d5f5e2458cff243c20400d73757a7Dave Burke
648aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        do {
649aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            memset(&outargs, 0, sizeof(outargs));
650aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
651aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outBuffer[0] = outPtr;
652aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outBufferSize[0] = outAvailable - nOutputBytes;
653aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
654aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            encoderErr = aacEncEncode(mAACEncoder,
655aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &inBufDesc,
656aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &outBufDesc,
657aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &inargs,
658aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &outargs);
659aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
660aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (encoderErr == AACENC_OK) {
661aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                outPtr += outargs.numOutBytes;
662aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                nOutputBytes += outargs.numOutBytes;
663aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
664aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                if (outargs.numInSamples > 0) {
665aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    int numRemainingSamples = inargs.numInSamples - outargs.numInSamples;
666aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    if (numRemainingSamples > 0) {
667aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        memmove(mInputFrame,
668aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                &mInputFrame[outargs.numInSamples],
669aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                sizeof(int16_t) * numRemainingSamples);
670aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    }
671aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    inargs.numInSamples -= outargs.numInSamples;
672aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                }
673aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
674aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        } while (encoderErr == AACENC_OK && inargs.numInSamples > 0);
675aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
676aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFilledLen = nOutputBytes;
677aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
678aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
679aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
680aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (mSawInputEOS) {
681aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // We also tag this output buffer with EOS if it corresponds
682aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // to the final input buffer.
683aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
684aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
685aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
686aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nTimeStamp = mInputTimeUs;
687aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
688aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#if 0
689aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)",
690aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke              nOutputBytes, mInputTimeUs, outHeader->nFlags);
691aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
692aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
693aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#endif
694aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
695aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outQueue.erase(outQueue.begin());
696aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo->mOwnedByUs = false;
697aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        notifyFillBufferDone(outHeader);
698aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
699aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader = NULL;
700aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo = NULL;
701aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
702aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mInputSize = 0;
703aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
704aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
705aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
706aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}  // namespace android
707aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
708aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkeandroid::SoftOMXComponent *createSoftOMXComponent(
709aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const char *name, const OMX_CALLBACKTYPE *callbacks,
710aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
711aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return new android::SoftAACEncoder2(name, callbacks, appData, component);
712aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
713