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 "SoftVPX" 19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <utils/Log.h> 20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "SoftVPX.h" 22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <media/stagefright/MediaDefs.h> 25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "vpx/vpx_decoder.h" 27bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "vpx/vpx_codec.h" 28bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "vpx/vp8dx.h" 29bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 30bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace android { 31bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 32bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubertemplate<class T> 33bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatic void InitOMXParams(T *params) { 34bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nSize = sizeof(T); 35bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMajor = 1; 36bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nVersionMinor = 0; 37bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nRevision = 0; 38bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber params->nVersion.s.nStep = 0; 39bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 40bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 41bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVPX::SoftVPX( 42bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, 43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_CALLBACKTYPE *callbacks, 44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, 45bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_COMPONENTTYPE **component) 46bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber : SimpleSoftOMXComponent(name, callbacks, appData, component), 47bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mCtx(NULL), 48bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mWidth(320), 49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mHeight(240), 50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange(NONE) { 51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber initPorts(); 52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(initDecoder(), (status_t)OK); 53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 55bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberSoftVPX::~SoftVPX() { 56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vpx_codec_destroy((vpx_codec_ctx_t *)mCtx); 57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber delete (vpx_codec_ctx_t *)mCtx; 58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mCtx = NULL; 59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVPX::initPorts() { 62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE def; 63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber InitOMXParams(&def); 64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 0; 66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirInput; 67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 6967f43688334bcd72ae7c3b5b386c1b6a34711f4fAndreas Huber def.nBufferSize = 256 * 1024; 70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainVideo; 73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 1; 75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VPX); 77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.pNativeRender = NULL; 78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nFrameWidth = mWidth; 79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nFrameHeight = mHeight; 80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nStride = def.format.video.nFrameWidth; 81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nSliceHeight = def.format.video.nFrameHeight; 82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nBitrate = 0; 83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.xFramerate = 0; 84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.bFlagErrorConcealment = OMX_FALSE; 85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; 86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.pNativeWindow = NULL; 88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nPortIndex = 1; 92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDir = OMX_DirOutput; 93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountMin = kNumBuffers; 94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferCountActual = def.nBufferCountMin; 95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bEnabled = OMX_TRUE; 96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bPopulated = OMX_FALSE; 97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.eDomain = OMX_PortDomainVideo; 98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.bBuffersContiguous = OMX_FALSE; 99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferAlignment = 2; 100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW); 102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.pNativeRender = NULL; 103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nFrameWidth = mWidth; 104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nFrameHeight = mHeight; 105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nStride = def.format.video.nFrameWidth; 106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nSliceHeight = def.format.video.nFrameHeight; 107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.nBitrate = 0; 108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.xFramerate = 0; 109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.bFlagErrorConcealment = OMX_FALSE; 110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.format.video.pNativeWindow = NULL; 113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def.nBufferSize = 115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2; 116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber addPort(def); 118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 120f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dongstatic int GetCPUCoreCount() { 121f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong int cpuCoreCount = 1; 122f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong#if defined(_SC_NPROCESSORS_ONLN) 123f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN); 124f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong#else 125f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong // _SC_NPROC_ONLN must be defined... 126f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong cpuCoreCount = sysconf(_SC_NPROC_ONLN); 127f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong#endif 128f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong CHECK(cpuCoreCount >= 1); 1293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Number of CPU cores: %d", cpuCoreCount); 130f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong return cpuCoreCount; 131f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong} 132f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong 133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstatus_t SoftVPX::initDecoder() { 134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mCtx = new vpx_codec_ctx_t; 135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vpx_codec_err_t vpx_err; 136f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong vpx_codec_dec_cfg_t cfg; 137f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t)); 138f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong cfg.threads = GetCPUCoreCount(); 139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if ((vpx_err = vpx_codec_dec_init( 140f3ac3e3c94c14dbf1cdf6a4577f0b3aa8edfad06James Dong (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, &cfg, 0))) { 14129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("on2 decoder failed to initialize. (%d)", vpx_err); 142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return UNKNOWN_ERROR; 143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OK; 146bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 147bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 148bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVPX::internalGetParameter( 149bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, OMX_PTR params) { 150bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 151bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamVideoPortFormat: 152bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 153bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 154bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 155bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (formatParams->nPortIndex > 1) { 157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 159bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 160bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (formatParams->nIndex != 0) { 161bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNoMore; 162bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 163bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 164bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (formatParams->nPortIndex == 0) { 165bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX; 166bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->eColorFormat = OMX_COLOR_FormatUnused; 167bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->xFramerate = 0; 168bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } else { 169bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(formatParams->nPortIndex, 1u); 170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; 173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber formatParams->xFramerate = 0; 174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 175bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 176bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 177bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 178bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalGetParameter(index, params); 181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 184bbba88cb1bdc34705d1477208990a06904c022e7Andreas HuberOMX_ERRORTYPE SoftVPX::internalSetParameter( 185bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_INDEXTYPE index, const OMX_PTR params) { 186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (index) { 187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamStandardComponentRole: 188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const OMX_PARAM_COMPONENTROLETYPE *roleParams = 190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (const OMX_PARAM_COMPONENTROLETYPE *)params; 191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (strncmp((const char *)roleParams->cRole, 193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber "video_decoder.vpx", 194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_MAX_STRINGNAME_SIZE - 1)) { 195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case OMX_IndexParamVideoPortFormat: 202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 205bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 206bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (formatParams->nPortIndex > 1) { 207bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorUndefined; 208bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (formatParams->nIndex != 0) { 211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNoMore; 212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return OMX_ErrorNone; 215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return SimpleSoftOMXComponent::internalSetParameter(index, params); 219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVPX::onQueueFilled(OMX_U32 portIndex) { 223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (mOutputPortSettingsChange != NONE) { 224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &inQueue = getPortQueue(0); 228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber List<BufferInfo *> &outQueue = getPortQueue(1); 229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber while (!inQueue.empty() && !outQueue.empty()) { 231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *inInfo = *inQueue.begin(); 232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader; 233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber BufferInfo *outInfo = *outQueue.begin(); 235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; 236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { 238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 242bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = 0; 243bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = OMX_BUFFERFLAG_EOS; 244bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 245bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (vpx_codec_decode( 252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (vpx_codec_ctx_t *)mCtx, 253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->pBuffer + inHeader->nOffset, 254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader->nFilledLen, 255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber NULL, 256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 0)) { 25729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("on2 decoder failed to decode frame."); 258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL); 260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 263bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vpx_codec_iter_t iter = NULL; 264bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter); 265bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 266bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (img != NULL) { 267bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ(img->fmt, IMG_FMT_I420); 268bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 269bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t width = img->d_w; 270bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber int32_t height = img->d_h; 271bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 272bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (width != mWidth || height != mHeight) { 273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mWidth = width; 274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mHeight = height; 275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 276bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber updatePortDefinitions(); 277bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 278bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notify(OMX_EventPortSettingsChanged, 1, 0, NULL); 279bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = AWAITING_DISABLED; 280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 283bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nOffset = 0; 284bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFilledLen = (width * height * 3) / 2; 285bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nFlags = 0; 286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader->nTimeStamp = inHeader->nTimeStamp; 287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y]; 289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber uint8_t *dst = outHeader->pBuffer; 290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber for (size_t i = 0; i < img->d_h; ++i) { 291bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber memcpy(dst, srcLine, img->d_w); 292bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 293bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber srcLine += img->stride[PLANE_Y]; 294bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber dst += img->d_w; 295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber srcLine = (const uint8_t *)img->planes[PLANE_U]; 298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber for (size_t i = 0; i < img->d_h / 2; ++i) { 299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber memcpy(dst, srcLine, img->d_w / 2); 300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber srcLine += img->stride[PLANE_U]; 302bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber dst += img->d_w / 2; 303bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 304bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 305bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber srcLine = (const uint8_t *)img->planes[PLANE_V]; 306bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber for (size_t i = 0; i < img->d_h / 2; ++i) { 307bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber memcpy(dst, srcLine, img->d_w / 2); 308bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 309bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber srcLine += img->stride[PLANE_V]; 310bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber dst += img->d_w / 2; 311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo->mOwnedByUs = false; 314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outQueue.erase(outQueue.begin()); 315bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outInfo = NULL; 316bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyFillBufferDone(outHeader); 317bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber outHeader = NULL; 318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo->mOwnedByUs = false; 321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inQueue.erase(inQueue.begin()); 322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inInfo = NULL; 323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber notifyEmptyBufferDone(inHeader); 324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber inHeader = NULL; 325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 328bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVPX::onPortFlushCompleted(OMX_U32 portIndex) { 329bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVPX::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 332bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber if (portIndex != 1) { 333bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return; 334bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 335bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 336bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber switch (mOutputPortSettingsChange) { 337bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case NONE: 338bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 339bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 340bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber case AWAITING_DISABLED: 341bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 342bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(!enabled); 343bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = AWAITING_ENABLED; 344bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber default: 348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber { 349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber CHECK(enabled); 351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber mOutputPortSettingsChange = NONE; 352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber break; 353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber } 355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubervoid SoftVPX::updatePortDefinitions() { 358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->mDef; 359bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nFrameWidth = mWidth; 360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nFrameHeight = mHeight; 361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nStride = def->format.video.nFrameWidth; 362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nSliceHeight = def->format.video.nFrameHeight; 363bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def = &editPortInfo(1)->mDef; 365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nFrameWidth = mWidth; 366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nFrameHeight = mHeight; 367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nStride = def->format.video.nFrameWidth; 368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->format.video.nSliceHeight = def->format.video.nFrameHeight; 369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber def->nBufferSize = 371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber (def->format.video.nFrameWidth 372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber * def->format.video.nFrameHeight * 3) / 2; 373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} // namespace android 376bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 377bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberandroid::SoftOMXComponent *createSoftOMXComponent( 378bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber const char *name, const OMX_CALLBACKTYPE *callbacks, 379bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber OMX_PTR appData, OMX_COMPONENTTYPE **component) { 380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber return new android::SoftVPX(name, callbacks, appData, component); 381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber} 382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber 383