SoftRaw.cpp revision c6c6d6baf934a594fc4f81b7c4d9289a4c5962f4
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "SoftRaw" 19#include <utils/Log.h> 20 21#include "SoftRaw.h" 22 23#include <media/stagefright/foundation/ADebug.h> 24#include <media/stagefright/foundation/hexdump.h> 25 26namespace android { 27 28template<class T> 29static void InitOMXParams(T *params) { 30 params->nSize = sizeof(T); 31 params->nVersion.s.nVersionMajor = 1; 32 params->nVersion.s.nVersionMinor = 0; 33 params->nVersion.s.nRevision = 0; 34 params->nVersion.s.nStep = 0; 35} 36 37SoftRaw::SoftRaw( 38 const char *name, 39 const OMX_CALLBACKTYPE *callbacks, 40 OMX_PTR appData, 41 OMX_COMPONENTTYPE **component) 42 : SimpleSoftOMXComponent(name, callbacks, appData, component), 43 mSignalledError(false), 44 mChannelCount(2), 45 mSampleRate(44100) { 46 initPorts(); 47 CHECK_EQ(initDecoder(), (status_t)OK); 48} 49 50SoftRaw::~SoftRaw() { 51} 52 53void SoftRaw::initPorts() { 54 OMX_PARAM_PORTDEFINITIONTYPE def; 55 InitOMXParams(&def); 56 57 def.nPortIndex = 0; 58 def.eDir = OMX_DirInput; 59 def.nBufferCountMin = kNumBuffers; 60 def.nBufferCountActual = def.nBufferCountMin; 61 def.nBufferSize = 32 * 1024; 62 def.bEnabled = OMX_TRUE; 63 def.bPopulated = OMX_FALSE; 64 def.eDomain = OMX_PortDomainAudio; 65 def.bBuffersContiguous = OMX_FALSE; 66 def.nBufferAlignment = 1; 67 68 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 69 def.format.audio.pNativeRender = NULL; 70 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 71 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 72 73 addPort(def); 74 75 def.nPortIndex = 1; 76 def.eDir = OMX_DirOutput; 77 def.nBufferCountMin = kNumBuffers; 78 def.nBufferCountActual = def.nBufferCountMin; 79 def.nBufferSize = 32 * 1024; 80 def.bEnabled = OMX_TRUE; 81 def.bPopulated = OMX_FALSE; 82 def.eDomain = OMX_PortDomainAudio; 83 def.bBuffersContiguous = OMX_FALSE; 84 def.nBufferAlignment = 2; 85 86 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 87 def.format.audio.pNativeRender = NULL; 88 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 89 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 90 91 addPort(def); 92} 93 94status_t SoftRaw::initDecoder() { 95 return OK; 96} 97 98OMX_ERRORTYPE SoftRaw::internalGetParameter( 99 OMX_INDEXTYPE index, OMX_PTR params) { 100 switch (index) { 101 case OMX_IndexParamAudioPcm: 102 { 103 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 104 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 105 106 if (pcmParams->nPortIndex != 0 && pcmParams->nPortIndex != 1) { 107 return OMX_ErrorUndefined; 108 } 109 110 pcmParams->eNumData = OMX_NumericalDataSigned; 111 pcmParams->eEndian = OMX_EndianBig; 112 pcmParams->bInterleaved = OMX_TRUE; 113 pcmParams->nBitPerSample = 16; 114 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 115 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 116 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 117 118 pcmParams->nChannels = mChannelCount; 119 pcmParams->nSamplingRate = mSampleRate; 120 121 return OMX_ErrorNone; 122 } 123 124 default: 125 return SimpleSoftOMXComponent::internalGetParameter(index, params); 126 } 127} 128 129OMX_ERRORTYPE SoftRaw::internalSetParameter( 130 OMX_INDEXTYPE index, const OMX_PTR params) { 131 switch (index) { 132 case OMX_IndexParamStandardComponentRole: 133 { 134 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 135 (const OMX_PARAM_COMPONENTROLETYPE *)params; 136 137 if (strncmp((const char *)roleParams->cRole, 138 "audio_decoder.raw", 139 OMX_MAX_STRINGNAME_SIZE - 1)) { 140 return OMX_ErrorUndefined; 141 } 142 143 return OMX_ErrorNone; 144 } 145 146 case OMX_IndexParamAudioPcm: 147 { 148 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 149 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 150 151 if (pcmParams->nPortIndex != 0) { 152 return OMX_ErrorUndefined; 153 } 154 155 mChannelCount = pcmParams->nChannels; 156 mSampleRate = pcmParams->nSamplingRate; 157 158 return OMX_ErrorNone; 159 } 160 161 default: 162 { 163 OMX_ERRORTYPE err = SimpleSoftOMXComponent::internalSetParameter( 164 index, params); 165 // In case inPort->mDef.nBufferSize changed, the output buffer size 166 // should match the input buffer size. 167 PortInfo *inPort = editPortInfo(0); 168 PortInfo *outPort = editPortInfo(1); 169 outPort->mDef.nBufferSize = inPort->mDef.nBufferSize; 170 return err; 171 } 172 } 173} 174 175void SoftRaw::onQueueFilled(OMX_U32 /* portIndex */) { 176 if (mSignalledError) { 177 return; 178 } 179 180 List<BufferInfo *> &inQueue = getPortQueue(0); 181 List<BufferInfo *> &outQueue = getPortQueue(1); 182 183 while (!inQueue.empty() && !outQueue.empty()) { 184 BufferInfo *inInfo = *inQueue.begin(); 185 OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 186 187 BufferInfo *outInfo = *outQueue.begin(); 188 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 189 190 CHECK_GE(outHeader->nAllocLen, inHeader->nFilledLen); 191 memcpy(outHeader->pBuffer, 192 inHeader->pBuffer + inHeader->nOffset, 193 inHeader->nFilledLen); 194 195 outHeader->nFlags = inHeader->nFlags; 196 outHeader->nOffset = 0; 197 outHeader->nFilledLen = inHeader->nFilledLen; 198 outHeader->nTimeStamp = inHeader->nTimeStamp; 199 200 bool sawEOS = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0; 201 202 inQueue.erase(inQueue.begin()); 203 inInfo->mOwnedByUs = false; 204 notifyEmptyBufferDone(inHeader); 205 206 outQueue.erase(outQueue.begin()); 207 outInfo->mOwnedByUs = false; 208 notifyFillBufferDone(outHeader); 209 210 if (sawEOS) { 211 break; 212 } 213 } 214} 215 216} // namespace android 217 218android::SoftOMXComponent *createSoftOMXComponent( 219 const char *name, const OMX_CALLBACKTYPE *callbacks, 220 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 221 return new android::SoftRaw(name, callbacks, appData, component); 222} 223