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