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