diff options
Diffstat (limited to 'media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp')
-rw-r--r-- | media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp deleted file mode 100644 index ac88107..0000000 --- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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 <utils/Log.h> - -#include "SoftVorbis.h" - -#include <media/stagefright/foundation/ADebug.h> -#include <media/stagefright/MediaDefs.h> - -extern "C" { - #include <Tremolo/codec_internal.h> - - 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<class T> -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<char *>(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<char *>("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<BufferInfo *> &inQueue = getPortQueue(0); - List<BufferInfo *> &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) { - ALOGW("vorbis_dsp_synthesis returned %d", err); - } else { - numFrames = vorbis_dsp_pcmout( - mState, (int16_t *)outHeader->pBuffer, - kMaxNumSamplesPerBuffer); - - if (numFrames < 0) { - ALOGE("vorbis_dsp_pcmout returned %d", numFrames); - numFrames = 0; - } - } - - if (mNumFramesLeftOnPage >= 0) { - if (numFrames > mNumFramesLeftOnPage) { - ALOGV("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); -} |