SoftAMR.cpp revision c5255ac5b1bd313dcb50159566163b24dce7483f
1bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/* 2bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * Copyright (C) 2011 The Android Open Source Project 3bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * 4bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * you may not use this file except in compliance with the License. 6bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * You may obtain a copy of the License at 7bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * 8bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * 10bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * Unless required by applicable law or agreed to in writing, software 11bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * See the License for the specific language governing permissions and 14bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * limitations under the License. 15bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber */ 16bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 17bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber//#define LOG_NDEBUG 0 18bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#define LOG_TAG "SoftAMR" 19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <utils/Log.h> 20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftAMR.h" 22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "gsmamr_dec.h" 24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "pvamrwbdecoder.h" 25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/foundation/ADebug.h> 27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android { 29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T> 31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) { 32bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nSize = sizeof(T); 33bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMajor = 1; 34bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMinor = 0; 35bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nRevision = 0; 36bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nStep = 0; 37bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 38bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 39bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftAMR::SoftAMR( 40bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, 41bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_CALLBACKTYPE *callbacks, 42bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, 43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_COMPONENTTYPE **component) 44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : SimpleSoftOMXComponent(name, callbacks, appData, component), 45bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMode(MODE_NARROW), 46bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState(NULL), 47bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderBuf(NULL), 48bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderCookie(NULL), 49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mInputBufferCount(0), 50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs(0), 51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumSamplesOutput(0), 52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mSignalledError(false), 53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange(NONE) { 54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (!strcmp(name, "OMX.google.amrwb.decoder")) { 55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMode = MODE_WIDE; 56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(!strcmp(name, "OMX.google.amrnb.decoder")); 58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber initPorts(); 61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(initDecoder(), (status_t)OK); 62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 64bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftAMR::~SoftAMR() { 65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mMode == MODE_NARROW) { 66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber GSMDecodeFrameExit(&mState); 67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState = NULL; 68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber free(mDecoderBuf); 70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderBuf = NULL; 71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState = NULL; 73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderCookie = NULL; 74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftAMR::initPorts() { 78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber InitOMXParams(&def); 80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 0; 82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirInput; 83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = 8192; 86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 1; 91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = 93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMode == MODE_NARROW 94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ? const_cast<char *>("audio/amr") 95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : const_cast<char *>("audio/amrwb"); 96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingAMR; 100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 1; 104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirOutput; 105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = 109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (mMode == MODE_NARROW ? kNumSamplesPerFrameNB : kNumSamplesPerFrameWB) 110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * sizeof(int16_t); 111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 2; 117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftAMR::initDecoder() { 127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mMode == MODE_NARROW) { 128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber Word16 err = GSMInitDecode(&mState, (Word8 *)"AMRNBDecoder"); 129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (err != 0) { 131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return UNKNOWN_ERROR; 132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t memReq = pvDecoder_AmrWbMemRequirements(); 135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderBuf = malloc(memReq); 136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pvDecoder_AmrWb_Init(&mState, mDecoderBuf, &mDecoderCookie); 138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OK; 141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 143bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftAMR::internalGetParameter( 144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, OMX_PTR params) { 145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioAmr: 147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_AMRTYPE *amrParams = 149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_AMRTYPE *)params; 150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (amrParams->nPortIndex != 0) { 152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->nChannels = 1; 156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff; 157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatConformance; 158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (!isConfigured()) { 160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->nBitRate = 0; 161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->eAMRBandMode = OMX_AUDIO_AMRBandModeUnused; 162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->nBitRate = 0; 164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber amrParams->eAMRBandMode = 165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mMode == MODE_NARROW 166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ? OMX_AUDIO_AMRBandModeNB0 : OMX_AUDIO_AMRBandModeWB0; 167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioPcm: 173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (pcmParams->nPortIndex != 1) { 178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nChannels = 1; 182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eNumData = OMX_NumericalDataSigned; 183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eEndian = OMX_EndianBig; 184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->bInterleaved = OMX_TRUE; 185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nBitPerSample = 16; 186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nSamplingRate = 188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (mMode == MODE_NARROW) ? kSampleRateNB : kSampleRateWB; 189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalGetParameter(index, params); 199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 202bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftAMR::internalSetParameter( 203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, const OMX_PTR params) { 204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamStandardComponentRole: 206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_PARAM_COMPONENTROLETYPE *roleParams = 208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_PARAM_COMPONENTROLETYPE *)params; 209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mMode == MODE_NARROW) { 211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "audio_decoder.amrnb", 213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "audio_decoder.amrwb", 219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioAmr: 228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_AUDIO_PARAM_AMRTYPE *aacParams = 230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_AUDIO_PARAM_AMRTYPE *)params; 231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (aacParams->nPortIndex != 0) { 233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 239c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber case OMX_IndexParamAudioPcm: 240c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber { 241c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 242c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 243c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber 244c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber if (pcmParams->nPortIndex != 1) { 245c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber return OMX_ErrorUndefined; 246c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber } 247c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber 248c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber return OMX_ErrorNone; 249c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber } 250c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber 251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalSetParameter(index, params); 253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftAMR::isConfigured() const { 257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return mInputBufferCount > 0; 258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic size_t getFrameSize(unsigned FT) { 261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber static const size_t kFrameSizeWB[9] = { 262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 132, 177, 253, 285, 317, 365, 397, 461, 477 263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber }; 264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber size_t frameSize = kFrameSizeWB[FT]; 266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber // Round up bits to bytes and add 1 for the header byte. 268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber frameSize = (frameSize + 7) / 8 + 1; 269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return frameSize; 271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftAMR::onQueueFilled(OMX_U32 portIndex) { 274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &inQueue = getPortQueue(0); 275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &outQueue = getPortQueue(1); 276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mSignalledError || mOutputPortSettingsChange != NONE) { 278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (!inQueue.empty() && !outQueue.empty()) { 282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *inInfo = *inQueue.begin(); 283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *outInfo = *outQueue.begin(); 286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = 0; 294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_EOS; 295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nOffset == 0) { 303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs = inHeader->nTimeStamp; 304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumSamplesOutput = 0; 305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const uint8_t *inputPtr = inHeader->pBuffer + inHeader->nOffset; 308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t numBytesRead; 309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mMode == MODE_NARROW) { 311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numBytesRead = 312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber AMRDecode(mState, 313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f), 314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (UWord8 *)&inputPtr[1], 315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber reinterpret_cast<int16_t *>(outHeader->pBuffer), 316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber MIME_IETF); 317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (numBytesRead == -1) { 31929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("PV AMR decoder AMRDecode() call failed"); 320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mSignalledError = true; 323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ++numBytesRead; // Include the frame type header byte. 328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (static_cast<size_t>(numBytesRead) > inHeader->nFilledLen) { 330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber // This is bad, should never have happened, but did. Abort now. 331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mSignalledError = true; 334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16 mode = ((inputPtr[0] >> 3) & 0x0f); 339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber size_t frameSize = getFrameSize(mode); 340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_GE(inHeader->nFilledLen, frameSize); 341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16 frameType; 343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber RX_State_wb rx_state; 344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mime_unsorting( 345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const_cast<uint8_t *>(&inputPtr[1]), 346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mInputSampleBuffer, 347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber &frameType, &mode, 1, &rx_state); 348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16_t *outPtr = (int16_t *)outHeader->pBuffer; 350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16_t numSamplesOutput; 352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pvDecoder_AmrWb( 353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mode, mInputSampleBuffer, 354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outPtr, 355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber &numSamplesOutput, 356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mDecoderBuf, frameType, mDecoderCookie); 357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ((int)numSamplesOutput, (int)kNumSamplesPerFrameWB); 359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber for (int i = 0; i < kNumSamplesPerFrameWB; ++i) { 361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber /* Delete the 2 LSBs (14-bit output) */ 362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outPtr[i] &= 0xfffC; 363bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numBytesRead = frameSize; 366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->nOffset += numBytesRead; 369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->nFilledLen -= numBytesRead; 370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = 0; 372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nOffset = 0; 373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mMode == MODE_NARROW) { 375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = kNumSamplesPerFrameNB * sizeof(int16_t); 376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nTimeStamp = 378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs 379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber + (mNumSamplesOutput * 1000000ll) / kSampleRateNB; 380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumSamplesOutput += kNumSamplesPerFrameNB; 382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = kNumSamplesPerFrameWB * sizeof(int16_t); 384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nTimeStamp = 386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs 387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber + (mNumSamplesOutput * 1000000ll) / kSampleRateWB; 388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 389bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumSamplesOutput += kNumSamplesPerFrameWB; 390bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 391bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 392bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFilledLen == 0) { 393bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 394bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 395bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo = NULL; 396bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 397bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader = NULL; 398bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 399bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 400bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 401bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 402bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo = NULL; 403bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader = NULL; 405bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 406bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ++mInputBufferCount; 407bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 408bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) { 411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (portIndex != 1) { 415bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 416bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 417bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 418bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (mOutputPortSettingsChange) { 419bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case NONE: 420bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 421bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 422bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case AWAITING_DISABLED: 423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(!enabled); 425bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = AWAITING_ENABLED; 426bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 427bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 428bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 429bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 430bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 431bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 432bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(enabled); 433bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = NONE; 434bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 435bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 436bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 437bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 438bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 439bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} // namespace android 440bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 441bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent( 442bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, const OMX_CALLBACKTYPE *callbacks, 443bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, OMX_COMPONENTTYPE **component) { 444bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return new android::SoftAMR(name, callbacks, appData, component); 445bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 446bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 447