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