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, ×tamp, &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