SoftMPEG4.cpp revision 457116d3a01618acf9a875020ca5860551ba03a6
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>
26457116d3a01618acf9a875020ca5860551ba03a6James Dong#include <media/IOMX.h>
27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "mp4dec_api.h"
29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android {
31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
32457116d3a01618acf9a875020ca5860551ba03a6James Dongstatic const CodecProfileLevel kM4VProfileLevels[] = {
33457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0 },
34457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b },
35457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1 },
36457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2 },
37457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3 },
38457116d3a01618acf9a875020ca5860551ba03a6James Dong};
39457116d3a01618acf9a875020ca5860551ba03a6James Dong
40457116d3a01618acf9a875020ca5860551ba03a6James Dongstatic const CodecProfileLevel kH263ProfileLevels[] = {
41457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10 },
42457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20 },
43457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30 },
44457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45 },
45457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level10 },
46457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level20 },
47457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level30 },
48457116d3a01618acf9a875020ca5860551ba03a6James Dong    { OMX_VIDEO_H263ProfileISWV2,    OMX_VIDEO_H263Level45 },
49457116d3a01618acf9a875020ca5860551ba03a6James Dong};
50457116d3a01618acf9a875020ca5860551ba03a6James Dong
51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T>
52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) {
53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nSize = sizeof(T);
54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nVersionMajor = 1;
55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nVersionMinor = 0;
56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nRevision = 0;
57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    params->nVersion.s.nStep = 0;
58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
60bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftMPEG4::SoftMPEG4(
61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name,
62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const OMX_CALLBACKTYPE *callbacks,
63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData,
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_COMPONENTTYPE **component)
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    : SimpleSoftOMXComponent(name, callbacks, appData, component),
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mMode(MODE_MPEG4),
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mHandle(new tagvideoDecControls),
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInputBufferCount(0),
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mWidth(352),
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mHeight(288),
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropLeft(0),
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropTop(0),
73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropRight(mWidth - 1),
74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mCropBottom(mHeight - 1),
75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mSignalledError(false),
76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInitialized(false),
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mFramesConfigured(false),
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mNumSamplesOutput(0),
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mOutputPortSettingsChange(NONE) {
80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!strcmp(name, "OMX.google.h263.decoder")) {
81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mMode = MODE_H263;
82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    } else {
83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        CHECK(!strcmp(name, "OMX.google.mpeg4.decoder"));
84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    initPorts();
87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftMPEG4::~SoftMPEG4() {
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mInitialized) {
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PVCleanUpVideoDecoder(mHandle);
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    delete mHandle;
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mHandle = NULL;
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::initPorts() {
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    InitOMXParams(&def);
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 0;
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirInput;
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumInputBuffers;
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize = 8192;
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainVideo;
111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 1;
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.cMIMEType =
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (mMode == MODE_MPEG4)
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ? const_cast<char *>(MEDIA_MIMETYPE_VIDEO_MPEG4)
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            : const_cast<char *>(MEDIA_MIMETYPE_VIDEO_H263);
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeRender = NULL;
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameWidth = mWidth;
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameHeight = mHeight;
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nStride = def.format.video.nFrameWidth;
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nBitrate = 0;
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.xFramerate = 0;
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.bFlagErrorConcealment = OMX_FALSE;
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eCompressionFormat =
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mMode == MODE_MPEG4 ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeWindow = NULL;
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nPortIndex = 1;
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDir = OMX_DirOutput;
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountMin = kNumOutputBuffers;
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferCountActual = def.nBufferCountMin;
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bEnabled = OMX_TRUE;
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bPopulated = OMX_FALSE;
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.eDomain = OMX_PortDomainVideo;
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.bBuffersContiguous = OMX_FALSE;
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferAlignment = 2;
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW);
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeRender = NULL;
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameWidth = mWidth;
149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nFrameHeight = mHeight;
150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nStride = def.format.video.nFrameWidth;
151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nSliceHeight = def.format.video.nFrameHeight;
152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.nBitrate = 0;
153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.xFramerate = 0;
154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.bFlagErrorConcealment = OMX_FALSE;
155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.format.video.pNativeWindow = NULL;
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def.nBufferSize =
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2;
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    addPort(def);
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftMPEG4::initDecoder() {
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    memset(mHandle, 0, sizeof(tagvideoDecControls));
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return OK;
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::internalGetParameter(
171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamVideoPortFormat:
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex > 1) {
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nIndex != 0) {
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorNoMore;
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex == 0) {
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eCompressionFormat =
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    (mMode == MODE_MPEG4)
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                        ? OMX_VIDEO_CodingMPEG4 : OMX_VIDEO_CodingH263;
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eColorFormat = OMX_COLOR_FormatUnused;
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->xFramerate = 0;
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                CHECK_EQ(formatParams->nPortIndex, 1u);
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                formatParams->xFramerate = 0;
199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
204457116d3a01618acf9a875020ca5860551ba03a6James Dong        case OMX_IndexParamVideoProfileLevelQuerySupported:
205457116d3a01618acf9a875020ca5860551ba03a6James Dong        {
206457116d3a01618acf9a875020ca5860551ba03a6James Dong            OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
207457116d3a01618acf9a875020ca5860551ba03a6James Dong                    (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
208457116d3a01618acf9a875020ca5860551ba03a6James Dong
209457116d3a01618acf9a875020ca5860551ba03a6James Dong            if (profileLevel->nPortIndex != 0) {  // Input port only
210457116d3a01618acf9a875020ca5860551ba03a6James Dong                LOGE("Invalid port index: %ld", profileLevel->nPortIndex);
211457116d3a01618acf9a875020ca5860551ba03a6James Dong                return OMX_ErrorUnsupportedIndex;
212457116d3a01618acf9a875020ca5860551ba03a6James Dong            }
213457116d3a01618acf9a875020ca5860551ba03a6James Dong
214457116d3a01618acf9a875020ca5860551ba03a6James Dong            size_t index = profileLevel->nProfileIndex;
215457116d3a01618acf9a875020ca5860551ba03a6James Dong            if (mMode == MODE_H263) {
216457116d3a01618acf9a875020ca5860551ba03a6James Dong                size_t nProfileLevels =
217457116d3a01618acf9a875020ca5860551ba03a6James Dong                    sizeof(kH263ProfileLevels) / sizeof(kH263ProfileLevels[0]);
218457116d3a01618acf9a875020ca5860551ba03a6James Dong                if (index >= nProfileLevels) {
219457116d3a01618acf9a875020ca5860551ba03a6James Dong                    return OMX_ErrorNoMore;
220457116d3a01618acf9a875020ca5860551ba03a6James Dong                }
221457116d3a01618acf9a875020ca5860551ba03a6James Dong
222457116d3a01618acf9a875020ca5860551ba03a6James Dong                profileLevel->eProfile = kH263ProfileLevels[index].mProfile;
223457116d3a01618acf9a875020ca5860551ba03a6James Dong                profileLevel->eLevel = kH263ProfileLevels[index].mLevel;
224457116d3a01618acf9a875020ca5860551ba03a6James Dong            } else {
225457116d3a01618acf9a875020ca5860551ba03a6James Dong                size_t nProfileLevels =
226457116d3a01618acf9a875020ca5860551ba03a6James Dong                    sizeof(kM4VProfileLevels) / sizeof(kM4VProfileLevels[0]);
227457116d3a01618acf9a875020ca5860551ba03a6James Dong                if (index >= nProfileLevels) {
228457116d3a01618acf9a875020ca5860551ba03a6James Dong                    return OMX_ErrorNoMore;
229457116d3a01618acf9a875020ca5860551ba03a6James Dong                }
230457116d3a01618acf9a875020ca5860551ba03a6James Dong
231457116d3a01618acf9a875020ca5860551ba03a6James Dong                profileLevel->eProfile = kM4VProfileLevels[index].mProfile;
232457116d3a01618acf9a875020ca5860551ba03a6James Dong                profileLevel->eLevel = kM4VProfileLevels[index].mLevel;
233457116d3a01618acf9a875020ca5860551ba03a6James Dong            }
234457116d3a01618acf9a875020ca5860551ba03a6James Dong            return OMX_ErrorNone;
235457116d3a01618acf9a875020ca5860551ba03a6James Dong        }
236457116d3a01618acf9a875020ca5860551ba03a6James Dong
237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalGetParameter(index, params);
239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
242bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::internalSetParameter(
243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, const OMX_PTR params) {
244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamStandardComponentRole:
246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            const OMX_PARAM_COMPONENTROLETYPE *roleParams =
248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (const OMX_PARAM_COMPONENTROLETYPE *)params;
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mMode == MODE_MPEG4) {
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                if (strncmp((const char *)roleParams->cRole,
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "video_decoder.mpeg4",
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            OMX_MAX_STRINGNAME_SIZE - 1)) {
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    return OMX_ErrorUndefined;
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                }
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            } else {
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                if (strncmp((const char *)roleParams->cRole,
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "video_decoder.h263",
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            OMX_MAX_STRINGNAME_SIZE - 1)) {
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    return OMX_ErrorUndefined;
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                }
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexParamVideoPortFormat:
268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nPortIndex > 1) {
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (formatParams->nIndex != 0) {
277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorNoMore;
278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return SimpleSoftOMXComponent::internalSetParameter(index, params);
285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftMPEG4::getConfig(
289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_INDEXTYPE index, OMX_PTR params) {
290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (index) {
291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case OMX_IndexConfigCommonOutputCrop:
292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params;
294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (rectParams->nPortIndex != 1) {
296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return OMX_ErrorUndefined;
297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nLeft = mCropLeft;
300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nTop = mCropTop;
301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nWidth = mCropRight - mCropLeft + 1;
302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            rectParams->nHeight = mCropBottom - mCropTop + 1;
303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorNone;
305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return OMX_ErrorUnsupportedIndex;
309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onQueueFilled(OMX_U32 portIndex) {
313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mSignalledError || mOutputPortSettingsChange != NONE) {
314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    while (!inQueue.empty() && outQueue.size() == kNumOutputBuffers) {
321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *inInfo = *inQueue.begin();
322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PortInfo *port = editPortInfo(1);
325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *outHeader =
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            port->mBuffers.editItemAt(mNumSamplesOutput & 1).mHeader;
328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inQueue.erase(inQueue.begin());
331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inInfo->mOwnedByUs = false;
332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyEmptyBufferDone(inHeader);
333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++mInputBufferCount;
335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFilledLen = 0;
337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            List<BufferInfo *>::iterator it = outQueue.begin();
340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            while ((*it)->mHeader != outHeader) {
341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                ++it;
342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            BufferInfo *outInfo = *it;
345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo->mOwnedByUs = false;
346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outQueue.erase(it);
347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo = NULL;
348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyFillBufferDone(outHeader);
350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader = NULL;
351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        uint8_t *bitstream = inHeader->pBuffer + inHeader->nOffset;
355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mInitialized) {
357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
363bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_data[0] = bitstream;
364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_size = inHeader->nFilledLen;
365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode mode =
368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (mMode == MODE_MPEG4) ? MPEG4_MODE : H263_MODE;
369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            Bool success = PVInitVideoDecoder(
371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight, mode);
372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!success) {
374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                LOGW("PVInitVideoDecoder failed. Unsupported content?");
375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode != actualMode) {
383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetPostProcType((VideoDecControls *) mHandle, 0);
389bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
390bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
391bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo->mOwnedByUs = false;
392bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inQueue.erase(inQueue.begin());
393bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo = NULL;
394bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notifyEmptyBufferDone(inHeader);
395bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inHeader = NULL;
396bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
397bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
398bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mInitialized = true;
399bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
400bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode == MPEG4_MODE && portSettingsChanged()) {
401bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
402bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
403bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
404bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            continue;
405bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
406bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
407bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mFramesConfigured) {
408bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PortInfo *port = editPortInfo(1);
409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader;
410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetReferenceYUV(mHandle, outHeader->pBuffer);
412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mFramesConfigured = true;
414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
415bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
416f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        uint32_t useExtTimestamp = (inHeader->nOffset == 0);
417f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
418f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        // decoder deals in ms, OMX in us.
419f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        uint32_t timestamp =
420f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            useExtTimestamp ? (inHeader->nTimeStamp + 500) / 1000 : 0xFFFFFFFF;
421f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
422bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int32_t bufferSize = inHeader->nFilledLen;
423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (PVDecodeVideoFrame(
425bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, &bitstream, &timestamp, &bufferSize,
426bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    &useExtTimestamp,
427bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    outHeader->pBuffer) != PV_TRUE) {
428bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            LOGE("failed to decode video frame.");
429bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
430bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
431bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mSignalledError = true;
432bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
433bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
434bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
435bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (portSettingsChanged()) {
436bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
437bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
438bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
439f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        // decoder deals in ms, OMX in us.
440f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        outHeader->nTimeStamp = timestamp * 1000;
441bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
442f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        CHECK_LE(bufferSize, inHeader->nFilledLen);
443f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        inHeader->nOffset += inHeader->nFilledLen - bufferSize;
444f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        inHeader->nFilledLen = bufferSize;
445f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
446f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        if (inHeader->nFilledLen == 0) {
447f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo->mOwnedByUs = false;
448f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inQueue.erase(inQueue.begin());
449f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo = NULL;
450f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            notifyEmptyBufferDone(inHeader);
451f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inHeader = NULL;
452f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        }
453bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
454bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
455bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
456bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nOffset = 0;
457bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
458bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFlags = 0;
459bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
460bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        List<BufferInfo *>::iterator it = outQueue.begin();
461bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        while ((*it)->mHeader != outHeader) {
462bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++it;
463bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
464bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
465bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *outInfo = *it;
466bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo->mOwnedByUs = false;
467bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outQueue.erase(it);
468bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo = NULL;
469bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
470bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyFillBufferDone(outHeader);
471bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader = NULL;
472bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
473bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mNumSamplesOutput;
474bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
475bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
476bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
477bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftMPEG4::portSettingsChanged() {
478bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    int32_t disp_width, disp_height;
479bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    PVGetVideoDimensions(mHandle, &disp_width, &disp_height);
480bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
481bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    int32_t buf_width, buf_height;
482bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    PVGetBufferDimensions(mHandle, &buf_width, &buf_height);
483bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
484bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_width, buf_width);
485bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_height, buf_height);
486bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
487bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    LOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d",
488bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            disp_width, disp_height, buf_width, buf_height);
489bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
490bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mCropRight != disp_width - 1
491bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            || mCropBottom != disp_height - 1) {
492bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropLeft = 0;
493bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropTop = 0;
494bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropRight = disp_width - 1;
495bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropBottom = disp_height - 1;
496bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
497bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged,
498bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               1,
499bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               OMX_IndexConfigCommonOutputCrop,
500bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               NULL);
501bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
502bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
503bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (buf_width != mWidth || buf_height != mHeight) {
504bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mWidth = buf_width;
505bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mHeight = buf_height;
506bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
507bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        updatePortDefinitions();
508bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
509bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mMode == MODE_H263) {
510bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVCleanUpVideoDecoder(mHandle);
511bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
512bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
513bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
514bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
515bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
516bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!PVInitVideoDecoder(
517bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight,
518bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    H263_MODE)) {
519bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
520bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
521bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return true;
522bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
523bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
524bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
525bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mFramesConfigured = false;
526bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
527bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
528bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mOutputPortSettingsChange = AWAITING_DISABLED;
529bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return true;
530bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
531bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
532bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return false;
533bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
534bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
535bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onPortFlushCompleted(OMX_U32 portIndex) {
536bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mInitialized) {
537bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
538bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
539bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
540bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
541bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
542bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex != 1) {
543bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
544bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
545bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
546bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    switch (mOutputPortSettingsChange) {
547bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case NONE:
548bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
549bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
550bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        case AWAITING_DISABLED:
551bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
552bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(!enabled);
553bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = AWAITING_ENABLED;
554bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
555bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
556bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
557bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        default:
558bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        {
559bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
560bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            CHECK(enabled);
561bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mOutputPortSettingsChange = NONE;
562bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            break;
563bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
564bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
565bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
566bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
567bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::updatePortDefinitions() {
568bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef;
569bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameWidth = mWidth;
570bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameHeight = mHeight;
571bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nStride = def->format.video.nFrameWidth;
572bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
573bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
574bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def = &editPortInfo(1)->mDef;
575bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameWidth = mWidth;
576bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nFrameHeight = mHeight;
577bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nStride = def->format.video.nFrameWidth;
578bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->format.video.nSliceHeight = def->format.video.nFrameHeight;
579bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
580bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->nBufferSize =
581bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (((def->format.video.nFrameWidth + 15) & -16)
582bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2;
583bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
584bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
585bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}  // namespace android
586bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
587bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
588bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
589bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
590bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return new android::SoftMPEG4(name, callbacks, appData, component);
591bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
592bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
593