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