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),
57c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen      mSawInputEos(false),
58c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen      mSignalledOutputEos(false),
59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mOutputPortSettingsChange(NONE) {
60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    initPorts();
61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVorbis::~SoftVorbis() {
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mState != NULL) {
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_dsp_clear(mState);
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        delete mState;
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mState = NULL;
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mVi != NULL) {
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_info_clear(mVi);
73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        delete mVi;
74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mVi = NULL;
75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::initPorts() {
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    InitOMXParams(&def);
81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 0;
83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirInput;
84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumBuffers;
85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize = 8192;
87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainAudio;
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 1;
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.cMIMEType =
94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const_cast<char *>(MEDIA_MIMETYPE_AUDIO_VORBIS);
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.pNativeRender = NULL;
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
985c824472f7cec8a3634838f7d88ffa9ccc7fc8e6Martin Storsjo    def.format.audio.eEncoding = OMX_AUDIO_CodingVORBIS;
99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 1;
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirOutput;
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumBuffers;
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainAudio;
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 2;
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.pNativeRender = NULL;
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftVorbis::initDecoder() {
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return OK;
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalGetParameter(
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioVorbis:
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_AUDIO_PARAM_VORBISTYPE *)params;
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (vorbisParams->nPortIndex != 0) {
134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nBitRate = 0;
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nMinBitRate = 0;
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nMaxBitRate = 0;
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nAudioBandWidth = 0;
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nQuality = 3;
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->bManaged = OMX_FALSE;
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->bDownmix = OMX_FALSE;
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!isConfigured()) {
146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nChannels = 1;
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nSampleRate = 44100;
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nChannels = mVi->channels;
150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nSampleRate = mVi->rate;
151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nBitRate = mVi->bitrate_nominal;
152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nMinBitRate = mVi->bitrate_lower;
153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nMaxBitRate = mVi->bitrate_upper;
154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioPcm:
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (pcmParams->nPortIndex != 1) {
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eNumData = OMX_NumericalDataSigned;
169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eEndian = OMX_EndianBig;
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->bInterleaved = OMX_TRUE;
171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->nBitPerSample = 16;
172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!isConfigured()) {
177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nChannels = 1;
178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nSamplingRate = 44100;
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nChannels = mVi->channels;
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nSamplingRate = mVi->rate;
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalGetParameter(index, params);
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalSetParameter(
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamStandardComponentRole:
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_PARAM_COMPONENTROLETYPE *)params;
199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (strncmp((const char *)roleParams->cRole,
201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        "audio_decoder.vorbis",
202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        OMX_MAX_STRINGNAME_SIZE - 1)) {
203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioVorbis:
210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_AUDIO_PARAM_VORBISTYPE *)params;
213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (vorbisParams->nPortIndex != 0) {
215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalSetParameter(index, params);
223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftVorbis::isConfigured() const {
227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return mInputBufferCount >= 2;
228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void makeBitReader(
231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const void *data, size_t size,
232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->data = (uint8_t *)data;
234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->size = size;
235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->refcount = 1;
236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->ptr.owner = NULL;
237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->buffer = buf;
239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->begin = 0;
240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->length = size;
241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->next = NULL;
242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    oggpack_readinit(bits, ref);
244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mOutputPortSettingsChange != NONE) {
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mInputBufferCount < 2) {
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *info = *inQueue.begin();
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *header = info->mHeader;
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const uint8_t *data = header->pBuffer + header->nOffset;
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        size_t size = header->nFilledLen;
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer buf;
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_reference ref;
263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        oggpack_buffer bits;
264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        makeBitReader(
266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const uint8_t *)data + 7, size - 7,
267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                &buf, &ref, &bits);
268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mInputBufferCount == 0) {
270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(mVi == NULL);
271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mVi = new vorbis_info;
272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbis_info_init(mVi);
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ(0, _vorbis_unpack_info(mVi, &bits));
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        } else {
276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ(0, _vorbis_unpack_books(mVi, &bits));
277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(mState == NULL);
279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mState = new vorbis_dsp_state;
280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_DISABLED;
284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        inQueue.erase(inQueue.begin());
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        info->mOwnedByUs = false;
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyEmptyBufferDone(header);
289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
295c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
296c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        BufferInfo *inInfo = NULL;
297c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        OMX_BUFFERHEADERTYPE *inHeader = NULL;
298c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (!inQueue.empty()) {
299c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo = *inQueue.begin();
300c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inHeader = inInfo->mHeader;
301c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        }
302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *outInfo = *outQueue.begin();
304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
306c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        int32_t numPageSamples = 0;
307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
308c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (inHeader) {
309c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
310c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                mSawInputEos = true;
311c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            }
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
313c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            if (inHeader->nFilledLen || !mSawInputEos) {
314c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
315c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                memcpy(&numPageSamples,
316c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                       inHeader->pBuffer
317c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                        + inHeader->nOffset + inHeader->nFilledLen - 4,
318c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                       sizeof(numPageSamples));
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
320c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                if (inHeader->nOffset == 0) {
321c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mAnchorTimeUs = inHeader->nTimeStamp;
322c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mNumFramesOutput = 0;
323c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                }
324b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent
325c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                inHeader->nFilledLen -= sizeof(numPageSamples);;
326c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            }
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
329c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (numPageSamples >= 0) {
330c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            mNumFramesLeftOnPage = numPageSamples;
331b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent        }
332b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent
333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer buf;
334c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL;
335c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        buf.size = inHeader ? inHeader->nFilledLen : 0;
336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        buf.refcount = 1;
337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        buf.ptr.owner = NULL;
338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_reference ref;
340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.buffer = &buf;
341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.begin = 0;
342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.length = buf.size;
343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.next = NULL;
344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_packet pack;
346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.packet = &ref;
347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.bytes = ref.length;
348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.b_o_s = 0;
349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.e_o_s = 0;
350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.granulepos = 0;
351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.packetno = 0;
352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int numFrames = 0;
354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
355c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        outHeader->nFlags = 0;
356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int err = vorbis_dsp_synthesis(mState, &pack, 1);
357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (err != 0) {
35883f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten            // FIXME temporary workaround for log spam
35983f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#if !defined(__arm__) && !defined(__aarch64__)
36083f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten            ALOGV("vorbis_dsp_synthesis returned %d", err);
36183f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#else
3625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("vorbis_dsp_synthesis returned %d", err);
36383f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#endif
364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        } else {
365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            numFrames = vorbis_dsp_pcmout(
366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mState, (int16_t *)outHeader->pBuffer,
367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    kMaxNumSamplesPerBuffer);
368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (numFrames < 0) {
37029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("vorbis_dsp_pcmout returned %d", numFrames);
371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                numFrames = 0;
372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mNumFramesLeftOnPage >= 0) {
376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (numFrames > mNumFramesLeftOnPage) {
3773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("discarding %d frames at end of page",
378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                     numFrames - mNumFramesLeftOnPage);
379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                numFrames = mNumFramesLeftOnPage;
380c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                if (mSawInputEos) {
381c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
382c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mSignalledOutputEos = true;
383c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                }
384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mNumFramesLeftOnPage -= numFrames;
386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels;
389bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nOffset = 0;
390bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
391bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nTimeStamp =
392bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mAnchorTimeUs
393bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                + (mNumFramesOutput * 1000000ll) / mVi->rate;
394bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
395bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mNumFramesOutput += numFrames;
396bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
397c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (inHeader) {
398c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo->mOwnedByUs = false;
399c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inQueue.erase(inQueue.begin());
400c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo = NULL;
401c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            notifyEmptyBufferDone(inHeader);
402c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inHeader = NULL;
403c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        }
404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
405bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo->mOwnedByUs = false;
406bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outQueue.erase(outQueue.begin());
407bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo = NULL;
408bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyFillBufferDone(outHeader);
409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader = NULL;
410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
415bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) {
416bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mState != NULL) {
417bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        // Make sure that the next buffer output does not still
418bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        // depend on fragments from the last one decoded.
419bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
420bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mNumFramesOutput = 0;
421bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_dsp_restart(mState);
422bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
4256fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissenvoid SoftVorbis::onReset() {
42694b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    mInputBufferCount = 0;
4276fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen    mNumFramesOutput = 0;
42894b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    if (mState != NULL) {
42994b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        vorbis_dsp_clear(mState);
43094b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        delete mState;
43194b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        mState = NULL;
43294b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    }
43394b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen
43494b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    if (mVi != NULL) {
43594b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        vorbis_info_clear(mVi);
43694b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        delete mVi;
43794b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        mVi = NULL;
43894b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    }
439d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber
440c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    mSawInputEos = false;
441c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    mSignalledOutputEos = false;
442d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber    mOutputPortSettingsChange = NONE;
4436fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen}
4446fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen
445bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
446bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex != 1) {
447bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
448bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
449bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
450bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (mOutputPortSettingsChange) {
451bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case NONE:
452bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
453bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
454bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case AWAITING_DISABLED:
455bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
456bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(!enabled);
457bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_ENABLED;
458bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
459bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
460bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
461bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
462bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
463bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
464bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(enabled);
465bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = NONE;
466bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
467bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
468bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
469bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
470bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
471bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}  // namespace android
472bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
473bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
474bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
475bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
476bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return new android::SoftVorbis(name, callbacks, appData, component);
477bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
478