SoftMPEG4.cpp revision 84333e0475bc911adc16417f4ca327c975cf6c36
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 HuberSoftMPEG4::SoftMPEG4(
52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name,
537f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        const char *componentRole,
547f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        OMX_VIDEO_CODINGTYPE codingType,
557f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        const CodecProfileLevel *profileLevels,
567f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        size_t numProfileLevels,
57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const OMX_CALLBACKTYPE *callbacks,
58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData,
59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_COMPONENTTYPE **component)
607f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    : SoftVideoDecoderOMXComponent(
617f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            name, componentRole, codingType, profileLevels, numProfileLevels,
627f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            352 /* width */, 288 /* height */, callbacks, appData, component),
637f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar      mMode(codingType == OMX_VIDEO_CodingH263 ? MODE_H263 : MODE_MPEG4),
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mHandle(new tagvideoDecControls),
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInputBufferCount(0),
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mSignalledError(false),
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mInitialized(false),
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mFramesConfigured(false),
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      mNumSamplesOutput(0),
707f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar      mPvTime(0) {
717f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    initPorts(
727f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            kNumInputBuffers,
737f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            8192 /* inputBufferSize */,
747f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            kNumOutputBuffers,
757f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            (mMode == MODE_MPEG4)
767f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            ? MEDIA_MIMETYPE_VIDEO_MPEG4 : MEDIA_MIMETYPE_VIDEO_H263);
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_EQ(initDecoder(), (status_t)OK);
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
80bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftMPEG4::~SoftMPEG4() {
81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mInitialized) {
82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PVCleanUpVideoDecoder(mHandle);
83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    delete mHandle;
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    mHandle = NULL;
87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftMPEG4::initDecoder() {
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    memset(mHandle, 0, sizeof(tagvideoDecControls));
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return OK;
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
9484333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (mSignalledError || mOutputPortSettingsChange != NONE) {
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return;
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &inQueue = getPortQueue(0);
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    List<BufferInfo *> &outQueue = getPortQueue(1);
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    while (!inQueue.empty() && outQueue.size() == kNumOutputBuffers) {
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *inInfo = *inQueue.begin();
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        PortInfo *port = editPortInfo(1);
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_BUFFERHEADERTYPE *outHeader =
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            port->mBuffers.editItemAt(mNumSamplesOutput & 1).mHeader;
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
1114c44e9fed87ff6363393f2559b150291242da247Marco Nelissen        if ((inHeader->nFlags & OMX_BUFFERFLAG_EOS) && inHeader->nFilledLen == 0) {
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inQueue.erase(inQueue.begin());
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            inInfo->mOwnedByUs = false;
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyEmptyBufferDone(inHeader);
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++mInputBufferCount;
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFilledLen = 0;
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            List<BufferInfo *>::iterator it = outQueue.begin();
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            while ((*it)->mHeader != outHeader) {
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                ++it;
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            BufferInfo *outInfo = *it;
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo->mOwnedByUs = false;
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outQueue.erase(it);
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outInfo = NULL;
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notifyFillBufferDone(outHeader);
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            outHeader = NULL;
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        uint8_t *bitstream = inHeader->pBuffer + inHeader->nOffset;
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mInitialized) {
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_data[0] = bitstream;
146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                vol_size = inHeader->nFilledLen;
147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
148bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode mode =
150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                (mMode == MODE_MPEG4) ? MPEG4_MODE : H263_MODE;
151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            Bool success = PVInitVideoDecoder(
153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight, mode);
154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!success) {
1565ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("PVInitVideoDecoder failed. Unsupported content?");
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode != actualMode) {
165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetPostProcType((VideoDecControls *) mHandle, 0);
171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo->mOwnedByUs = false;
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inQueue.erase(inQueue.begin());
175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inInfo = NULL;
176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notifyEmptyBufferDone(inHeader);
177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                inHeader = NULL;
178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mInitialized = true;
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (mode == MPEG4_MODE && portSettingsChanged()) {
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return;
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            continue;
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (!mFramesConfigured) {
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PortInfo *port = editPortInfo(1);
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            OMX_BUFFERHEADERTYPE *outHeader = port->mBuffers.editItemAt(1).mHeader;
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVSetReferenceYUV(mHandle, outHeader->pBuffer);
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mFramesConfigured = true;
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
198f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        uint32_t useExtTimestamp = (inHeader->nOffset == 0);
199f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
200269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        // decoder deals in ms (int32_t), OMX in us (int64_t)
201269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        // so use fake timestamp instead
202269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        uint32_t timestamp = 0xFFFFFFFF;
203269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        if (useExtTimestamp) {
204269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar            mPvToOmxTimeMap.add(mPvTime, inHeader->nTimeStamp);
205269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar            timestamp = mPvTime;
206269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar            mPvTime++;
207269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        }
208f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        int32_t bufferSize = inHeader->nFilledLen;
21002accddf8d69da7b2b5e05631ad222cd842ff547Andreas Huber        int32_t tmp = bufferSize;
211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2120029faf8f4efbca3844c4174b75d46c432f8f272Andreas Huber        // The PV decoder is lying to us, sometimes it'll claim to only have
2130029faf8f4efbca3844c4174b75d46c432f8f272Andreas Huber        // consumed a subset of the buffer when it clearly consumed all of it.
2140029faf8f4efbca3844c4174b75d46c432f8f272Andreas Huber        // ignore whatever it says...
215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (PVDecodeVideoFrame(
2160029faf8f4efbca3844c4174b75d46c432f8f272Andreas Huber                    mHandle, &bitstream, &timestamp, &tmp,
217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    &useExtTimestamp,
218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    outHeader->pBuffer) != PV_TRUE) {
21929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("failed to decode video frame.");
220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            mSignalledError = true;
223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (portSettingsChanged()) {
227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            return;
228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
230f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        // decoder deals in ms, OMX in us.
231269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        outHeader->nTimeStamp = mPvToOmxTimeMap.valueFor(timestamp);
232269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar        mPvToOmxTimeMap.removeItem(timestamp);
233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
23402accddf8d69da7b2b5e05631ad222cd842ff547Andreas Huber        inHeader->nOffset += bufferSize;
23502accddf8d69da7b2b5e05631ad222cd842ff547Andreas Huber        inHeader->nFilledLen = 0;
2364c44e9fed87ff6363393f2559b150291242da247Marco Nelissen        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
2374c44e9fed87ff6363393f2559b150291242da247Marco Nelissen            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
2384c44e9fed87ff6363393f2559b150291242da247Marco Nelissen        } else {
2394c44e9fed87ff6363393f2559b150291242da247Marco Nelissen            outHeader->nFlags = 0;
2404c44e9fed87ff6363393f2559b150291242da247Marco Nelissen        }
241f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber
242f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        if (inHeader->nFilledLen == 0) {
243f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo->mOwnedByUs = false;
244f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inQueue.erase(inQueue.begin());
245f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inInfo = NULL;
246f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            notifyEmptyBufferDone(inHeader);
247f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber            inHeader = NULL;
248f2af5a2c607e71ff4cd39da28b077c0a68b206feAndreas Huber        }
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mInputBufferCount;
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nOffset = 0;
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        List<BufferInfo *>::iterator it = outQueue.begin();
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        while ((*it)->mHeader != outHeader) {
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            ++it;
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        BufferInfo *outInfo = *it;
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo->mOwnedByUs = false;
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outQueue.erase(it);
263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outInfo = NULL;
264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notifyFillBufferDone(outHeader);
266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        outHeader = NULL;
267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        ++mNumSamplesOutput;
269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool SoftMPEG4::portSettingsChanged() {
2737f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    uint32_t disp_width, disp_height;
2747f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    PVGetVideoDimensions(mHandle, (int32 *)&disp_width, (int32 *)&disp_height);
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2767f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    uint32_t buf_width, buf_height;
2777f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    PVGetBufferDimensions(mHandle, (int32 *)&buf_width, (int32 *)&buf_height);
278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_width, buf_width);
280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CHECK_LE(disp_height, buf_height);
281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("disp_width = %d, disp_height = %d, buf_width = %d, buf_height = %d",
283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            disp_width, disp_height, buf_width, buf_height);
284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
2857f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    if (mCropWidth != disp_width
2867f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar            || mCropHeight != disp_height) {
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropLeft = 0;
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mCropTop = 0;
2897f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        mCropWidth = disp_width;
2907f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        mCropHeight = disp_height;
291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged,
293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               1,
294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               OMX_IndexConfigCommonOutputCrop,
295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               NULL);
296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (buf_width != mWidth || buf_height != mHeight) {
299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mWidth = buf_width;
300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mHeight = buf_height;
301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        updatePortDefinitions();
303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        if (mMode == MODE_H263) {
305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            PVCleanUpVideoDecoder(mHandle);
306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            uint8_t *vol_data[1];
308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            int32_t vol_size = 0;
309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            vol_data[0] = NULL;
311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            if (!PVInitVideoDecoder(
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    mHandle, vol_data, &vol_size, 1, mWidth, mHeight,
313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                    H263_MODE)) {
314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                mSignalledError = true;
316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                return true;
317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            }
318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        }
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mFramesConfigured = false;
321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        mOutputPortSettingsChange = AWAITING_DISABLED;
324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        return true;
325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return false;
328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::onPortFlushCompleted(OMX_U32 portIndex) {
331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (portIndex == 0 && mInitialized) {
332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        CHECK_EQ((int)PVResetVideoDecoder(mHandle), (int)PV_TRUE);
333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
336d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Hubervoid SoftMPEG4::onReset() {
3377f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    SoftVideoDecoderOMXComponent::onReset();
338269a355679fce6a71523faeefc2ff575abbd1a8eLajos Molnar    mPvToOmxTimeMap.clear();
339d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber    mSignalledError = false;
34053b0a2b1f9cb6b99b3f0d1a639921d1b24bc30b7Lajos Molnar    mFramesConfigured = false;
34153b0a2b1f9cb6b99b3f0d1a639921d1b24bc30b7Lajos Molnar    if (mInitialized) {
34253b0a2b1f9cb6b99b3f0d1a639921d1b24bc30b7Lajos Molnar        PVCleanUpVideoDecoder(mHandle);
34353b0a2b1f9cb6b99b3f0d1a639921d1b24bc30b7Lajos Molnar        mInitialized = false;
34453b0a2b1f9cb6b99b3f0d1a639921d1b24bc30b7Lajos Molnar    }
345d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber}
346d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber
347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftMPEG4::updatePortDefinitions() {
3487f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    SoftVideoDecoderOMXComponent::updatePortDefinitions();
349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
3507f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    /* We have to align our width and height - this should affect stride! */
3517f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef;
352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    def->nBufferSize =
353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        (((def->format.video.nFrameWidth + 15) & -16)
354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            * ((def->format.video.nFrameHeight + 15) & -16) * 3) / 2;
355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}  // namespace android
358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent(
360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        const char *name, const OMX_CALLBACKTYPE *callbacks,
361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
3627f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    using namespace android;
3637f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    if (!strcmp(name, "OMX.google.h263.decoder")) {
3647f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        return new android::SoftMPEG4(
3657f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                name, "video_decoder.h263", OMX_VIDEO_CodingH263,
3667f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                kH263ProfileLevels, ARRAY_SIZE(kH263ProfileLevels),
3677f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                callbacks, appData, component);
3687f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    } else if (!strcmp(name, "OMX.google.mpeg4.decoder")) {
3697f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        return new android::SoftMPEG4(
3707f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                name, "video_decoder.mpeg4", OMX_VIDEO_CodingMPEG4,
3717f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                kM4VProfileLevels, ARRAY_SIZE(kM4VProfileLevels),
3727f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                callbacks, appData, component);
3737f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    } else {
3747f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        CHECK(!"Unknown component");
3757f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    }
376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
378