SoftAACEncoder2.cpp revision aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5b
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"
22aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
23aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/ADebug.h>
24aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#include <media/stagefright/foundation/hexdump.h>
25aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
26aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkenamespace android {
27aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
28aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burketemplate<class T>
29aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatic void InitOMXParams(T *params) {
30aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nSize = sizeof(T);
31aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nVersionMajor = 1;
32aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nVersionMinor = 0;
33aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nRevision = 0;
34aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    params->nVersion.s.nStep = 0;
35aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
36aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
37aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeSoftAACEncoder2::SoftAACEncoder2(
38aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const char *name,
39aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const OMX_CALLBACKTYPE *callbacks,
40aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_PTR appData,
41aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_COMPONENTTYPE **component)
42aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    : SimpleSoftOMXComponent(name, callbacks, appData, component),
43aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mAACEncoder(NULL),
44aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mNumChannels(1),
45aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSampleRate(44100),
46aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mBitRate(0),
47aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mAACProfile(OMX_AUDIO_AACObjectLC),
48aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSentCodecSpecificData(false),
49aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputSize(0),
50aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputFrame(NULL),
51aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mInputTimeUs(-1ll),
52aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSawInputEOS(false),
53aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke      mSignalledError(false) {
54aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    initPorts();
55aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    CHECK_EQ(initEncoder(), (status_t)OK);
56aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    setAudioParams();
57aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
58aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
59aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeSoftAACEncoder2::~SoftAACEncoder2() {
60aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    aacEncClose(&mAACEncoder);
61aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
62aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    delete[] mInputFrame;
63aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    mInputFrame = NULL;
64aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
65aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
66aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkevoid SoftAACEncoder2::initPorts() {
67aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    OMX_PARAM_PORTDEFINITIONTYPE def;
68aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    InitOMXParams(&def);
69aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
70aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nPortIndex = 0;
71aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDir = OMX_DirInput;
72aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountMin = kNumBuffers;
73aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountActual = def.nBufferCountMin;
74aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t) * 2;
75aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bEnabled = OMX_TRUE;
76aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bPopulated = OMX_FALSE;
77aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDomain = OMX_PortDomainAudio;
78aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bBuffersContiguous = OMX_FALSE;
79aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferAlignment = 1;
80aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
81aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
82aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.pNativeRender = NULL;
83aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
84aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
85aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
86aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    addPort(def);
87aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
88aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nPortIndex = 1;
89aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDir = OMX_DirOutput;
90aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountMin = kNumBuffers;
91aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferCountActual = def.nBufferCountMin;
92aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferSize = 8192;
93aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bEnabled = OMX_TRUE;
94aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bPopulated = OMX_FALSE;
95aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.eDomain = OMX_PortDomainAudio;
96aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.bBuffersContiguous = OMX_FALSE;
97aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.nBufferAlignment = 2;
98aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
99aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
100aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.pNativeRender = NULL;
101aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
102aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
103aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
104aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    addPort(def);
105aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
106aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
107aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatus_t SoftAACEncoder2::initEncoder() {
108aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncOpen(&mAACEncoder, 0, 0)) {
109aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to init AAC encoder");
110aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
111aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
112aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return OK;
113aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
114aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
115aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeOMX_ERRORTYPE SoftAACEncoder2::internalGetParameter(
116aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_INDEXTYPE index, OMX_PTR params) {
117aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    switch (index) {
118aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPortFormat:
119aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
120aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
121aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
122aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
123aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nPortIndex > 1) {
124aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
125aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
126aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
127aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nIndex > 0) {
128aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorNoMore;
129aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
130aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
131aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            formatParams->eEncoding =
132aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (formatParams->nPortIndex == 0)
133aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAAC;
134aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
135aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
136aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
137aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
138aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioAac:
139aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
140aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
141aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
142aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
143aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->nPortIndex != 1) {
144aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
145aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
146aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
147aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nBitRate = mBitRate;
148aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAudioBandWidth = 0;
149aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAACtools = 0;
150aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nAACERtools = 0;
151aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eAACProfile = (OMX_AUDIO_AACPROFILETYPE) mAACProfile;
152aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
153aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
154aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
155aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nChannels = mNumChannels;
156aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nSampleRate = mSampleRate;
157aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            aacParams->nFrameLength = 0;
158aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
159aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
160aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
161aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
162aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPcm:
163aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
164aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
165aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
166aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
167aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (pcmParams->nPortIndex != 0) {
168aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
169aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
170aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
171aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eNumData = OMX_NumericalDataSigned;
172aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eEndian = OMX_EndianBig;
173aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->bInterleaved = OMX_TRUE;
174aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nBitPerSample = 16;
175aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
176aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
177aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
178aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
179aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nChannels = mNumChannels;
180aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            pcmParams->nSamplingRate = mSampleRate;
181aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
182aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
183aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
184aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
185aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default:
186aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return SimpleSoftOMXComponent::internalGetParameter(index, params);
187aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
188aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
189aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
190aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeOMX_ERRORTYPE SoftAACEncoder2::internalSetParameter(
191aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_INDEXTYPE index, const OMX_PTR params) {
192aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    switch (index) {
193aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamStandardComponentRole:
194aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
195aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
196aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (const OMX_PARAM_COMPONENTROLETYPE *)params;
197aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
198aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (strncmp((const char *)roleParams->cRole,
199aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        "audio_encoder.aac",
200aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        OMX_MAX_STRINGNAME_SIZE - 1)) {
201aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
203aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
204aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
205aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
206aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
207aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPortFormat:
208aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
209aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
210aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
211aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
212aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nPortIndex > 1) {
213aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
215aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
216aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (formatParams->nIndex > 0) {
217aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorNoMore;
218aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
220aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if ((formatParams->nPortIndex == 0
221aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        && formatParams->eEncoding != OMX_AUDIO_CodingPCM)
222aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                || (formatParams->nPortIndex == 1
223aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        && formatParams->eEncoding != OMX_AUDIO_CodingAAC)) {
224aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
225aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
226aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
227aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
228aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
229aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
230aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioAac:
231aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
232aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
233aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
234aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
235aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->nPortIndex != 1) {
236aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
237aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
238aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
239aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mBitRate = aacParams->nBitRate;
240aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mNumChannels = aacParams->nChannels;
241aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSampleRate = aacParams->nSampleRate;
242aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
243aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (aacParams->eAACProfile != OMX_AUDIO_AACObjectNull) {
244aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                mAACProfile = aacParams->eAACProfile;
245aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
246aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
247aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (setAudioParams() != OK) {
248aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
249aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
250aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
251aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
252aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
253aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
254aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case OMX_IndexParamAudioPcm:
255aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        {
256aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
257aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
258aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
259aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (pcmParams->nPortIndex != 0) {
260aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
261aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
262aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
263aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mNumChannels = pcmParams->nChannels;
264aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSampleRate = pcmParams->nSamplingRate;
265aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
266aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (setAudioParams() != OK) {
267aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return OMX_ErrorUndefined;
268aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
269aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
270aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return OMX_ErrorNone;
271aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
272aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
273aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default:
274aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return SimpleSoftOMXComponent::internalSetParameter(index, params);
275aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
276aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
277aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
278aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave BurkeCHANNEL_MODE getChannelMode(OMX_U32 nChannels) {
279aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    CHANNEL_MODE chMode = MODE_INVALID;
280aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    switch (nChannels) {
281aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 1: chMode = MODE_1; break;
282aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 2: chMode = MODE_2; break;
283aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 3: chMode = MODE_1_2; break;
284aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 4: chMode = MODE_1_2_1; break;
285aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 5: chMode = MODE_1_2_2; break;
286aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        case 6: chMode = MODE_1_2_2_1; break;
287aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        default: chMode = MODE_INVALID;
288aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
289aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return chMode;
290aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
291aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
292aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkestatus_t SoftAACEncoder2::setAudioParams() {
293aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    // We call this whenever sample rate, number of channels or bitrate change
294aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    // in reponse to setParameter calls.
295aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
296aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    ALOGV("setAudioParams: %lu Hz, %lu channels, %lu bps",
297aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke         mSampleRate, mNumChannels, mBitRate);
298aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
299aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT,
300aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mAACProfile == OMX_AUDIO_AACObjectELD ? AOT_ER_AAC_ELD : AOT_AAC_LC)) {
301aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
302aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
303aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
304aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
305aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_SAMPLERATE, mSampleRate)) {
306aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
307aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
308aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
309aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_BITRATE, mBitRate)) {
310aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
311aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
312aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
313aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CHANNELMODE,
314aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            getChannelMode(mNumChannels))) {
315aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
316aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
317aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
318aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_TRANSMUX, TT_MP4_RAW)) {
319aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGE("Failed to set AAC encoder parameters");
320aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return UNKNOWN_ERROR;
321aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
322aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
323aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return OK;
324aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
325aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
326aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkevoid SoftAACEncoder2::onQueueFilled(OMX_U32 portIndex) {
327aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (mSignalledError) {
328aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        return;
329aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
330aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
331aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    List<BufferInfo *> &inQueue = getPortQueue(0);
332aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    List<BufferInfo *> &outQueue = getPortQueue(1);
333aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
334aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (!mSentCodecSpecificData) {
335aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // The very first thing we want to output is the codec specific
336aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // data. It does not require any input data but we will need an
337aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // output buffer to store it in.
338aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
339aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (outQueue.empty()) {
340aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
341aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
342aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
343aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (AACENC_OK != aacEncEncode(mAACEncoder, NULL, NULL, NULL, NULL)) {
344aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            ALOGE("Failed to initialize AAC encoder");
345aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
346aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSignalledError = true;
347aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
348aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
349aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
350aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_InfoStruct encInfo;
351aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (AACENC_OK != aacEncInfo(mAACEncoder, &encInfo)) {
352aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            ALOGE("Failed to get AAC encoder info");
353aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
354aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mSignalledError = true;
355aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
356aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
357aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
358aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        BufferInfo *outInfo = *outQueue.begin();
359aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
360aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFilledLen = encInfo.confSize;
361aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
362aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
363aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        uint8_t *out = outHeader->pBuffer + outHeader->nOffset;
364aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memcpy(out, encInfo.confBuf, encInfo.confSize);
365aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
366aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outQueue.erase(outQueue.begin());
367aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo->mOwnedByUs = false;
368aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        notifyFillBufferDone(outHeader);
369aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
370aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mSentCodecSpecificData = true;
371aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
372aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
373aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    size_t numBytesPerInputFrame =
374aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mNumChannels * kNumSamplesPerFrame * sizeof(int16_t);
375aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
376aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    // BUGBUG: Fraunhofer's decoder chokes on large chunks of AAC-ELD
377aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    if (mAACProfile == OMX_AUDIO_AACObjectELD && numBytesPerInputFrame > 512) {
378aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        numBytesPerInputFrame = 512;
379aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
380aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
381aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    for (;;) {
382aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // We do the following until we run out of buffers.
383aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
384aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        while (mInputSize < numBytesPerInputFrame) {
385aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // As long as there's still input data to be read we
386aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // will drain "kNumSamplesPerFrame * mNumChannels" samples
387aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // into the "mInputFrame" buffer and then encode those
388aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // as a unit into an output buffer.
389aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
390aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mSawInputEOS || inQueue.empty()) {
391aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                return;
392aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
393aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
394aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            BufferInfo *inInfo = *inQueue.begin();
395aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
396aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
397aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            const void *inData = inHeader->pBuffer + inHeader->nOffset;
398aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
399aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            size_t copy = numBytesPerInputFrame - mInputSize;
400aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (copy > inHeader->nFilledLen) {
401aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                copy = inHeader->nFilledLen;
402aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
403aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
404aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mInputFrame == NULL) {
405aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                mInputFrame = new int16_t[kNumSamplesPerFrame * mNumChannels];
406aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
407aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
408aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (mInputSize == 0) {
409aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                mInputTimeUs = inHeader->nTimeStamp;
410aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
411aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
412aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy);
413aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            mInputSize += copy;
414aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
415aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nOffset += copy;
416aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nFilledLen -= copy;
417aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
418aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // "Time" on the input buffer has in effect advanced by the
419aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // number of audio frames we just advanced nOffset by.
420aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            inHeader->nTimeStamp +=
421aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                (copy * 1000000ll / mSampleRate)
422aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    / (mNumChannels * sizeof(int16_t));
423aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
424aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (inHeader->nFilledLen == 0) {
425aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
426aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    mSawInputEOS = true;
427aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
428aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    // Pad any remaining data with zeroes.
429aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    memset((uint8_t *)mInputFrame + mInputSize,
430aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                           0,
431aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                           numBytesPerInputFrame - mInputSize);
432aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
433aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    mInputSize = numBytesPerInputFrame;
434aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                }
435aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
436aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inQueue.erase(inQueue.begin());
437aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inInfo->mOwnedByUs = false;
438aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                notifyEmptyBufferDone(inHeader);
439aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
440aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inData = NULL;
441aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inHeader = NULL;
442aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                inInfo = NULL;
443aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
444aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
445aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // At this  point we have all the input data necessary to encode
447aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // a single frame, all we need is an output buffer to store the result
448aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // in.
449aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
450aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (outQueue.empty()) {
451aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            return;
452aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
453aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
454aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        BufferInfo *outInfo = *outQueue.begin();
455aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
456aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
457aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        uint8_t *outPtr = (uint8_t *)outHeader->pBuffer + outHeader->nOffset;
458aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset;
459aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
460aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_InArgs inargs;
461aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_OutArgs outargs;
462aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memset(&inargs, 0, sizeof(inargs));
463aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        memset(&outargs, 0, sizeof(outargs));
464aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inargs.numInSamples = numBytesPerInputFrame / sizeof(int16_t);
465aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
466aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        void* inBuffer[]        = { (unsigned char *)mInputFrame };
467aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   inBufferIds[]     = { IN_AUDIO_DATA };
468aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   inBufferSize[]    = { numBytesPerInputFrame };
469aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   inBufferElSize[]  = { sizeof(int16_t) };
470aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
471aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_BufDesc inBufDesc;
472aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.numBufs           = sizeof(inBuffer) / sizeof(void*);
473aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufs              = (void**)&inBuffer;
474aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufferIdentifiers = inBufferIds;
475aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufSizes          = inBufferSize;
476aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        inBufDesc.bufElSizes        = inBufferElSize;
477aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
478aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        void* outBuffer[]       = { outPtr };
479aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferIds[]    = { OUT_BITSTREAM_DATA };
480aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferSize[]   = { 0 };
481aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        INT   outBufferElSize[] = { sizeof(UCHAR) };
482aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
483aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_BufDesc outBufDesc;
484aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.numBufs           = sizeof(outBuffer) / sizeof(void*);
485aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufs              = (void**)&outBuffer;
486aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufferIdentifiers = outBufferIds;
487aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufSizes          = outBufferSize;
488aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outBufDesc.bufElSizes        = outBufferElSize;
489aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
490aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        // Encode the mInputFrame, which is treated as a modulo buffer
491aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        AACENC_ERROR encoderErr = AACENC_OK;
492aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        size_t nOutputBytes = 0;
493aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        do {
494aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            memset(&outargs, 0, sizeof(outargs));
495aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
496aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outBuffer[0] = outPtr;
497aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outBufferSize[0] = outAvailable - nOutputBytes;
498aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
499aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            encoderErr = aacEncEncode(mAACEncoder,
500aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &inBufDesc,
501aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &outBufDesc,
502aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &inargs,
503aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                      &outargs);
504aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
505aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (encoderErr == AACENC_OK) {
506aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                outPtr += outargs.numOutBytes;
507aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                nOutputBytes += outargs.numOutBytes;
508aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
509aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                if (outargs.numInSamples > 0) {
510aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    int numRemainingSamples = inargs.numInSamples - outargs.numInSamples;
511aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    if (numRemainingSamples > 0) {
512aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                        memmove(mInputFrame,
513aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                &mInputFrame[outargs.numInSamples],
514aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                                sizeof(int16_t) * numRemainingSamples);
515aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    }
516aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    inargs.numInSamples -= outargs.numInSamples;
517aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                }
518aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
519aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        } while (encoderErr == AACENC_OK && inargs.numInSamples > 0);
520aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
521aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFilledLen = nOutputBytes;
522aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
523aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
524aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
525aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        if (mSawInputEOS) {
526aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // We also tag this output buffer with EOS if it corresponds
527aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            // to the final input buffer.
528aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
529aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        }
530aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
531aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader->nTimeStamp = mInputTimeUs;
532aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
533aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#if 0
534aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)",
535aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke              nOutputBytes, mInputTimeUs, outHeader->nFlags);
536aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
537aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
538aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke#endif
539aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
540aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outQueue.erase(outQueue.begin());
541aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo->mOwnedByUs = false;
542aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        notifyFillBufferDone(outHeader);
543aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
544aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outHeader = NULL;
545aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        outInfo = NULL;
546aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
547aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        mInputSize = 0;
548aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    }
549aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
550aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
551aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}  // namespace android
552aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke
553aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burkeandroid::SoftOMXComponent *createSoftOMXComponent(
554aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        const char *name, const OMX_CALLBACKTYPE *callbacks,
555aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
556aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke    return new android::SoftAACEncoder2(name, callbacks, appData, component);
557aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke}
558