183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber/* 283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Copyright (C) 2012 The Android Open Source Project 383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * 483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * you may not use this file except in compliance with the License. 683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * You may obtain a copy of the License at 783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * 883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * 1083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * Unless required by applicable law or agreed to in writing, software 1183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * See the License for the specific language governing permissions and 1483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber * limitations under the License. 1583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber */ 1683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 1783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber//#define LOG_NDEBUG 0 1883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#define LOG_TAG "SoftAMRWBEncoder" 1983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <utils/Log.h> 2083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include "SoftAMRWBEncoder.h" 2283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include "cmnMemory.h" 2483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#include <media/stagefright/foundation/hexdump.h> 2783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Hubernamespace android { 2983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 3083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstatic const int32_t kSampleRate = 16000; 3183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 3283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Hubertemplate<class T> 3383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstatic void InitOMXParams(T *params) { 3483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber params->nSize = sizeof(T); 3583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber params->nVersion.s.nVersionMajor = 1; 3683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber params->nVersion.s.nVersionMinor = 0; 3783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber params->nVersion.s.nRevision = 0; 3883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber params->nVersion.s.nStep = 0; 3983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 4083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 4183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas HuberSoftAMRWBEncoder::SoftAMRWBEncoder( 4283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const char *name, 4383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const OMX_CALLBACKTYPE *callbacks, 4483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_PTR appData, 4583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_COMPONENTTYPE **component) 4683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber : SimpleSoftOMXComponent(name, callbacks, appData, component), 4783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mEncoderHandle(NULL), 4883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mApiHandle(NULL), 4983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator(NULL), 5083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mBitRate(0), 5183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMode(VOAMRWB_MD66), 5283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputSize(0), 5383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputTimeUs(-1ll), 5483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mSawInputEOS(false), 5583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mSignalledError(false) { 5683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber initPorts(); 5783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber CHECK_EQ(initEncoder(), (status_t)OK); 5883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 5983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 6083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas HuberSoftAMRWBEncoder::~SoftAMRWBEncoder() { 6183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (mEncoderHandle != NULL) { 6283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle)); 6383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mEncoderHandle = NULL; 6483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 6583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 6683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber delete mApiHandle; 6783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mApiHandle = NULL; 6883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 6983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber delete mMemOperator; 7083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator = NULL; 7183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 7283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 7383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Hubervoid SoftAMRWBEncoder::initPorts() { 7483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 7583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber InitOMXParams(&def); 7683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 7783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nPortIndex = 0; 7883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.eDir = OMX_DirInput; 7983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferCountMin = kNumBuffers; 8083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 8183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t); 8283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bEnabled = OMX_TRUE; 8383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bPopulated = OMX_FALSE; 8483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.eDomain = OMX_PortDomainAudio; 8583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bBuffersContiguous = OMX_FALSE; 8683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferAlignment = 1; 8783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 8883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 8983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.pNativeRender = NULL; 9083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 9183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 9283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 9383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber addPort(def); 9483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 9583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nPortIndex = 1; 9683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.eDir = OMX_DirOutput; 9783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferCountMin = kNumBuffers; 9883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 9983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferSize = 8192; 10083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bEnabled = OMX_TRUE; 10183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bPopulated = OMX_FALSE; 10283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.eDomain = OMX_PortDomainAudio; 10383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.bBuffersContiguous = OMX_FALSE; 10483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.nBufferAlignment = 2; 10583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 10683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.cMIMEType = const_cast<char *>("audio/amr-wb"); 10783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.pNativeRender = NULL; 10883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 10983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; 11083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 11183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber addPort(def); 11283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 11383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 11483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberstatus_t SoftAMRWBEncoder::initEncoder() { 11583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mApiHandle = new VO_AUDIO_CODECAPI; 11683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 11783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) { 11883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGE("Failed to get api handle"); 11983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return UNKNOWN_ERROR; 12083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 12183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 12283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator = new VO_MEM_OPERATOR; 12383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator->Alloc = cmnMemAlloc; 12483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator->Copy = cmnMemCopy; 12583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator->Free = cmnMemFree; 12683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator->Set = cmnMemSet; 12783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMemOperator->Check = cmnMemCheck; 12883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 12983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VO_CODEC_INIT_USERDATA userData; 13083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memset(&userData, 0, sizeof(userData)); 13183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber userData.memflag = VO_IMF_USERMEMOPERATOR; 13283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber userData.memData = (VO_PTR) mMemOperator; 13383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 13483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (VO_ERR_NONE != mApiHandle->Init( 13583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber &mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) { 13683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGE("Failed to init AMRWB encoder"); 13783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return UNKNOWN_ERROR; 13883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 13983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 14083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VOAMRWBFRAMETYPE type = VOAMRWB_RFC3267; 14183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (VO_ERR_NONE != mApiHandle->SetParam( 14283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &type)) { 14383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGE("Failed to set AMRWB encoder frame type to %d", type); 14483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return UNKNOWN_ERROR; 14583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 14683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 14783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OK; 14883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 14983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 15083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas HuberOMX_ERRORTYPE SoftAMRWBEncoder::internalGetParameter( 15183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_INDEXTYPE index, OMX_PTR params) { 15283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber switch (index) { 15383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioPortFormat: 15483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 15583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 15683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 15783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 1582720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(formatParams)) { 1592720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 1602720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 1612720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 16283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (formatParams->nPortIndex > 1) { 16383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 16483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 16583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 16683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (formatParams->nIndex > 0) { 16783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNoMore; 16883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 16983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 17083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber formatParams->eEncoding = 17183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (formatParams->nPortIndex == 0) 17283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAMR; 17383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 17483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 17583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 17683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 17783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioAmr: 17883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 17983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_AUDIO_PARAM_AMRTYPE *amrParams = 18083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_PARAM_AMRTYPE *)params; 18183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 1822720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(amrParams)) { 1832720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 1842720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 1852720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 18683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (amrParams->nPortIndex != 1) { 18783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 18883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 18983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 19083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->nChannels = 1; 19183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->nBitRate = mBitRate; 19283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 19383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRBandMode = 19483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_AMRBANDMODETYPE)(mMode + OMX_AUDIO_AMRBandModeWB0); 19583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 19683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff; 19783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 19883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 19983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 20083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 20183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 20283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioPcm: 20383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 20483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 20583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 20683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2072720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(pcmParams)) { 2082720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2092720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2102720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 21183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (pcmParams->nPortIndex != 0) { 21283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 21383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 21483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 21583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->eNumData = OMX_NumericalDataSigned; 21683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->eEndian = OMX_EndianBig; 21783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->bInterleaved = OMX_TRUE; 21883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->nBitPerSample = 16; 21983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 22083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelCF; 22183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 22283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->nChannels = 1; 22383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber pcmParams->nSamplingRate = kSampleRate; 22483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 22583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 22683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 22783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 22883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber default: 22983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return SimpleSoftOMXComponent::internalGetParameter(index, params); 23083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 23183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 23283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 23383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas HuberOMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter( 23483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_INDEXTYPE index, const OMX_PTR params) { 23583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber switch (index) { 23683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamStandardComponentRole: 23783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 23883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const OMX_PARAM_COMPONENTROLETYPE *roleParams = 23983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (const OMX_PARAM_COMPONENTROLETYPE *)params; 24083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2412720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(roleParams)) { 2422720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2432720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2442720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 24583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (strncmp((const char *)roleParams->cRole, 24683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber "audio_encoder.amrwb", 24783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 24883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 24983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 25083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 25183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 25283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 25383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 25483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioPortFormat: 25583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 25683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams = 25783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params; 25883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2592720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(formatParams)) { 2602720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2612720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2622720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 26383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (formatParams->nPortIndex > 1) { 26483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 26583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 26683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 26783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if ((formatParams->nPortIndex == 0 26883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber && formatParams->eEncoding != OMX_AUDIO_CodingPCM) 26983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || (formatParams->nPortIndex == 1 27083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber && formatParams->eEncoding != OMX_AUDIO_CodingAMR)) { 27183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 27283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 27383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 27483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 27583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 27683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 27783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioAmr: 27883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 27983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_AUDIO_PARAM_AMRTYPE *amrParams = 28083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_PARAM_AMRTYPE *)params; 28183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 2822720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(amrParams)) { 2832720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 2842720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 2852720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 28683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (amrParams->nPortIndex != 1) { 28783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 28883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 28983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 29083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (amrParams->nChannels != 1 29183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || amrParams->eAMRDTXMode != OMX_AUDIO_AMRDTXModeOff 29283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || amrParams->eAMRFrameFormat 29383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber != OMX_AUDIO_AMRFrameFormatFSF 29483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || amrParams->eAMRBandMode < OMX_AUDIO_AMRBandModeWB0 29583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || amrParams->eAMRBandMode > OMX_AUDIO_AMRBandModeWB8) { 29683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 29783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 29883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 29983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mBitRate = amrParams->nBitRate; 30083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 30183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mMode = (VOAMRWBMODE)( 30283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRBandMode - OMX_AUDIO_AMRBandModeWB0); 30383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 30483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff; 30583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF; 30683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 30783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (VO_ERR_NONE != 30883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mApiHandle->SetParam( 30983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mEncoderHandle, VO_PID_AMRWB_MODE, &mMode)) { 31083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGE("Failed to set AMRWB encoder mode to %d", mMode); 31183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 31283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 31383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 31483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 31583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 31683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 31783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber case OMX_IndexParamAudioPcm: 31883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber { 31983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 32083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 32183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 3222720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen if (!isValidOMXParam(pcmParams)) { 3232720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen return OMX_ErrorBadParameter; 3242720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen } 3252720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen 32683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (pcmParams->nPortIndex != 0) { 32783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 32883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 32983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 33083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (pcmParams->nChannels != 1 33183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber || pcmParams->nSamplingRate != (OMX_U32)kSampleRate) { 33283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorUndefined; 33383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 33483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 33583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return OMX_ErrorNone; 33683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 33783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 33883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 33983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber default: 34083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return SimpleSoftOMXComponent::internalSetParameter(index, params); 34183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 34283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 34383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 34484333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftAMRWBEncoder::onQueueFilled(OMX_U32 /* portIndex */) { 34583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (mSignalledError) { 34683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return; 34783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 34883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 34983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber List<BufferInfo *> &inQueue = getPortQueue(0); 35083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber List<BufferInfo *> &outQueue = getPortQueue(1); 35183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 35283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber size_t numBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t); 35383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 35483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber for (;;) { 35583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // We do the following until we run out of buffers. 35683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 35783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber while (mInputSize < numBytesPerInputFrame) { 35883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // As long as there's still input data to be read we 35983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // will drain "kNumSamplesPerFrame" samples 36083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // into the "mInputFrame" buffer and then encode those 36183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // as a unit into an output buffer. 36283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 36383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (mSawInputEOS || inQueue.empty()) { 36483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return; 36583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 36683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 36783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber BufferInfo *inInfo = *inQueue.begin(); 36883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 36983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 37083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const void *inData = inHeader->pBuffer + inHeader->nOffset; 37183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 37283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber size_t copy = numBytesPerInputFrame - mInputSize; 37383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (copy > inHeader->nFilledLen) { 37483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber copy = inHeader->nFilledLen; 37583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 37683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 37783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (mInputSize == 0) { 37883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputTimeUs = inHeader->nTimeStamp; 37983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 38083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 38183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy); 38283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputSize += copy; 38383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 38483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inHeader->nOffset += copy; 38583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inHeader->nFilledLen -= copy; 38683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 38783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // "Time" on the input buffer has in effect advanced by the 38883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // number of audio frames we just advanced nOffset by. 38983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inHeader->nTimeStamp += 39083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber (copy * 1000000ll / kSampleRate) / sizeof(int16_t); 39183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 39283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (inHeader->nFilledLen == 0) { 39383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 39483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGV("saw input EOS"); 39583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mSawInputEOS = true; 39683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 39783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // Pad any remaining data with zeroes. 39883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memset((uint8_t *)mInputFrame + mInputSize, 39983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 0, 40083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber numBytesPerInputFrame - mInputSize); 40183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 40283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputSize = numBytesPerInputFrame; 40383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 40483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 40583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inQueue.erase(inQueue.begin()); 40683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inInfo->mOwnedByUs = false; 40783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber notifyEmptyBufferDone(inHeader); 40883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 40983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inData = NULL; 41083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inHeader = NULL; 41183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inInfo = NULL; 41283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 41383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 41483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 41583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // At this point we have all the input data necessary to encode 41683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // a single frame, all we need is an output buffer to store the result 41783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // in. 41883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 41983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (outQueue.empty()) { 42083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return; 42183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 42283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 42383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber BufferInfo *outInfo = *outQueue.begin(); 42483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 42583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 42683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber uint8_t *outPtr = outHeader->pBuffer + outHeader->nOffset; 42783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset; 42883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 42983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VO_CODECBUFFER inputData; 43083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memset(&inputData, 0, sizeof(inputData)); 43183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inputData.Buffer = (unsigned char *) mInputFrame; 43283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber inputData.Length = mInputSize; 43383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 43483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber CHECK_EQ(VO_ERR_NONE, 43583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mApiHandle->SetInputData(mEncoderHandle, &inputData)); 43683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 43783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VO_CODECBUFFER outputData; 43883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memset(&outputData, 0, sizeof(outputData)); 43983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VO_AUDIO_OUTPUTINFO outputInfo; 44083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber memset(&outputInfo, 0, sizeof(outputInfo)); 44183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 44283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outputData.Buffer = outPtr; 44383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outputData.Length = outAvailable; 44483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber VO_U32 ret = mApiHandle->GetOutputData( 44583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mEncoderHandle, &outputData, &outputInfo); 44683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL); 44783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 44883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader->nFilledLen = outputData.Length; 44983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; 45083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 45183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber if (mSawInputEOS) { 45283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // We also tag this output buffer with EOS if it corresponds 45383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber // to the final input buffer. 45483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_EOS; 45583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 45683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 45783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader->nTimeStamp = mInputTimeUs; 45883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 45983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#if 0 46083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber ALOGI("sending %ld bytes of data (time = %lld us, flags = 0x%08lx)", 46183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader->nFilledLen, mInputTimeUs, outHeader->nFlags); 46283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 46383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen); 46483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber#endif 46583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 46683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outQueue.erase(outQueue.begin()); 46783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outInfo->mOwnedByUs = false; 46883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber notifyFillBufferDone(outHeader); 46983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 47083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outHeader = NULL; 47183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber outInfo = NULL; 47283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 47383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber mInputSize = 0; 47483f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber } 47583f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 47683f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 47783f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} // namespace android 47883f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber 47983f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent( 48083f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber const char *name, const OMX_CALLBACKTYPE *callbacks, 48183f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber OMX_PTR appData, OMX_COMPONENTTYPE **component) { 48283f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber return new android::SoftAMRWBEncoder(name, callbacks, appData, component); 48383f70f4472e9b0cacc5d372eddfcef4b02662d10Andreas Huber} 484