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