SoftMPEG4.cpp revision f2af5a2c607e71ff4cd39da28b077c0a68b206fe
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 "SoftMPEG4"
19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <utils/Log.h>
20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftMPEG4.h"
22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/MediaDefs.h>
25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/MediaErrors.h>
26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "mp4dec_api.h"
28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android {
30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T>
32bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) {
33bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nSize = sizeof(T);
34bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nVersionMajor = 1;
35bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nVersionMinor = 0;
36bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nRevision = 0;
37bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nStep = 0;
38bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
39bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
40bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftMPEG4::SoftMPEG4(
41bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name,
42bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const OMX_CALLBACKTYPE *callbacks,
43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData,
44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_COMPONENTTYPE **component)
45bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    : SimpleSoftOMXComponent(name, callbacks, appData, component),
46bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mMode(MODE_MPEG4),
47bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mHandle(new tagvideoDecControls),
48bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInputBufferCount(0),
49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mWidth(352),
50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mHeight(288),
51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropLeft(0),
52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropTop(0),
53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropRight(mWidth - 1),
54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropBottom(mHeight - 1),
55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mSignalledError(false),
56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInitialized(false),
57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mFramesConfigured(false),
58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mNumSamplesOutput(0),
59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mOutputPortSettingsChange(NONE) {
60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!strcmp(name, "OMX.google.h263.decoder")) {
61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mMode = MODE_H263;
62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    } else {
63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        CHECK(!strcmp(name, "OMX.google.mpeg4.decoder"));
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    initPorts();
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftMPEG4::~SoftMPEG4() {
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mInitialized) {
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PVCleanUpVideoDecoder(mHandle);
73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    delete mHandle;
76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mHandle = NULL;
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::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 = kNumInputBuffers;
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize = 8192;
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainVideo;
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 1;
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.cMIMEType =
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (mMode == MODE_MPEG4)
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ? const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG4)
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            : const_cast<char *>(MEDIA_MIMETYPE_VIDEO_H263);
98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeRender = NULL;
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameWidth = mWidth;
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameHeight = mHeight;
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nStride = def.format.video.nFrameWidth;
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nBitrate = 0;
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.xFramerate = 0;
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.bFlagErrorConcealment = OMX_FALSE;
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eCompressionFormat =
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mMode == MODE_MPEG4 ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeWindow = NULL;
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 1;
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirOutput;
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumOutputBuffers;
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainVideo;
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 2;
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeRender = NULL;
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameWidth = mWidth;
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameHeight = mHeight;
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nStride = def.format.video.nFrameWidth;
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nBitrate = 0;
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.xFramerate = 0;
134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.bFlagErrorConcealment = OMX_FALSE;
135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeWindow = NULL;
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize =
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftMPEG4::initDecoder() {
146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    memset(mHandle, 0, sizeof(tagvideoDecControls));
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return OK;
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
150bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::internalGetParameter(
151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamVideoPortFormat:
154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex > 1) {
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nIndex != 0) {
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorNoMore;
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex == 0) {
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eCompressionFormat =
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    (mMode == MODE_MPEG4)
169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->xFramerate = 0;
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                CHECK_EQ(formatParams->nPortIndex, 1u);
175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->xFramerate = 0;
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalGetParameter(index, params);
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::internalSetParameter(
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamStandardComponentRole:
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_PARAM_COMPONENTROLETYPE *)params;
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mMode == MODE_MPEG4) {
198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                if (strncmp((const char *)roleParams->cRole,
199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "video_decoder.mpeg4",
200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            OMX_MAX_STRINGNAME_SIZE - 1)) {
201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    return OMX_ErrorUndefined;
202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                }
203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                if (strncmp((const char *)roleParams->cRole,
205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "video_decoder.h263",
206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            OMX_MAX_STRINGNAME_SIZE - 1)) {
207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    return OMX_ErrorUndefined;
208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                }
209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamVideoPortFormat:
215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex > 1) {
220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nIndex != 0) {
224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorNoMore;
225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalSetParameter(index, params);
232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
235bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::getConfig(
236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexConfigCommonOutputCrop:
239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params;
241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (rectParams->nPortIndex != 1) {
243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nLeft = mCropLeft;
247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nTop = mCropTop;
248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nWidth = mCropRight - mCropLeft + 1;
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nHeight = mCropBottom - mCropTop + 1;
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorUnsupportedIndex;
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onQueueFilled(OMX_U32 portIndex) {
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mSignalledError || mOutputPortSettingsChange != NONE) {
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    while (!inQueue.empty() && outQueue.size() == kNumOutputBuffers) {
268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *inInfo = *inQueue.begin();
269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PortInfo *port = editPortInfo(1);
272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *outHeader =
274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            port->mBuffers.editItemAt(mNumSamplesOutput & 1).mHeader;
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inQueue.erase(inQueue.begin());
278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inInfo->mOwnedByUs = false;
279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyEmptyBufferDone(inHeader);
280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++mInputBufferCount;
282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFilledLen = 0;
284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            List<BufferInfo *>::iterator it = outQueue.begin();
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            while ((*it)->mHeader != outHeader) {
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                ++it;
289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            BufferInfo *outInfo = *it;
292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo->mOwnedByUs = false;
293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outQueue.erase(it);
294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo = NULL;
295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyFillBufferDone(outHeader);
297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader = NULL;
298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        uint8_t *bitstream = inHeader->pBuffer + inHeader->nOffset;
302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mInitialized) {
304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_data[0] = bitstream;
311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_size = inHeader->nFilledLen;
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode mode =
315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (mMode == MODE_MPEG4) ? MPEG4_MODE : H263_MODE;
316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            Bool success = PVInitVideoDecoder(
318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight, mode);
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!success) {
321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                LOGW("PVInitVideoDecoder failed. Unsupported content?");
322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode != actualMode) {
330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetPostProcType((VideoDecControls *) mHandle, 0);
336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo->mOwnedByUs = false;
339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inQueue.erase(inQueue.begin());
340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo = NULL;
341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notifyEmptyBufferDone(inHeader);
342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inHeader = NULL;
343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mInitialized = true;
346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode == MPEG4_MODE && portSettingsChanged()) {
348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            continue;
352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mFramesConfigured) {
355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PortInfo *port = editPortInfo(1);
356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader;
357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetReferenceYUV(mHandle, outHeader->pBuffer);
359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mFramesConfigured = true;
361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
363f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        uint32_t useExtTimestamp = (inHeader->nOffset == 0);
364f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
365f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        // decoder deals in ms, OMX in us.
366f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        uint32_t timestamp =
367f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            useExtTimestamp ? (inHeader->nTimeStamp + 500) / 1000 : 0xFFFFFFFF;
368f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int32_t bufferSize = inHeader->nFilledLen;
370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (PVDecodeVideoFrame(
372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, &bitstream, &timestamp, &bufferSize,
373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    &useExtTimestamp,
374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    outHeader->pBuffer) != PV_TRUE) {
375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            LOGE("failed to decode video frame.");
376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mSignalledError = true;
379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (portSettingsChanged()) {
383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
386f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        // decoder deals in ms, OMX in us.
387f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        outHeader->nTimeStamp = timestamp * 1000;
388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
389f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        CHECK_LE(bufferSize, inHeader->nFilledLen);
390f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        inHeader->nOffset += inHeader->nFilledLen - bufferSize;
391f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        inHeader->nFilledLen = bufferSize;
392f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
393f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        if (inHeader->nFilledLen == 0) {
394f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo->mOwnedByUs = false;
395f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inQueue.erase(inQueue.begin());
396f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo = NULL;
397f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            notifyEmptyBufferDone(inHeader);
398f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inHeader = NULL;
399f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        }
400bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
401bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
402bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
403bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nOffset = 0;
404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
405bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFlags = 0;
406bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
407bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        List<BufferInfo *>::iterator it = outQueue.begin();
408bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        while ((*it)->mHeader != outHeader) {
409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++it;
410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *outInfo = *it;
413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo->mOwnedByUs = false;
414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outQueue.erase(it);
415bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo = NULL;
416bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
417bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyFillBufferDone(outHeader);
418bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader = NULL;
419bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
420bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mNumSamplesOutput;
421bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
422bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftMPEG4::portSettingsChanged() {
425bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    int32_t disp_width, disp_height;
426bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    PVGetVideoDimensions(mHandle, &disp_width, &disp_height);
427bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
428bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    int32_t buf_width, buf_height;
429bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    PVGetBufferDimensions(mHandle, &buf_width, &buf_height);
430bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
431bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_width, buf_width);
432bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_height, buf_height);
433bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
434bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    LOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d",
435bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            disp_width, disp_height, buf_width, buf_height);
436bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
437bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mCropRight != disp_width - 1
438bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            || mCropBottom != disp_height - 1) {
439bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropLeft = 0;
440bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropTop = 0;
441bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropRight = disp_width - 1;
442bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropBottom = disp_height - 1;
443bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
444bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged,
445bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               1,
446bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               OMX_IndexConfigCommonOutputCrop,
447bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               NULL);
448bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
449bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
450bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (buf_width != mWidth || buf_height != mHeight) {
451bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mWidth = buf_width;
452bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mHeight = buf_height;
453bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
454bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        updatePortDefinitions();
455bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
456bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mMode == MODE_H263) {
457bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVCleanUpVideoDecoder(mHandle);
458bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
459bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
460bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
461bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
462bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
463bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!PVInitVideoDecoder(
464bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight,
465bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    H263_MODE)) {
466bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
467bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
468bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return true;
469bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
470bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
471bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
472bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mFramesConfigured = false;
473bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
474bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
475bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mOutputPortSettingsChange = AWAITING_DISABLED;
476bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return true;
477bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
478bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
479bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return false;
480bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
481bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
482bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onPortFlushCompleted(OMX_U32 portIndex) {
483bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mInitialized) {
484bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
485bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
486bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
487bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
488bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
489bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex != 1) {
490bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
491bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
492bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
493bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (mOutputPortSettingsChange) {
494bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case NONE:
495bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
496bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
497bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case AWAITING_DISABLED:
498bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
499bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(!enabled);
500bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_ENABLED;
501bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
502bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
503bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
504bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
505bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
506bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
507bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(enabled);
508bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = NONE;
509bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
510bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
511bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
512bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
513bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
514bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::updatePortDefinitions() {
515bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
516bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameWidth = mWidth;
517bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameHeight = mHeight;
518bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nStride = def->format.video.nFrameWidth;
519bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
520bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
521bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def = &editPortInfo(1)->mDef;
522bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameWidth = mWidth;
523bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameHeight = mHeight;
524bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nStride = def->format.video.nFrameWidth;
525bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
526bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
527bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->nBufferSize =
528bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (((def->format.video.nFrameWidth + 15) & -16)
529bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2;
530bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
531bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
532bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}  // namespace android
533bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
534bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
535bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
536bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
537bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return new android::SoftMPEG4(name, callbacks, appData, component);
538bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
539bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
540