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