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