SoftVideoDecoderOMXComponent.cpp revision db43b34c3428e480f8c4c66e7e88f4001f37f91e
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <inttypes.h> 18 19//#define LOG_NDEBUG 0 20#define LOG_TAG "SoftVideoDecoderOMXComponent" 21#include <utils/Log.h> 22 23#include "include/SoftVideoDecoderOMXComponent.h" 24 25#include <media/stagefright/foundation/ADebug.h> 26#include <media/stagefright/foundation/ALooper.h> 27#include <media/stagefright/foundation/AMessage.h> 28#include <media/stagefright/MediaDefs.h> 29 30namespace android { 31 32template<class T> 33static void InitOMXParams(T *params) { 34 params->nSize = sizeof(T); 35 params->nVersion.s.nVersionMajor = 1; 36 params->nVersion.s.nVersionMinor = 0; 37 params->nVersion.s.nRevision = 0; 38 params->nVersion.s.nStep = 0; 39} 40 41SoftVideoDecoderOMXComponent::SoftVideoDecoderOMXComponent( 42 const char *name, 43 const char *componentRole, 44 OMX_VIDEO_CODINGTYPE codingType, 45 const CodecProfileLevel *profileLevels, 46 size_t numProfileLevels, 47 int32_t width, 48 int32_t height, 49 const OMX_CALLBACKTYPE *callbacks, 50 OMX_PTR appData, 51 OMX_COMPONENTTYPE **component) 52 : SimpleSoftOMXComponent(name, callbacks, appData, component), 53 mWidth(width), 54 mHeight(height), 55 mCropLeft(0), 56 mCropTop(0), 57 mCropWidth(width), 58 mCropHeight(height), 59 mOutputPortSettingsChange(NONE), 60 mComponentRole(componentRole), 61 mCodingType(codingType), 62 mProfileLevels(profileLevels), 63 mNumProfileLevels(numProfileLevels) { 64} 65 66void SoftVideoDecoderOMXComponent::initPorts( 67 OMX_U32 numInputBuffers, 68 OMX_U32 inputBufferSize, 69 OMX_U32 numOutputBuffers, 70 const char *mimeType) { 71 OMX_PARAM_PORTDEFINITIONTYPE def; 72 InitOMXParams(&def); 73 74 def.nPortIndex = kInputPortIndex; 75 def.eDir = OMX_DirInput; 76 def.nBufferCountMin = numInputBuffers; 77 def.nBufferCountActual = def.nBufferCountMin; 78 def.nBufferSize = inputBufferSize; 79 def.bEnabled = OMX_TRUE; 80 def.bPopulated = OMX_FALSE; 81 def.eDomain = OMX_PortDomainVideo; 82 def.bBuffersContiguous = OMX_FALSE; 83 def.nBufferAlignment = 1; 84 85 def.format.video.cMIMEType = const_cast<char *>(mimeType); 86 def.format.video.pNativeRender = NULL; 87 /* size is initialized in updatePortDefinitions() */ 88 def.format.video.nBitrate = 0; 89 def.format.video.xFramerate = 0; 90 def.format.video.bFlagErrorConcealment = OMX_FALSE; 91 def.format.video.eCompressionFormat = mCodingType; 92 def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 93 def.format.video.pNativeWindow = NULL; 94 95 addPort(def); 96 97 def.nPortIndex = kOutputPortIndex; 98 def.eDir = OMX_DirOutput; 99 def.nBufferCountMin = numOutputBuffers; 100 def.nBufferCountActual = def.nBufferCountMin; 101 def.bEnabled = OMX_TRUE; 102 def.bPopulated = OMX_FALSE; 103 def.eDomain = OMX_PortDomainVideo; 104 def.bBuffersContiguous = OMX_FALSE; 105 def.nBufferAlignment = 2; 106 107 def.format.video.cMIMEType = const_cast<char *>("video/raw"); 108 def.format.video.pNativeRender = NULL; 109 /* size is initialized in updatePortDefinitions() */ 110 def.format.video.nBitrate = 0; 111 def.format.video.xFramerate = 0; 112 def.format.video.bFlagErrorConcealment = OMX_FALSE; 113 def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 114 def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 115 def.format.video.pNativeWindow = NULL; 116 117 addPort(def); 118 119 updatePortDefinitions(); 120} 121 122void SoftVideoDecoderOMXComponent::updatePortDefinitions() { 123 OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; 124 def->format.video.nFrameWidth = mWidth; 125 def->format.video.nFrameHeight = mHeight; 126 def->format.video.nStride = def->format.video.nFrameWidth; 127 def->format.video.nSliceHeight = def->format.video.nFrameHeight; 128 129 def = &editPortInfo(kOutputPortIndex)->mDef; 130 def->format.video.nFrameWidth = mWidth; 131 def->format.video.nFrameHeight = mHeight; 132 def->format.video.nStride = def->format.video.nFrameWidth; 133 def->format.video.nSliceHeight = def->format.video.nFrameHeight; 134 135 def->nBufferSize = 136 (def->format.video.nFrameWidth * 137 def->format.video.nFrameHeight * 3) / 2; 138 139 mCropLeft = 0; 140 mCropTop = 0; 141 mCropWidth = mWidth; 142 mCropHeight = mHeight; 143} 144 145OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter( 146 OMX_INDEXTYPE index, OMX_PTR params) { 147 switch (index) { 148 case OMX_IndexParamVideoPortFormat: 149 { 150 OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 151 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 152 153 if (formatParams->nPortIndex > kMaxPortIndex) { 154 return OMX_ErrorUndefined; 155 } 156 157 if (formatParams->nIndex != 0) { 158 return OMX_ErrorNoMore; 159 } 160 161 if (formatParams->nPortIndex == kInputPortIndex) { 162 formatParams->eCompressionFormat = mCodingType; 163 formatParams->eColorFormat = OMX_COLOR_FormatUnused; 164 formatParams->xFramerate = 0; 165 } else { 166 CHECK_EQ(formatParams->nPortIndex, 1u); 167 168 formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 169 formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; 170 formatParams->xFramerate = 0; 171 } 172 173 return OMX_ErrorNone; 174 } 175 176 case OMX_IndexParamVideoProfileLevelQuerySupported: 177 { 178 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = 179 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params; 180 181 if (profileLevel->nPortIndex != kInputPortIndex) { 182 ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex); 183 return OMX_ErrorUnsupportedIndex; 184 } 185 186 if (index >= mNumProfileLevels) { 187 return OMX_ErrorNoMore; 188 } 189 190 profileLevel->eProfile = mProfileLevels[index].mProfile; 191 profileLevel->eLevel = mProfileLevels[index].mLevel; 192 return OMX_ErrorNone; 193 } 194 195 default: 196 return SimpleSoftOMXComponent::internalGetParameter(index, params); 197 } 198} 199 200OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( 201 OMX_INDEXTYPE index, const OMX_PTR params) { 202 switch (index) { 203 case OMX_IndexParamStandardComponentRole: 204 { 205 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 206 (const OMX_PARAM_COMPONENTROLETYPE *)params; 207 208 if (strncmp((const char *)roleParams->cRole, 209 mComponentRole, 210 OMX_MAX_STRINGNAME_SIZE - 1)) { 211 return OMX_ErrorUndefined; 212 } 213 214 return OMX_ErrorNone; 215 } 216 217 case OMX_IndexParamVideoPortFormat: 218 { 219 OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 220 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 221 222 if (formatParams->nPortIndex > kMaxPortIndex) { 223 return OMX_ErrorUndefined; 224 } 225 226 if (formatParams->nIndex != 0) { 227 return OMX_ErrorNoMore; 228 } 229 230 return OMX_ErrorNone; 231 } 232 233 default: 234 return SimpleSoftOMXComponent::internalSetParameter(index, params); 235 } 236} 237 238OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig( 239 OMX_INDEXTYPE index, OMX_PTR params) { 240 switch (index) { 241 case OMX_IndexConfigCommonOutputCrop: 242 { 243 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params; 244 245 if (rectParams->nPortIndex != kOutputPortIndex) { 246 return OMX_ErrorUndefined; 247 } 248 249 rectParams->nLeft = mCropLeft; 250 rectParams->nTop = mCropTop; 251 rectParams->nWidth = mCropWidth; 252 rectParams->nHeight = mCropHeight; 253 254 return OMX_ErrorNone; 255 } 256 257 default: 258 return OMX_ErrorUnsupportedIndex; 259 } 260} 261 262void SoftVideoDecoderOMXComponent::onReset() { 263 mOutputPortSettingsChange = NONE; 264} 265 266void SoftVideoDecoderOMXComponent::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 267 if (portIndex != kOutputPortIndex) { 268 return; 269 } 270 271 switch (mOutputPortSettingsChange) { 272 case NONE: 273 break; 274 275 case AWAITING_DISABLED: 276 { 277 CHECK(!enabled); 278 mOutputPortSettingsChange = AWAITING_ENABLED; 279 break; 280 } 281 282 default: 283 { 284 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 285 CHECK(enabled); 286 mOutputPortSettingsChange = NONE; 287 break; 288 } 289 } 290} 291 292} // namespace android 293