SoftVorbis.cpp revision bbba88cb1bdc34705d1477208990a06904c022e7
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 "SoftVorbis" 19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <utils/Log.h> 20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftVorbis.h" 22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/MediaDefs.h> 25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberextern "C" { 27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber #include <Tremolo/codec_internal.h> 28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb); 30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb); 31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); 32bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 33bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 34bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android { 35bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 36bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T> 37bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) { 38bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nSize = sizeof(T); 39bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMajor = 1; 40bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMinor = 0; 41bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nRevision = 0; 42bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nStep = 0; 43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 45bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVorbis::SoftVorbis( 46bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, 47bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_CALLBACKTYPE *callbacks, 48bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, 49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_COMPONENTTYPE **component) 50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : SimpleSoftOMXComponent(name, callbacks, appData, component), 51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mInputBufferCount(0), 52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState(NULL), 53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mVi(NULL), 54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs(0), 55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesOutput(0), 56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesLeftOnPage(-1), 57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange(NONE) { 58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber initPorts(); 59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(initDecoder(), (status_t)OK); 60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 62bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVorbis::~SoftVorbis() { 63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mState != NULL) { 64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbis_dsp_clear(mState); 65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber delete mState; 66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState = NULL; 67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mVi != NULL) { 70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbis_info_clear(mVi); 71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber delete mVi; 72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mVi = NULL; 73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::initPorts() { 77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber InitOMXParams(&def); 79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 0; 81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirInput; 82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = 8192; 85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 1; 90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = 92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const_cast<char *>(MEDIA_MIMETYPE_AUDIO_VORBIS); 93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; 97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 1; 101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirOutput; 102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t); 105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainAudio; 108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 2; 110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.cMIMEType = const_cast<char *>("audio/raw"); 112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.pNativeRender = NULL; 113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.bFlagErrorConcealment = OMX_FALSE; 114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; 115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftVorbis::initDecoder() { 120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OK; 121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 123bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalGetParameter( 124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, OMX_PTR params) { 125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioVorbis: 127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = 129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_VORBISTYPE *)params; 130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (vorbisParams->nPortIndex != 0) { 132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nBitRate = 0; 136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nMinBitRate = 0; 137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nMaxBitRate = 0; 138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nAudioBandWidth = 0; 139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nQuality = 3; 140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->bManaged = OMX_FALSE; 141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->bDownmix = OMX_FALSE; 142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (!isConfigured()) { 144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nChannels = 1; 145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nSampleRate = 44100; 146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nChannels = mVi->channels; 148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nSampleRate = mVi->rate; 149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nBitRate = mVi->bitrate_nominal; 150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nMinBitRate = mVi->bitrate_lower; 151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbisParams->nMaxBitRate = mVi->bitrate_upper; 152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioPcm: 158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = 160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_AUDIO_PARAM_PCMMODETYPE *)params; 161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (pcmParams->nPortIndex != 1) { 163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eNumData = OMX_NumericalDataSigned; 167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eEndian = OMX_EndianBig; 168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->bInterleaved = OMX_TRUE; 169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nBitPerSample = 16; 170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; 171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; 172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; 173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (!isConfigured()) { 175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nChannels = 1; 176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nSamplingRate = 44100; 177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nChannels = mVi->channels; 179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pcmParams->nSamplingRate = mVi->rate; 180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalGetParameter(index, params); 187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 190bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalSetParameter( 191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, const OMX_PTR params) { 192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamStandardComponentRole: 194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_PARAM_COMPONENTROLETYPE *roleParams = 196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_PARAM_COMPONENTROLETYPE *)params; 197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "audio_decoder.vorbis", 200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamAudioVorbis: 208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = 210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_AUDIO_PARAM_VORBISTYPE *)params; 211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (vorbisParams->nPortIndex != 0) { 213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalSetParameter(index, params); 221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftVorbis::isConfigured() const { 225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return mInputBufferCount >= 2; 226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void makeBitReader( 229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const void *data, size_t size, 230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) { 231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf->data = (uint8_t *)data; 232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf->size = size; 233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf->refcount = 1; 234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf->ptr.owner = NULL; 235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref->buffer = buf; 237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref->begin = 0; 238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref->length = size; 239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref->next = NULL; 240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber oggpack_readinit(bits, ref); 242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onQueueFilled(OMX_U32 portIndex) { 245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &inQueue = getPortQueue(0); 246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &outQueue = getPortQueue(1); 247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mOutputPortSettingsChange != NONE) { 249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (portIndex == 0 && mInputBufferCount < 2) { 253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *info = *inQueue.begin(); 254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *header = info->mHeader; 255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const uint8_t *data = header->pBuffer + header->nOffset; 257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber size_t size = header->nFilledLen; 258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_buffer buf; 260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_reference ref; 261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber oggpack_buffer bits; 262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber makeBitReader( 264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const uint8_t *)data + 7, size - 7, 265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber &buf, &ref, &bits); 266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mInputBufferCount == 0) { 268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(mVi == NULL); 269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mVi = new vorbis_info; 270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbis_info_init(mVi); 271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits)); 273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits)); 275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(mState == NULL); 277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState = new vorbis_dsp_state; 278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(0, vorbis_dsp_init(mState, mVi)); 279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = AWAITING_DISABLED; 282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber info->mOwnedByUs = false; 286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(header); 287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ++mInputBufferCount; 289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (!inQueue.empty() && !outQueue.empty()) { 294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *inInfo = *inQueue.begin(); 295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *outInfo = *outQueue.begin(); 298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = 0; 306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_EOS; 307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t numPageSamples; 315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples)); 316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber memcpy(&numPageSamples, 317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->pBuffer 318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber + inHeader->nOffset + inHeader->nFilledLen - 4, 319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber sizeof(numPageSamples)); 320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (numPageSamples >= 0) { 322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesLeftOnPage = numPageSamples; 323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nOffset == 0) { 326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs = inHeader->nTimeStamp; 327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesOutput = 0; 328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->nFilledLen -= sizeof(numPageSamples);; 331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_buffer buf; 333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf.data = inHeader->pBuffer + inHeader->nOffset; 334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf.size = inHeader->nFilledLen; 335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf.refcount = 1; 336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber buf.ptr.owner = NULL; 337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_reference ref; 339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref.buffer = &buf; 340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref.begin = 0; 341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref.length = buf.size; 342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ref.next = NULL; 343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ogg_packet pack; 345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.packet = &ref; 346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.bytes = ref.length; 347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.b_o_s = 0; 348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.e_o_s = 0; 349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.granulepos = 0; 350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber pack.packetno = 0; 351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int numFrames = 0; 353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int err = vorbis_dsp_synthesis(mState, &pack, 1); 355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (err != 0) { 356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber LOGW("vorbis_dsp_synthesis returned %d", err); 357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numFrames = vorbis_dsp_pcmout( 359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mState, (int16_t *)outHeader->pBuffer, 360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber kMaxNumSamplesPerBuffer); 361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (numFrames < 0) { 363bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber LOGE("vorbis_dsp_pcmout returned %d", numFrames); 364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numFrames = 0; 365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mNumFramesLeftOnPage >= 0) { 369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (numFrames > mNumFramesLeftOnPage) { 370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber LOGV("discarding %d frames at end of page", 371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numFrames - mNumFramesLeftOnPage); 372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber numFrames = mNumFramesLeftOnPage; 373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesLeftOnPage -= numFrames; 375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels; 378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nOffset = 0; 379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = 0; 380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nTimeStamp = 382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mAnchorTimeUs 383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber + (mNumFramesOutput * 1000000ll) / mVi->rate; 384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesOutput += numFrames; 386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 389bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo = NULL; 390bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 391bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader = NULL; 392bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 393bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 394bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 395bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo = NULL; 396bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 397bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader = NULL; 398bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 399bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber ++mInputBufferCount; 400bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 401bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 402bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 403bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) { 404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (portIndex == 0 && mState != NULL) { 405bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber // Make sure that the next buffer output does not still 406bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber // depend on fragments from the last one decoded. 407bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 408bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mNumFramesOutput = 0; 409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vorbis_dsp_restart(mState); 410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::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::SoftVorbis(name, callbacks, appData, component); 445bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 446