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 "SoftG711" 19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <utils/Log.h> 20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftG711.h" 22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/MediaDefs.h> 25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android { 27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T> 29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) { 30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nSize = sizeof(T); 31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMajor = 1; 32bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMinor = 0; 33bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nRevision = 0; 34bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nStep = 0; 35bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 36bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 37bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftG711::SoftG711( 38bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, 39bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_CALLBACKTYPE *callbacks, 40bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, 41bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_COMPONENTTYPE **component) 42bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : SimpleSoftOMXComponent(name, callbacks, appData, component), 43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mIsMLaw(true), 44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumChannels(1), 45bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mSignalledError(false) { 46bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (!strcmp(name, "OMX.google.g711.alaw.decoder")) { 47bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mIsMLaw = false; 48bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(!strcmp(name, "OMX.google.g711.mlaw.decoder")); 50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber initPorts(); 53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 55bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftG711::~SoftG711() { 56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftG711::initPorts() { 59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber InitOMXParams(&def); 61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 0; 63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirInput; 64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = 8192; 67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 1; 72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = 74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const_cast<char *>( 75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mIsMLaw 76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ? MEDIA_MIMETYPE_AUDIO_G711_MLAW 77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : MEDIA_MIMETYPE_AUDIO_G711_ALAW); 78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingG711; 82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 1; 86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirOutput; 87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = kMaxNumSamplesPerFrame * sizeof(int16_t); 90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 2; 95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 104bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftG711::internalGetParameter( 105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, OMX_PTR params) { 106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioPcm: 108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (pcmParams->nPortIndex > 1) { 113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eNumData = OMX_NumericalDataSigned; 117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eEndian = OMX_EndianBig; 118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->bInterleaved = OMX_TRUE; 119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nBitPerSample = 16; 120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nChannels = mNumChannels; 125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nSamplingRate = 8000; 126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalGetParameter(index, params); 132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 135bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftG711::internalSetParameter( 136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, const OMX_PTR params) { 137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioPcm: 139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 143c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { 144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (pcmParams->nChannels < 1 || pcmParams->nChannels > 2) { 148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 151c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber if(pcmParams->nPortIndex == 0) { 152c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber mNumChannels = pcmParams->nChannels; 153c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber } 154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamStandardComponentRole: 159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_PARAM_COMPONENTROLETYPE *roleParams = 161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_PARAM_COMPONENTROLETYPE *)params; 162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mIsMLaw) { 164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "audio_decoder.g711mlaw", 166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "audio_decoder.g711alaw", 172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalSetParameter(index, params); 182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftG711::onQueueFilled(OMX_U32 portIndex) { 186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mSignalledError) { 187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &inQueue = getPortQueue(0); 191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &outQueue = getPortQueue(1); 192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (!inQueue.empty() && !outQueue.empty()) { 194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *inInfo = *inQueue.begin(); 195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *outInfo = *outQueue.begin(); 198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = 0; 206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_EOS; 207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFilledLen > kMaxNumSamplesPerFrame) { 21529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("input buffer too large (%ld).", inHeader->nFilledLen); 216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mSignalledError = true; 219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset; 222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mIsMLaw) { 224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber DecodeMLaw( 225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber reinterpret_cast<int16_t *>(outHeader->pBuffer), 226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inputptr, inHeader->nFilledLen); 227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber DecodeALaw( 229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber reinterpret_cast<int16_t *>(outHeader->pBuffer), 230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inputptr, inHeader->nFilledLen); 231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nTimeStamp = inHeader->nTimeStamp; 234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nOffset = 0; 235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = inHeader->nFilledLen * sizeof(int16_t); 236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = 0; 237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo = NULL; 241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader = NULL; 243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo = NULL; 247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader = NULL; 249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber// static 253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftG711::DecodeALaw( 254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16_t *out, const uint8_t *in, size_t inSize) { 255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (inSize-- > 0) { 256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t x = *in++; 257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t ix = x ^ 0x55; 259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ix &= 0x7f; 260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t iexp = ix >> 4; 262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t mant = ix & 0x0f; 263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (iexp > 0) { 265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mant += 16; 266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mant = (mant << 4) + 8; 269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (iexp > 1) { 271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mant = mant << (iexp - 1); 272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber *out++ = (x > 127) ? mant : -mant; 275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber// static 279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftG711::DecodeMLaw( 280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int16_t *out, const uint8_t *in, size_t inSize) { 281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (inSize-- > 0) { 282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t x = *in++; 283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t mantissa = ~x; 285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t exponent = (mantissa >> 4) & 7; 286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t segment = exponent + 1; 287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mantissa &= 0x0f; 288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t step = 4 << segment; 290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t abs = (0x80l << exponent) + step * mantissa + step / 2 - 4 * 33; 292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber *out++ = (x < 0x80) ? -abs : abs; 294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} // namespace android 298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent( 300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, const OMX_CALLBACKTYPE *callbacks, 301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, OMX_COMPONENTTYPE **component) { 302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return new android::SoftG711(name, callbacks, appData, component); 303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 305