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),
591277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen      mSignalledError(false),
60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mOutputPortSettingsChange(NONE) {
61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    initPorts();
62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVorbis::~SoftVorbis() {
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mState != NULL) {
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_dsp_clear(mState);
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        delete mState;
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mState = NULL;
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mVi != NULL) {
73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_info_clear(mVi);
74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        delete mVi;
75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mVi = NULL;
76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::initPorts() {
80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    InitOMXParams(&def);
82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 0;
84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirInput;
85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumBuffers;
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
87e609fce7eb89da7a7445460493564cef724a7a3fRobert Shih    def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainAudio;
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 1;
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.cMIMEType =
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const_cast<char *>(MEDIA_MIMETYPE_AUDIO_VORBIS);
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.pNativeRender = NULL;
98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
995c824472f7cec8a3634838f7d88ffa9ccc7fc8e6Martin Storsjo    def.format.audio.eEncoding = OMX_AUDIO_CodingVORBIS;
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 1;
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirOutput;
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumBuffers;
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize = kMaxNumSamplesPerBuffer * sizeof(int16_t);
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainAudio;
111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 2;
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.pNativeRender = NULL;
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.bFlagErrorConcealment = OMX_FALSE;
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftVorbis::initDecoder() {
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return OK;
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalGetParameter(
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioVorbis:
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_AUDIO_PARAM_VORBISTYPE *)params;
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
1342720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vorbisParams)) {
1352720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
1362720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
1372720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (vorbisParams->nPortIndex != 0) {
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nBitRate = 0;
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nMinBitRate = 0;
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nMaxBitRate = 0;
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nAudioBandWidth = 0;
146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->nQuality = 3;
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->bManaged = OMX_FALSE;
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbisParams->bDownmix = OMX_FALSE;
149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!isConfigured()) {
151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nChannels = 1;
152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nSampleRate = 44100;
153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nChannels = mVi->channels;
155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nSampleRate = mVi->rate;
156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nBitRate = mVi->bitrate_nominal;
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nMinBitRate = mVi->bitrate_lower;
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vorbisParams->nMaxBitRate = mVi->bitrate_upper;
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioPcm:
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
1692720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(pcmParams)) {
1702720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
1712720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
1722720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (pcmParams->nPortIndex != 1) {
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eNumData = OMX_NumericalDataSigned;
178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eEndian = OMX_EndianBig;
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->bInterleaved = OMX_TRUE;
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->nBitPerSample = 16;
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!isConfigured()) {
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nChannels = 1;
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nSamplingRate = 44100;
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nChannels = mVi->channels;
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                pcmParams->nSamplingRate = mVi->rate;
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalGetParameter(index, params);
198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
201bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVorbis::internalSetParameter(
202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamStandardComponentRole:
205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_PARAM_COMPONENTROLETYPE *)params;
208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2092720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(roleParams)) {
2102720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
2112720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
2122720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (strncmp((const char *)roleParams->cRole,
214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        "audio_decoder.vorbis",
215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        OMX_MAX_STRINGNAME_SIZE - 1)) {
216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamAudioVorbis:
223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_AUDIO_PARAM_VORBISTYPE *vorbisParams =
225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_AUDIO_PARAM_VORBISTYPE *)params;
226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2272720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            if (!isValidOMXParam(vorbisParams)) {
2282720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen                return OMX_ErrorBadParameter;
2292720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen            }
2302720c8b094cfa58de314daa8e5e4fb4fa81fe3b2Marco Nelissen
231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (vorbisParams->nPortIndex != 0) {
232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalSetParameter(index, params);
240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftVorbis::isConfigured() const {
244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return mInputBufferCount >= 2;
245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void makeBitReader(
248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const void *data, size_t size,
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer *buf, ogg_reference *ref, oggpack_buffer *bits) {
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->data = (uint8_t *)data;
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->size = size;
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->refcount = 1;
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    buf->ptr.owner = NULL;
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->buffer = buf;
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->begin = 0;
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->length = size;
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    ref->next = NULL;
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    oggpack_readinit(bits, ref);
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2671277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen    if (mSignalledError || mOutputPortSettingsChange != NONE) {
268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mInputBufferCount < 2) {
272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *info = *inQueue.begin();
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *header = info->mHeader;
274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const uint8_t *data = header->pBuffer + header->nOffset;
276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        size_t size = header->nFilledLen;
277e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim        if (size < 7) {
278e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            ALOGE("Too small input buffer: %zu bytes", size);
279ff64ea33382081f46d4b1061df00298bbbe3dd65Wonsik Kim            android_errorWriteLog(0x534e4554, "27833616");
280e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
281e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            mSignalledError = true;
282e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            return;
283e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim        }
284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer buf;
286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_reference ref;
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        oggpack_buffer bits;
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        makeBitReader(
290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const uint8_t *)data + 7, size - 7,
291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                &buf, &ref, &bits);
292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mInputBufferCount == 0) {
294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(mVi == NULL);
295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mVi = new vorbis_info;
296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vorbis_info_init(mVi);
297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2981277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            int ret = _vorbis_unpack_info(mVi, &bits);
2991277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            if (ret != 0) {
3001277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
3011277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                mSignalledError = true;
3021277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                return;
3031277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            }
304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        } else {
3051277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            int ret = _vorbis_unpack_books(mVi, &bits);
3061277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            if (ret != 0) {
3071277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                notify(OMX_EventError, OMX_ErrorUndefined, ret, NULL);
3081277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                mSignalledError = true;
3091277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen                return;
3101277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen            }
311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(mState == NULL);
313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mState = new vorbis_dsp_state;
314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ(0, vorbis_dsp_init(mState, mVi));
315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_DISABLED;
318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        inQueue.erase(inQueue.begin());
321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        info->mOwnedByUs = false;
322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyEmptyBufferDone(header);
323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
329c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
330c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        BufferInfo *inInfo = NULL;
331c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        OMX_BUFFERHEADERTYPE *inHeader = NULL;
332c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (!inQueue.empty()) {
333c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo = *inQueue.begin();
334c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inHeader = inInfo->mHeader;
335c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        }
336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *outInfo = *outQueue.begin();
338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
340c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        int32_t numPageSamples = 0;
341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
342c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (inHeader) {
343c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
344c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                mSawInputEos = true;
345c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            }
346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
347c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            if (inHeader->nFilledLen || !mSawInputEos) {
348b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                if (inHeader->nFilledLen < sizeof(numPageSamples)) {
349b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                    notify(OMX_EventError, OMX_ErrorBadParameter, 0, NULL);
350b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                    mSignalledError = true;
351b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                    ALOGE("onQueueFilled, input header has nFilledLen %u, expected %zu",
352b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                            inHeader->nFilledLen, sizeof(numPageSamples));
353b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                    return;
354b5ce7ae2857d0ab1767244b9f212f5f3799f5abaWei Jia                }
355c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                memcpy(&numPageSamples,
356c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                       inHeader->pBuffer
357c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                        + inHeader->nOffset + inHeader->nFilledLen - 4,
358c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                       sizeof(numPageSamples));
359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
360c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                if (inHeader->nOffset == 0) {
361c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mAnchorTimeUs = inHeader->nTimeStamp;
362c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mNumFramesOutput = 0;
363c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                }
364b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent
365c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                inHeader->nFilledLen -= sizeof(numPageSamples);;
366c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            }
367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
369c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (numPageSamples >= 0) {
370c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            mNumFramesLeftOnPage = numPageSamples;
371b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent        }
372b6209a3d4c29bbb88de5a77546f4d545883cc484Eric Laurent
373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_buffer buf;
374c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL;
375c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        buf.size = inHeader ? inHeader->nFilledLen : 0;
376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        buf.refcount = 1;
377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        buf.ptr.owner = NULL;
378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_reference ref;
380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.buffer = &buf;
381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.begin = 0;
382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.length = buf.size;
383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ref.next = NULL;
384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ogg_packet pack;
386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.packet = &ref;
387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.bytes = ref.length;
388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.b_o_s = 0;
389bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.e_o_s = 0;
390bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.granulepos = 0;
391bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        pack.packetno = 0;
392bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
393bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int numFrames = 0;
394bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
395c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        outHeader->nFlags = 0;
396bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int err = vorbis_dsp_synthesis(mState, &pack, 1);
397bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (err != 0) {
39883f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten            // FIXME temporary workaround for log spam
39983f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#if !defined(__arm__) && !defined(__aarch64__)
40083f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten            ALOGV("vorbis_dsp_synthesis returned %d", err);
40183f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#else
4025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("vorbis_dsp_synthesis returned %d", err);
40383f052a749b8e0ee5df3467d8332d6140fcafb50Glenn Kasten#endif
404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        } else {
405e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            size_t numSamplesPerBuffer = kMaxNumSamplesPerBuffer;
406e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            if (numSamplesPerBuffer > outHeader->nAllocLen / sizeof(int16_t)) {
407e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim                numSamplesPerBuffer = outHeader->nAllocLen / sizeof(int16_t);
408ff64ea33382081f46d4b1061df00298bbbe3dd65Wonsik Kim                android_errorWriteLog(0x534e4554, "27833616");
409e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim            }
410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            numFrames = vorbis_dsp_pcmout(
411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mState, (int16_t *)outHeader->pBuffer,
412e6a2b5d7d2e9fa8db10ccb911d472c0fefa77557Wonsik Kim                    (numSamplesPerBuffer / mVi->channels));
413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (numFrames < 0) {
41529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("vorbis_dsp_pcmout returned %d", numFrames);
416bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                numFrames = 0;
417bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
418bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
419bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
420bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mNumFramesLeftOnPage >= 0) {
421bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (numFrames > mNumFramesLeftOnPage) {
4223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("discarding %d frames at end of page",
423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                     numFrames - mNumFramesLeftOnPage);
424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                numFrames = mNumFramesLeftOnPage;
425c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                if (mSawInputEos) {
426c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
427c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                    mSignalledOutputEos = true;
428c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen                }
429bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
430bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mNumFramesLeftOnPage -= numFrames;
431bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
432bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
433bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels;
434bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nOffset = 0;
435bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
436bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nTimeStamp =
437bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mAnchorTimeUs
438bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                + (mNumFramesOutput * 1000000ll) / mVi->rate;
439bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
440bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mNumFramesOutput += numFrames;
441bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
442c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        if (inHeader) {
443c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo->mOwnedByUs = false;
444c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inQueue.erase(inQueue.begin());
445c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inInfo = NULL;
446c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            notifyEmptyBufferDone(inHeader);
447c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen            inHeader = NULL;
448c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen        }
449bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
450bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo->mOwnedByUs = false;
451bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outQueue.erase(outQueue.begin());
452bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo = NULL;
453bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyFillBufferDone(outHeader);
454bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader = NULL;
455bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
456bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
457bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
458bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
459bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
460bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) {
461bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mState != NULL) {
462bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        // Make sure that the next buffer output does not still
463bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        // depend on fragments from the last one decoded.
464bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
465bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mNumFramesOutput = 0;
4663d827263f2f471d65f8b5c0ee57cae77f0f8f343Ronghua Wu        mSawInputEos = false;
4673d827263f2f471d65f8b5c0ee57cae77f0f8f343Ronghua Wu        mSignalledOutputEos = false;
4683d827263f2f471d65f8b5c0ee57cae77f0f8f343Ronghua Wu        mNumFramesLeftOnPage = -1;
469bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        vorbis_dsp_restart(mState);
470bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
471bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
472bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
4736fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissenvoid SoftVorbis::onReset() {
47494b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    mInputBufferCount = 0;
4756fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen    mNumFramesOutput = 0;
47694b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    if (mState != NULL) {
47794b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        vorbis_dsp_clear(mState);
47894b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        delete mState;
47994b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        mState = NULL;
48094b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    }
48194b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen
48294b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    if (mVi != NULL) {
48394b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        vorbis_info_clear(mVi);
48494b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        delete mVi;
48594b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen        mVi = NULL;
48694b66227ff5a57dd810aafa7b3aa810b9a185b8dMarco Nelissen    }
487d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber
488c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    mSawInputEos = false;
489c71a99131ca97bd3bdc5b78473d06e613e96e073Marco Nelissen    mSignalledOutputEos = false;
4901277aea8405ea3256a2b0f730506c4610cadafa4Marco Nelissen    mSignalledError = false;
491d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber    mOutputPortSettingsChange = NONE;
4926fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen}
4936fc72b01a3b67903b52f1d33b1ad5c960b5365f1Marco Nelissen
494bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVorbis::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
495bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex != 1) {
496bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
497bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
498bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
499bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (mOutputPortSettingsChange) {
500bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case NONE:
501bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
502bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
503bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case AWAITING_DISABLED:
504bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
505bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(!enabled);
506bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_ENABLED;
507bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
508bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
509bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
510bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
511bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
512bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
513bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(enabled);
514bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = NONE;
515bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
516bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
517bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
518bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
519bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
520bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}  // namespace android
521bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
522bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
523bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
524bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
525bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return new android::SoftVorbis(name, callbacks, appData, component);
526bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
527