From bbba88cb1bdc34705d1477208990a06904c022e7 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 11 May 2011 14:13:42 -0700 Subject: Squashed commit of the following: commit c80992e419ed567abef451042f09c4958534b90d Author: Andreas Huber Date: Wed May 11 14:00:07 2011 -0700 Support for the mp3 audio decoder as a software OMX component. Change-Id: I66e10c4d0be4c3aecdef1c21b15a2c7359ceb807 commit a358d0e1bf2a88897887445f42ccdda0f5f2f528 Author: Andreas Huber Date: Wed May 11 13:11:23 2011 -0700 Support for G.711 alaw and mulaw decoders as software OMX components Change-Id: Ia5c76c02cb83a9f94ce39a27b2251e5880218f03 commit 79088b9c9a5c8b8c97ea66cb4f90a2b0f0d34553 Author: Andreas Huber Date: Thu May 5 15:43:32 2011 -0700 Instead of using an RGB surface and conversion yuv420->rgb565 convert from OMX_COLOR_FormatYUV420Planar to HAL_PIXEL_FORMAT_YV12 instead. Change-Id: I8c4fc3c54c963f0d4ba6377f3c4ab4e0013152e5 related-to-bug: 4394005 commit 69469d3bd84425777b11b9fc938c5e0c61af26a7 Author: Andreas Huber Date: Tue May 10 15:46:42 2011 -0700 voip mustn't link against libstagefright.so Change-Id: I4d0ba9a8b9dc9380b792a1bd04bcda231964862c commit 2a9a9eeeeeb36ae3a9e680469c3016d509ff08c3 Author: Andreas Huber Date: Tue May 10 14:37:10 2011 -0700 Remove most non-OMX software decoders by default Change-Id: Ic56514bc1b56b8fa952e8c4a164ea7379ecb69d0 commit a4de62c37b335c318217765403a9fb282b20a216 Author: Andreas Huber Date: Mon May 9 16:50:02 2011 -0700 Conditionally build the old-style software decoders. Change-Id: I5de609e1d76c92d26d6eb81d1551462258f3f15f commit 5d8b039f9449dc3dad1e77c42c80cc0b54b0c846 Author: Andreas Huber Date: Mon May 9 16:13:12 2011 -0700 Support for MPEG4 and H.263 video decoders as soft OMX components. Change-Id: I5e3a4835afab89f98e3aa128d013628f5830eafe commit b25a1bfbeb0ff6e62e1cc694ce2599c91489c7d0 Author: Andreas Huber Date: Mon May 9 11:49:10 2011 -0700 Boost Soft OMX thread priority, fix timestamp handling in vorbis Soft OMX decoder. Change-Id: I68d26d4999f06fcc451d69e5303663fab0cba9e8 commit c0574362f8dc3319ce84d981097867062a698527 Author: Andreas Huber Date: Mon May 9 11:28:53 2011 -0700 Support for the AMR decoders (NB and WB) as Soft OMX components. Change-Id: Ia565f59833fb52653e23f26536e7e41fc329a754 commit 3e5575a8f0e27a490cb7bde77bd9456087837f08 Author: Andreas Huber Date: Wed May 4 13:41:25 2011 -0700 Signal an error if the aac decoder failed to initialize from codec specific data. Change-Id: I01da7831bdf722edd7d6dc5974486daa2cf2b209 related-to-bug: 4272179 commit f94aeaa9886e772ff4823e671ed237096649f4af Author: Andreas Huber Date: Tue May 3 13:07:38 2011 -0700 Software OMX nodes don't (yet?) support native_window mode. Change-Id: I7d9ca9164ef4abf66b573ca21dba12d672f8b12d commit eefdfabac8dc659e00daa56da69aea705c49cb67 Author: Andreas Huber Date: Tue May 3 12:57:16 2011 -0700 Fixing the OMX tests to refer to appropriate files from test content. Change-Id: I5b61c3498749bfb876abbd3946a5132356e3f6ff commit f31b7326aef14b6a1b7946520a9688f092e844d5 Author: Andreas Huber Date: Tue May 3 11:08:38 2011 -0700 Soft OMX components are now dynamiclly loaded/unloaded, not directly linked against. Change-Id: I1e2ecfbfab67a8869886f738eaf0c7b3c948b6d9 commit b7f0343879e4df06f0a1c9bfece24df557954e2f Author: Andreas Huber Date: Mon May 2 15:58:36 2011 -0700 Support for the AVC software decoder as an OMX component. Change-Id: I13c12df435ba4afbd968a9fc659f66b91c818bc2 commit 5bb9e616d6c8e1b13d531fe996b9a9affdfb2977 Author: Andreas Huber Date: Fri Apr 29 12:05:37 2011 -0700 Fix Vorbis OMX decoder's component role. Change-Id: I5e871e5e11b3f951c93590210e63fd7987c467b5 commit 089c91f2333062e196c7afd5fb0ca914878aa474 Author: Andreas Huber Date: Fri Apr 29 12:05:18 2011 -0700 Support vorbis_decoder OMX testing. Change-Id: I1985be178a12ae3f8768bc72067d9236238be170 commit 56e241fa36fc37219bc536b823bdc2ab82dc1fad Author: Andreas Huber Date: Fri Apr 29 12:01:46 2011 -0700 SoftVorbis OMX component now respects the number of valid frames per page. Change-Id: I82a117a064d9b083fc58a54ad900a987a763ef03 commit fcd618ec520c376fdb78f4cbb44b8d9f5d213e2b Author: Andreas Huber Date: Fri Apr 29 10:59:38 2011 -0700 Support for the vorbis audio decoder as a soft OMX component. Change-Id: Iaeb057e58ca306d3dce205c0445b74d5aefef492 commit d1fcc3203fc8003ad79c6e96b3a1fc4261743f16 Author: Andreas Huber Date: Fri Apr 29 10:07:50 2011 -0700 VPX decoder now properly resizes buffers after a port settings change. Change-Id: I110749a31b6cba087891d8e5dfe420830bdbf831 commit 35c7168243cb69849d88911144a2c7fdfed5c54e Author: Andreas Huber Date: Thu Apr 28 13:23:34 2011 -0700 Support for the VPX video decoder as a Software OMX component. Change-Id: Ic345add2d6d768d4af631160153f2e9b97fcea71 commit 923b2534b4211fc5405377b5190bfa6f2dd27f32 Author: Andreas Huber Date: Thu Apr 28 11:34:40 2011 -0700 Table-based registration of soft omx components. Change-Id: I7f45f0fa5b3a7950776e69c66349731f7674e937 commit 04a88f3edb2266a463da9c4481b80178be460902 Author: Andreas Huber Date: Thu Apr 28 11:22:31 2011 -0700 Apparently OMX_GetParameter is valid in any state other than OMX_StateInvalid OMX_SetParameter is still constrained to OMX_StateLoaded or a disabled port. Change-Id: I1032d7cf4011982d306aa369d4158a82830d26fb commit 9d70ca68445e7c40f5c9b2d12466e468f514de88 Author: Andreas Huber Date: Wed Apr 27 15:03:18 2011 -0700 Use the new soft OMX aac decoder for HTTP live playback. Change-Id: Ifbcfb732a9edb855cb46b49f6d0ac942170ee28f commit 213fe4a10ea93cce08e8622dc3908053f29878a1 Author: Andreas Huber Date: Tue Apr 12 16:39:45 2011 -0700 Foundation for supporting software decoders as OMX components Change-Id: I7fdab256563b35d1d090617abaea9a26b198d816 Change-Id: I83e9236beed4af985d10333c203f065df9e09a42 --- media/libstagefright/codecs/vorbis/dec/Android.mk | 27 +- .../codecs/vorbis/dec/SoftVorbis.cpp | 445 +++++++++++++++++++++ .../libstagefright/codecs/vorbis/dec/SoftVorbis.h | 78 ++++ 3 files changed, 549 insertions(+), 1 deletion(-) create mode 100644 media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp create mode 100644 media/libstagefright/codecs/vorbis/dec/SoftVorbis.h (limited to 'media/libstagefright/codecs/vorbis/dec') diff --git a/media/libstagefright/codecs/vorbis/dec/Android.mk b/media/libstagefright/codecs/vorbis/dec/Android.mk index 5c768c8..06f0079 100644 --- a/media/libstagefright/codecs/vorbis/dec/Android.mk +++ b/media/libstagefright/codecs/vorbis/dec/Android.mk @@ -6,8 +6,33 @@ LOCAL_SRC_FILES := \ LOCAL_C_INCLUDES := \ frameworks/base/media/libstagefright/include \ - external/tremolo + external/tremolo \ LOCAL_MODULE := libstagefright_vorbisdec include $(BUILD_STATIC_LIBRARY) + +################################################################################ + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SoftVorbis.cpp + +LOCAL_C_INCLUDES := \ + external/tremolo \ + frameworks/base/media/libstagefright/include \ + frameworks/base/include/media/stagefright/openmax \ + +LOCAL_STATIC_LIBRARIES := \ + libstagefright_vorbisdec + +LOCAL_SHARED_LIBRARIES := \ + libvorbisidec libstagefright libstagefright_omx \ + libstagefright_foundation libutils + +LOCAL_MODULE := libstagefright_soft_vorbisdec +LOCAL_MODULE_TAGS := eng + +include $(BUILD_SHARED_LIBRARY) + diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp new file mode 100644 index 0000000..4091111 --- /dev/null +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SoftVorbis" +#include + +#include "SoftVorbis.h" + +#include +#include + +extern "C" { + #include + + int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb); + int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb); + int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb); +} + +namespace android { + +template +static void InitOMXParams(T *params) { + params->nSize = sizeof(T); + params->nVersion.s.nVersionMajor = 1; + params->nVersion.s.nVersionMinor = 0; + params->nVersion.s.nRevision = 0; + params->nVersion.s.nStep = 0; +} + +SoftVorbis::SoftVorbis( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) + : SimpleSoftOMXComponent(name, callbacks, appData, component), + mInputBufferCount(0), + mState(NULL), + mVi(NULL), + mAnchorTimeUs(0), + mNumFramesOutput(0), + mNumFramesLeftOnPage(-1), + mOutputPortSettingsChange(NONE) { + initPorts(); + CHECK_EQ(initDecoder(), (status_t)OK); +} + +SoftVorbis::~SoftVorbis() { + if (mState != NULL) { + vorbis_dsp_clear(mState); + delete mState; + mState = NULL; + } + + if (mVi != NULL) { + vorbis_info_clear(mVi); + delete mVi; + mVi = NULL; + } +} + +void SoftVorbis::initPorts() { + OMX_PARAM_PORTDEFINITIONTYPE def; + InitOMXParams(&def); + + def.nPortIndex = 0; + def.eDir = OMX_DirInput; + def.nBufferCountMin = kNumBuffers; + def.nBufferCountActual = def.nBufferCountMin; + def.nBufferSize = 8192; + def.bEnabled = OMX_TRUE; + def.bPopulated = OMX_FALSE; + def.eDomain = OMX_PortDomainAudio; + def.bBuffersContiguous = OMX_FALSE; + def.nBufferAlignment = 1; + + def.format.audio.cMIMEType = + const_cast(MEDIA_MIMETYPE_AUDIO_VORBIS); + + def.format.audio.pNativeRender = NULL; + def.format.audio.bFlagErrorConcealment = OMX_FALSE; + def.format.audio.eEncoding = OMX_AUDIO_CodingAAC; + + addPort(def); + + def.nPortIndex = 1; + def.eDir = OMX_DirOutput; + def.nBufferCountMin = kNumBuffers; + def.nBufferCountActual = def.nBufferCountMin; + def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t); + def.bEnabled = OMX_TRUE; + def.bPopulated = OMX_FALSE; + def.eDomain = OMX_PortDomainAudio; + def.bBuffersContiguous = OMX_FALSE; + def.nBufferAlignment = 2; + + def.format.audio.cMIMEType = const_cast("audio/raw"); + def.format.audio.pNativeRender = NULL; + def.format.audio.bFlagErrorConcealment = OMX_FALSE; + def.format.audio.eEncoding = OMX_AUDIO_CodingPCM; + + addPort(def); +} + +status_t SoftVorbis::initDecoder() { + return OK; +} + +OMX_ERRORTYPE SoftVorbis::internalGetParameter( + OMX_INDEXTYPE index, OMX_PTR params) { + switch (index) { + case OMX_IndexParamAudioVorbis: + { + OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = + (OMX_AUDIO_PARAM_VORBISTYPE *)params; + + if (vorbisParams->nPortIndex != 0) { + return OMX_ErrorUndefined; + } + + vorbisParams->nBitRate = 0; + vorbisParams->nMinBitRate = 0; + vorbisParams->nMaxBitRate = 0; + vorbisParams->nAudioBandWidth = 0; + vorbisParams->nQuality = 3; + vorbisParams->bManaged = OMX_FALSE; + vorbisParams->bDownmix = OMX_FALSE; + + if (!isConfigured()) { + vorbisParams->nChannels = 1; + vorbisParams->nSampleRate = 44100; + } else { + vorbisParams->nChannels = mVi->channels; + vorbisParams->nSampleRate = mVi->rate; + vorbisParams->nBitRate = mVi->bitrate_nominal; + vorbisParams->nMinBitRate = mVi->bitrate_lower; + vorbisParams->nMaxBitRate = mVi->bitrate_upper; + } + + return OMX_ErrorNone; + } + + case OMX_IndexParamAudioPcm: + { + OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams = + (OMX_AUDIO_PARAM_PCMMODETYPE *)params; + + if (pcmParams->nPortIndex != 1) { + return OMX_ErrorUndefined; + } + + pcmParams->eNumData = OMX_NumericalDataSigned; + pcmParams->eEndian = OMX_EndianBig; + pcmParams->bInterleaved = OMX_TRUE; + pcmParams->nBitPerSample = 16; + pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear; + pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF; + pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF; + + if (!isConfigured()) { + pcmParams->nChannels = 1; + pcmParams->nSamplingRate = 44100; + } else { + pcmParams->nChannels = mVi->channels; + pcmParams->nSamplingRate = mVi->rate; + } + + return OMX_ErrorNone; + } + + default: + return SimpleSoftOMXComponent::internalGetParameter(index, params); + } +} + +OMX_ERRORTYPE SoftVorbis::internalSetParameter( + OMX_INDEXTYPE index, const OMX_PTR params) { + switch (index) { + case OMX_IndexParamStandardComponentRole: + { + const OMX_PARAM_COMPONENTROLETYPE *roleParams = + (const OMX_PARAM_COMPONENTROLETYPE *)params; + + if (strncmp((const char *)roleParams->cRole, + "audio_decoder.vorbis", + OMX_MAX_STRINGNAME_SIZE - 1)) { + return OMX_ErrorUndefined; + } + + return OMX_ErrorNone; + } + + case OMX_IndexParamAudioVorbis: + { + const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams = + (const OMX_AUDIO_PARAM_VORBISTYPE *)params; + + if (vorbisParams->nPortIndex != 0) { + return OMX_ErrorUndefined; + } + + return OMX_ErrorNone; + } + + default: + return SimpleSoftOMXComponent::internalSetParameter(index, params); + } +} + +bool SoftVorbis::isConfigured() const { + return mInputBufferCount >= 2; +} + +static void makeBitReader( + const void *data, size_t size, + ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) { + buf->data = (uint8_t *)data; + buf->size = size; + buf->refcount = 1; + buf->ptr.owner = NULL; + + ref->buffer = buf; + ref->begin = 0; + ref->length = size; + ref->next = NULL; + + oggpack_readinit(bits, ref); +} + +void SoftVorbis::onQueueFilled(OMX_U32 portIndex) { + List &inQueue = getPortQueue(0); + List &outQueue = getPortQueue(1); + + if (mOutputPortSettingsChange != NONE) { + return; + } + + if (portIndex == 0 && mInputBufferCount < 2) { + BufferInfo *info = *inQueue.begin(); + OMX_BUFFERHEADERTYPE *header = info->mHeader; + + const uint8_t *data = header->pBuffer + header->nOffset; + size_t size = header->nFilledLen; + + ogg_buffer buf; + ogg_reference ref; + oggpack_buffer bits; + + makeBitReader( + (const uint8_t *)data + 7, size - 7, + &buf, &ref, &bits); + + if (mInputBufferCount == 0) { + CHECK(mVi == NULL); + mVi = new vorbis_info; + vorbis_info_init(mVi); + + CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits)); + } else { + CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits)); + + CHECK(mState == NULL); + mState = new vorbis_dsp_state; + CHECK_EQ(0, vorbis_dsp_init(mState, mVi)); + + notify(OMX_EventPortSettingsChanged, 1, 0, NULL); + mOutputPortSettingsChange = AWAITING_DISABLED; + } + + inQueue.erase(inQueue.begin()); + info->mOwnedByUs = false; + notifyEmptyBufferDone(header); + + ++mInputBufferCount; + + return; + } + + while (!inQueue.empty() && !outQueue.empty()) { + BufferInfo *inInfo = *inQueue.begin(); + OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; + + BufferInfo *outInfo = *outQueue.begin(); + OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; + + if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { + inQueue.erase(inQueue.begin()); + inInfo->mOwnedByUs = false; + notifyEmptyBufferDone(inHeader); + + outHeader->nFilledLen = 0; + outHeader->nFlags = OMX_BUFFERFLAG_EOS; + + outQueue.erase(outQueue.begin()); + outInfo->mOwnedByUs = false; + notifyFillBufferDone(outHeader); + return; + } + + int32_t numPageSamples; + CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples)); + memcpy(&numPageSamples, + inHeader->pBuffer + + inHeader->nOffset + inHeader->nFilledLen - 4, + sizeof(numPageSamples)); + + if (numPageSamples >= 0) { + mNumFramesLeftOnPage = numPageSamples; + } + + if (inHeader->nOffset == 0) { + mAnchorTimeUs = inHeader->nTimeStamp; + mNumFramesOutput = 0; + } + + inHeader->nFilledLen -= sizeof(numPageSamples);; + + ogg_buffer buf; + buf.data = inHeader->pBuffer + inHeader->nOffset; + buf.size = inHeader->nFilledLen; + buf.refcount = 1; + buf.ptr.owner = NULL; + + ogg_reference ref; + ref.buffer = &buf; + ref.begin = 0; + ref.length = buf.size; + ref.next = NULL; + + ogg_packet pack; + pack.packet = &ref; + pack.bytes = ref.length; + pack.b_o_s = 0; + pack.e_o_s = 0; + pack.granulepos = 0; + pack.packetno = 0; + + int numFrames = 0; + + int err = vorbis_dsp_synthesis(mState, &pack, 1); + if (err != 0) { + LOGW("vorbis_dsp_synthesis returned %d", err); + } else { + numFrames = vorbis_dsp_pcmout( + mState, (int16_t *)outHeader->pBuffer, + kMaxNumSamplesPerBuffer); + + if (numFrames < 0) { + LOGE("vorbis_dsp_pcmout returned %d", numFrames); + numFrames = 0; + } + } + + if (mNumFramesLeftOnPage >= 0) { + if (numFrames > mNumFramesLeftOnPage) { + LOGV("discarding %d frames at end of page", + numFrames - mNumFramesLeftOnPage); + numFrames = mNumFramesLeftOnPage; + } + mNumFramesLeftOnPage -= numFrames; + } + + outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels; + outHeader->nOffset = 0; + outHeader->nFlags = 0; + + outHeader->nTimeStamp = + mAnchorTimeUs + + (mNumFramesOutput * 1000000ll) / mVi->rate; + + mNumFramesOutput += numFrames; + + inInfo->mOwnedByUs = false; + inQueue.erase(inQueue.begin()); + inInfo = NULL; + notifyEmptyBufferDone(inHeader); + inHeader = NULL; + + outInfo->mOwnedByUs = false; + outQueue.erase(outQueue.begin()); + outInfo = NULL; + notifyFillBufferDone(outHeader); + outHeader = NULL; + + ++mInputBufferCount; + } +} + +void SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) { + if (portIndex == 0 && mState != NULL) { + // Make sure that the next buffer output does not still + // depend on fragments from the last one decoded. + + mNumFramesOutput = 0; + vorbis_dsp_restart(mState); + } +} + +void SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { + if (portIndex != 1) { + return; + } + + switch (mOutputPortSettingsChange) { + case NONE: + break; + + case AWAITING_DISABLED: + { + CHECK(!enabled); + mOutputPortSettingsChange = AWAITING_ENABLED; + break; + } + + default: + { + CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); + CHECK(enabled); + mOutputPortSettingsChange = NONE; + break; + } + } +} + +} // namespace android + +android::SoftOMXComponent *createSoftOMXComponent( + const char *name, const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, OMX_COMPONENTTYPE **component) { + return new android::SoftVorbis(name, callbacks, appData, component); +} diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h new file mode 100644 index 0000000..e252f55 --- /dev/null +++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFT_VORBIS_H_ + +#define SOFT_VORBIS_H_ + +#include "SimpleSoftOMXComponent.h" + +struct vorbis_dsp_state; +struct vorbis_info; + +namespace android { + +struct SoftVorbis : public SimpleSoftOMXComponent { + SoftVorbis(const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component); + +protected: + virtual ~SoftVorbis(); + + virtual OMX_ERRORTYPE internalGetParameter( + OMX_INDEXTYPE index, OMX_PTR params); + + virtual OMX_ERRORTYPE internalSetParameter( + OMX_INDEXTYPE index, const OMX_PTR params); + + virtual void onQueueFilled(OMX_U32 portIndex); + virtual void onPortFlushCompleted(OMX_U32 portIndex); + virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled); + +private: + enum { + kNumBuffers = 4, + kMaxNumSamplesPerBuffer = 8192 * 2 + }; + + size_t mInputBufferCount; + + vorbis_dsp_state *mState; + vorbis_info *mVi; + + int64_t mAnchorTimeUs; + int64_t mNumFramesOutput; + int32_t mNumFramesLeftOnPage; + + enum { + NONE, + AWAITING_DISABLED, + AWAITING_ENABLED + } mOutputPortSettingsChange; + + void initPorts(); + status_t initDecoder(); + bool isConfigured() const; + + DISALLOW_EVIL_CONSTRUCTORS(SoftVorbis); +}; + +} // namespace android + +#endif // SOFT_VORBIS_H_ + -- cgit v1.1