1/* 2 * Copyright (C) 2011 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 "SoftMP3" 19#include <utils/Log.h> 20 21#include "SoftMP3.h" 22 23#include <media/stagefright/foundation/ADebug.h> 24#include <media/stagefright/MediaDefs.h> 25 26#include "include/pvmp3decoder_api.h" 27 28namespace android { 29 30template<class T> 31static void InitOMXParams(T *params) { 32 params->nSize = sizeof(T); 33 params->nVersion.s.nVersionMajor = 1; 34 params->nVersion.s.nVersionMinor = 0; 35 params->nVersion.s.nRevision = 0; 36 params->nVersion.s.nStep = 0; 37} 38 39SoftMP3::SoftMP3( 40 const char *name, 41 const OMX_CALLBACKTYPE *callbacks, 42 OMX_PTR appData, 43 OMX_COMPONENTTYPE **component) 44 : SimpleSoftOMXComponent(name, callbacks, appData, component), 45 mConfig(new tPVMP3DecoderExternal), 46 mDecoderBuf(NULL), 47 mAnchorTimeUs(0), 48 mNumFramesOutput(0), 49 mNumChannels(2), 50 mSamplingRate(44100), 51 mSignalledError(false), 52 mSawInputEos(false), 53 mSignalledOutputEos(false), 54 mOutputPortSettingsChange(NONE) { 55 initPorts(); 56 initDecoder(); 57} 58 59SoftMP3::~SoftMP3() { 60 if (mDecoderBuf != NULL) { 61 free(mDecoderBuf); 62 mDecoderBuf = NULL; 63 } 64 65 delete mConfig; 66 mConfig = NULL; 67} 68 69void SoftMP3::initPorts() { 70 OMX_PARAM_PORTDEFINITIONTYPE def; 71 InitOMXParams(&def); 72 73 def.nPortIndex = 0; 74 def.eDir = OMX_DirInput; 75 def.nBufferCountMin = kNumBuffers; 76 def.nBufferCountActual = def.nBufferCountMin; 77 def.nBufferSize = 8192; 78 def.bEnabled = OMX_TRUE; 79 def.bPopulated = OMX_FALSE; 80 def.eDomain = OMX_PortDomainAudio; 81 def.bBuffersContiguous = OMX_FALSE; 82 def.nBufferAlignment = 1; 83 84 def.format.audio.cMIMEType = 85 const_cast<char *>(MEDIA_MIMETYPE_AUDIO_MPEG); 86 87 def.format.audio.pNativeRender = NULL; 88 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 89 def.format.audio.eEncoding = OMX_AUDIO_CodingMP3; 90 91 addPort(def); 92 93 def.nPortIndex = 1; 94 def.eDir = OMX_DirOutput; 95 def.nBufferCountMin = kNumBuffers; 96 def.nBufferCountActual = def.nBufferCountMin; 97 def.nBufferSize = kOutputBufferSize; 98 def.bEnabled = OMX_TRUE; 99 def.bPopulated = OMX_FALSE; 100 def.eDomain = OMX_PortDomainAudio; 101 def.bBuffersContiguous = OMX_FALSE; 102 def.nBufferAlignment = 2; 103 104 def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 105 def.format.audio.pNativeRender = NULL; 106 def.format.audio.bFlagErrorConcealment = OMX_FALSE; 107 def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 108 109 addPort(def); 110} 111 112void SoftMP3::initDecoder() { 113 mConfig->equalizerType = flat; 114 mConfig->crcEnabled = false; 115 116 uint32_t memRequirements = pvmp3_decoderMemRequirements(); 117 mDecoderBuf = malloc(memRequirements); 118 119 pvmp3_InitDecoder(mConfig, mDecoderBuf); 120 mIsFirst = true; 121} 122 123OMX_ERRORTYPE SoftMP3::internalGetParameter( 124 OMX_INDEXTYPE index, OMX_PTR params) { 125 switch (index) { 126 case OMX_IndexParamAudioPcm: 127 { 128 OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 129 (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 130 131 if (pcmParams->nPortIndex > 1) { 132 return OMX_ErrorUndefined; 133 } 134 135 pcmParams->eNumData = OMX_NumericalDataSigned; 136 pcmParams->eEndian = OMX_EndianBig; 137 pcmParams->bInterleaved = OMX_TRUE; 138 pcmParams->nBitPerSample = 16; 139 pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 140 pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 141 pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 142 143 pcmParams->nChannels = mNumChannels; 144 pcmParams->nSamplingRate = mSamplingRate; 145 146 return OMX_ErrorNone; 147 } 148 149 case OMX_IndexParamAudioMp3: 150 { 151 OMX_AUDIO_PARAM_MP3TYPE *mp3Params = 152 (OMX_AUDIO_PARAM_MP3TYPE *)params; 153 154 if (mp3Params->nPortIndex > 1) { 155 return OMX_ErrorUndefined; 156 } 157 158 mp3Params->nChannels = mNumChannels; 159 mp3Params->nBitRate = 0 /* unknown */; 160 mp3Params->nSampleRate = mSamplingRate; 161 // other fields are encoder-only 162 163 return OMX_ErrorNone; 164 } 165 166 default: 167 return SimpleSoftOMXComponent::internalGetParameter(index, params); 168 } 169} 170 171OMX_ERRORTYPE SoftMP3::internalSetParameter( 172 OMX_INDEXTYPE index, const OMX_PTR params) { 173 switch (index) { 174 case OMX_IndexParamStandardComponentRole: 175 { 176 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 177 (const OMX_PARAM_COMPONENTROLETYPE *)params; 178 179 if (strncmp((const char *)roleParams->cRole, 180 "audio_decoder.mp3", 181 OMX_MAX_STRINGNAME_SIZE - 1)) { 182 return OMX_ErrorUndefined; 183 } 184 185 return OMX_ErrorNone; 186 } 187 188 case OMX_IndexParamAudioPcm: 189 { 190 const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 191 (const OMX_AUDIO_PARAM_PCMMODETYPE *)params; 192 193 if (pcmParams->nPortIndex != 1) { 194 return OMX_ErrorUndefined; 195 } 196 197 mNumChannels = pcmParams->nChannels; 198 mSamplingRate = pcmParams->nSamplingRate; 199 200 return OMX_ErrorNone; 201 } 202 203 default: 204 return SimpleSoftOMXComponent::internalSetParameter(index, params); 205 } 206} 207 208void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) { 209 if (mSignalledError || mOutputPortSettingsChange != NONE) { 210 return; 211 } 212 213 List<BufferInfo *> &inQueue = getPortQueue(0); 214 List<BufferInfo *> &outQueue = getPortQueue(1); 215 216 while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) { 217 BufferInfo *inInfo = NULL; 218 OMX_BUFFERHEADERTYPE *inHeader = NULL; 219 if (!inQueue.empty()) { 220 inInfo = *inQueue.begin(); 221 inHeader = inInfo->mHeader; 222 } 223 224 BufferInfo *outInfo = *outQueue.begin(); 225 OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 226 outHeader->nFlags = 0; 227 228 if (inHeader) { 229 if (inHeader->nOffset == 0 && inHeader->nFilledLen) { 230 mAnchorTimeUs = inHeader->nTimeStamp; 231 mNumFramesOutput = 0; 232 } 233 234 if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 235 mSawInputEos = true; 236 } 237 238 mConfig->pInputBuffer = 239 inHeader->pBuffer + inHeader->nOffset; 240 241 mConfig->inputBufferCurrentLength = inHeader->nFilledLen; 242 } else { 243 mConfig->pInputBuffer = NULL; 244 mConfig->inputBufferCurrentLength = 0; 245 } 246 mConfig->inputBufferMaxLength = 0; 247 mConfig->inputBufferUsedLength = 0; 248 249 mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t); 250 251 mConfig->pOutputBuffer = 252 reinterpret_cast<int16_t *>(outHeader->pBuffer); 253 254 ERROR_CODE decoderErr; 255 if ((decoderErr = pvmp3_framedecoder(mConfig, mDecoderBuf)) 256 != NO_DECODING_ERROR) { 257 ALOGV("mp3 decoder returned error %d", decoderErr); 258 259 if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR 260 && decoderErr != SIDE_INFO_ERROR) { 261 ALOGE("mp3 decoder returned error %d", decoderErr); 262 263 notify(OMX_EventError, OMX_ErrorUndefined, decoderErr, NULL); 264 mSignalledError = true; 265 return; 266 } 267 268 if (mConfig->outputFrameSize == 0) { 269 mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t); 270 } 271 272 if (decoderErr == NO_ENOUGH_MAIN_DATA_ERROR && mSawInputEos) { 273 if (!mIsFirst) { 274 // pad the end of the stream with 529 samples, since that many samples 275 // were trimmed off the beginning when decoding started 276 outHeader->nOffset = 0; 277 outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); 278 279 memset(outHeader->pBuffer, 0, outHeader->nFilledLen); 280 } 281 outHeader->nFlags = OMX_BUFFERFLAG_EOS; 282 mSignalledOutputEos = true; 283 } else { 284 // This is recoverable, just ignore the current frame and 285 // play silence instead. 286 287 // TODO: should we skip silence (and consume input data) 288 // if mIsFirst is true as we may not have a valid 289 // mConfig->samplingRate and mConfig->num_channels? 290 ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence"); 291 memset(outHeader->pBuffer, 292 0, 293 mConfig->outputFrameSize * sizeof(int16_t)); 294 295 if (inHeader) { 296 mConfig->inputBufferUsedLength = inHeader->nFilledLen; 297 } 298 } 299 } else if (mConfig->samplingRate != mSamplingRate 300 || mConfig->num_channels != mNumChannels) { 301 mSamplingRate = mConfig->samplingRate; 302 mNumChannels = mConfig->num_channels; 303 304 notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 305 mOutputPortSettingsChange = AWAITING_DISABLED; 306 return; 307 } 308 309 if (mIsFirst) { 310 mIsFirst = false; 311 // The decoder delay is 529 samples, so trim that many samples off 312 // the start of the first output buffer. This essentially makes this 313 // decoder have zero delay, which the rest of the pipeline assumes. 314 outHeader->nOffset = 315 kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t); 316 317 outHeader->nFilledLen = 318 mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset; 319 } else if (!mSignalledOutputEos) { 320 outHeader->nOffset = 0; 321 outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t); 322 } 323 324 outHeader->nTimeStamp = 325 mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate; 326 327 if (inHeader) { 328 CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength); 329 330 inHeader->nOffset += mConfig->inputBufferUsedLength; 331 inHeader->nFilledLen -= mConfig->inputBufferUsedLength; 332 333 334 if (inHeader->nFilledLen == 0) { 335 inInfo->mOwnedByUs = false; 336 inQueue.erase(inQueue.begin()); 337 inInfo = NULL; 338 notifyEmptyBufferDone(inHeader); 339 inHeader = NULL; 340 } 341 } 342 343 mNumFramesOutput += mConfig->outputFrameSize / mNumChannels; 344 345 outInfo->mOwnedByUs = false; 346 outQueue.erase(outQueue.begin()); 347 outInfo = NULL; 348 notifyFillBufferDone(outHeader); 349 outHeader = NULL; 350 } 351} 352 353void SoftMP3::onPortFlushCompleted(OMX_U32 portIndex) { 354 if (portIndex == 0) { 355 // Make sure that the next buffer output does not still 356 // depend on fragments from the last one decoded. 357 pvmp3_InitDecoder(mConfig, mDecoderBuf); 358 mIsFirst = true; 359 mSignalledError = false; 360 mSawInputEos = false; 361 mSignalledOutputEos = false; 362 } 363} 364 365void SoftMP3::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 366 if (portIndex != 1) { 367 return; 368 } 369 370 switch (mOutputPortSettingsChange) { 371 case NONE: 372 break; 373 374 case AWAITING_DISABLED: 375 { 376 CHECK(!enabled); 377 mOutputPortSettingsChange = AWAITING_ENABLED; 378 break; 379 } 380 381 default: 382 { 383 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 384 CHECK(enabled); 385 mOutputPortSettingsChange = NONE; 386 break; 387 } 388 } 389} 390 391void SoftMP3::onReset() { 392 pvmp3_InitDecoder(mConfig, mDecoderBuf); 393 mIsFirst = true; 394 mSignalledError = false; 395 mSawInputEos = false; 396 mSignalledOutputEos = false; 397 mOutputPortSettingsChange = NONE; 398} 399 400} // namespace android 401 402android::SoftOMXComponent *createSoftOMXComponent( 403 const char *name, const OMX_CALLBACKTYPE *callbacks, 404 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 405 return new android::SoftMP3(name, callbacks, appData, component); 406} 407