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