SoftVideoDecoderOMXComponent.cpp revision 031be0f358b07732092a4d1bf02fc99f109a63c4
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/hardware/HardwareAPI.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <media/stagefright/foundation/ALooper.h> 28#include <media/stagefright/foundation/AMessage.h> 29#include <media/stagefright/MediaDefs.h> 30 31namespace android { 32 33template<class T> 34static void InitOMXParams(T *params) { 35 params->nSize = sizeof(T); 36 params->nVersion.s.nVersionMajor = 1; 37 params->nVersion.s.nVersionMinor = 0; 38 params->nVersion.s.nRevision = 0; 39 params->nVersion.s.nStep = 0; 40} 41 42SoftVideoDecoderOMXComponent::SoftVideoDecoderOMXComponent( 43 const char *name, 44 const char *componentRole, 45 OMX_VIDEO_CODINGTYPE codingType, 46 const CodecProfileLevel *profileLevels, 47 size_t numProfileLevels, 48 int32_t width, 49 int32_t height, 50 const OMX_CALLBACKTYPE *callbacks, 51 OMX_PTR appData, 52 OMX_COMPONENTTYPE **component) 53 : SimpleSoftOMXComponent(name, callbacks, appData, component), 54 mIsAdaptive(false), 55 mAdaptiveMaxWidth(0), 56 mAdaptiveMaxHeight(0), 57 mWidth(width), 58 mHeight(height), 59 mCropLeft(0), 60 mCropTop(0), 61 mCropWidth(width), 62 mCropHeight(height), 63 mOutputPortSettingsChange(NONE), 64 mComponentRole(componentRole), 65 mCodingType(codingType), 66 mProfileLevels(profileLevels), 67 mNumProfileLevels(numProfileLevels) { 68} 69 70void SoftVideoDecoderOMXComponent::initPorts( 71 OMX_U32 numInputBuffers, 72 OMX_U32 inputBufferSize, 73 OMX_U32 numOutputBuffers, 74 const char *mimeType) { 75 OMX_PARAM_PORTDEFINITIONTYPE def; 76 InitOMXParams(&def); 77 78 def.nPortIndex = kInputPortIndex; 79 def.eDir = OMX_DirInput; 80 def.nBufferCountMin = numInputBuffers; 81 def.nBufferCountActual = def.nBufferCountMin; 82 def.nBufferSize = inputBufferSize; 83 def.bEnabled = OMX_TRUE; 84 def.bPopulated = OMX_FALSE; 85 def.eDomain = OMX_PortDomainVideo; 86 def.bBuffersContiguous = OMX_FALSE; 87 def.nBufferAlignment = 1; 88 89 def.format.video.cMIMEType = const_cast<char *>(mimeType); 90 def.format.video.pNativeRender = NULL; 91 /* size is initialized in updatePortDefinitions() */ 92 def.format.video.nBitrate = 0; 93 def.format.video.xFramerate = 0; 94 def.format.video.bFlagErrorConcealment = OMX_FALSE; 95 def.format.video.eCompressionFormat = mCodingType; 96 def.format.video.eColorFormat = OMX_COLOR_FormatUnused; 97 def.format.video.pNativeWindow = NULL; 98 99 addPort(def); 100 101 def.nPortIndex = kOutputPortIndex; 102 def.eDir = OMX_DirOutput; 103 def.nBufferCountMin = numOutputBuffers; 104 def.nBufferCountActual = def.nBufferCountMin; 105 def.bEnabled = OMX_TRUE; 106 def.bPopulated = OMX_FALSE; 107 def.eDomain = OMX_PortDomainVideo; 108 def.bBuffersContiguous = OMX_FALSE; 109 def.nBufferAlignment = 2; 110 111 def.format.video.cMIMEType = const_cast<char *>("video/raw"); 112 def.format.video.pNativeRender = NULL; 113 /* size is initialized in updatePortDefinitions() */ 114 def.format.video.nBitrate = 0; 115 def.format.video.xFramerate = 0; 116 def.format.video.bFlagErrorConcealment = OMX_FALSE; 117 def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 118 def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 119 def.format.video.pNativeWindow = NULL; 120 121 addPort(def); 122 123 updatePortDefinitions(); 124} 125 126void SoftVideoDecoderOMXComponent::updatePortDefinitions() { 127 OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; 128 def->format.video.nFrameWidth = mWidth; 129 def->format.video.nFrameHeight = mHeight; 130 def->format.video.nStride = def->format.video.nFrameWidth; 131 def->format.video.nSliceHeight = def->format.video.nFrameHeight; 132 133 def = &editPortInfo(kOutputPortIndex)->mDef; 134 def->format.video.nFrameWidth = mIsAdaptive ? mAdaptiveMaxWidth : mWidth; 135 def->format.video.nFrameHeight = mIsAdaptive ? mAdaptiveMaxHeight : mHeight; 136 def->format.video.nStride = def->format.video.nFrameWidth; 137 def->format.video.nSliceHeight = def->format.video.nFrameHeight; 138 139 def->nBufferSize = 140 (def->format.video.nFrameWidth * 141 def->format.video.nFrameHeight * 3) / 2; 142 143 mCropLeft = 0; 144 mCropTop = 0; 145 mCropWidth = mWidth; 146 mCropHeight = mHeight; 147} 148 149OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter( 150 OMX_INDEXTYPE index, OMX_PTR params) { 151 switch (index) { 152 case OMX_IndexParamVideoPortFormat: 153 { 154 OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 155 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 156 157 if (formatParams->nPortIndex > kMaxPortIndex) { 158 return OMX_ErrorUndefined; 159 } 160 161 if (formatParams->nIndex != 0) { 162 return OMX_ErrorNoMore; 163 } 164 165 if (formatParams->nPortIndex == kInputPortIndex) { 166 formatParams->eCompressionFormat = mCodingType; 167 formatParams->eColorFormat = OMX_COLOR_FormatUnused; 168 formatParams->xFramerate = 0; 169 } else { 170 CHECK_EQ(formatParams->nPortIndex, 1u); 171 172 formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; 173 formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; 174 formatParams->xFramerate = 0; 175 } 176 177 return OMX_ErrorNone; 178 } 179 180 case OMX_IndexParamVideoProfileLevelQuerySupported: 181 { 182 OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = 183 (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params; 184 185 if (profileLevel->nPortIndex != kInputPortIndex) { 186 ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex); 187 return OMX_ErrorUnsupportedIndex; 188 } 189 190 if (profileLevel->nProfileIndex >= mNumProfileLevels) { 191 return OMX_ErrorNoMore; 192 } 193 194 profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile; 195 profileLevel->eLevel = mProfileLevels[profileLevel->nProfileIndex].mLevel; 196 return OMX_ErrorNone; 197 } 198 199 default: 200 return SimpleSoftOMXComponent::internalGetParameter(index, params); 201 } 202} 203 204OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( 205 OMX_INDEXTYPE index, const OMX_PTR params) { 206 // Include extension index OMX_INDEXEXTTYPE. 207 const int32_t indexFull = index; 208 209 switch (indexFull) { 210 case OMX_IndexParamStandardComponentRole: 211 { 212 const OMX_PARAM_COMPONENTROLETYPE *roleParams = 213 (const OMX_PARAM_COMPONENTROLETYPE *)params; 214 215 if (strncmp((const char *)roleParams->cRole, 216 mComponentRole, 217 OMX_MAX_STRINGNAME_SIZE - 1)) { 218 return OMX_ErrorUndefined; 219 } 220 221 return OMX_ErrorNone; 222 } 223 224 case OMX_IndexParamVideoPortFormat: 225 { 226 OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = 227 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; 228 229 if (formatParams->nPortIndex > kMaxPortIndex) { 230 return OMX_ErrorUndefined; 231 } 232 233 if (formatParams->nIndex != 0) { 234 return OMX_ErrorNoMore; 235 } 236 237 return OMX_ErrorNone; 238 } 239 240 case kPrepareForAdaptivePlaybackIndex: 241 { 242 const PrepareForAdaptivePlaybackParams* adaptivePlaybackParams = 243 (const PrepareForAdaptivePlaybackParams *)params; 244 mIsAdaptive = adaptivePlaybackParams->bEnable; 245 if (mIsAdaptive) { 246 mAdaptiveMaxWidth = adaptivePlaybackParams->nMaxFrameWidth; 247 mAdaptiveMaxHeight = adaptivePlaybackParams->nMaxFrameHeight; 248 mWidth = mAdaptiveMaxWidth; 249 mHeight = mAdaptiveMaxHeight; 250 } else { 251 mAdaptiveMaxWidth = 0; 252 mAdaptiveMaxHeight = 0; 253 } 254 updatePortDefinitions(); 255 return OMX_ErrorNone; 256 } 257 258 default: 259 return SimpleSoftOMXComponent::internalSetParameter(index, params); 260 } 261} 262 263OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig( 264 OMX_INDEXTYPE index, OMX_PTR params) { 265 switch (index) { 266 case OMX_IndexConfigCommonOutputCrop: 267 { 268 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params; 269 270 if (rectParams->nPortIndex != kOutputPortIndex) { 271 return OMX_ErrorUndefined; 272 } 273 274 rectParams->nLeft = mCropLeft; 275 rectParams->nTop = mCropTop; 276 rectParams->nWidth = mCropWidth; 277 rectParams->nHeight = mCropHeight; 278 279 return OMX_ErrorNone; 280 } 281 282 default: 283 return OMX_ErrorUnsupportedIndex; 284 } 285} 286 287OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getExtensionIndex( 288 const char *name, OMX_INDEXTYPE *index) { 289 if (!strcmp(name, "OMX.google.android.index.prepareForAdaptivePlayback")) { 290 *(int32_t*)index = kPrepareForAdaptivePlaybackIndex; 291 return OMX_ErrorNone; 292 } 293 294 return SimpleSoftOMXComponent::getExtensionIndex(name, index); 295} 296 297void SoftVideoDecoderOMXComponent::onReset() { 298 mOutputPortSettingsChange = NONE; 299} 300 301void SoftVideoDecoderOMXComponent::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { 302 if (portIndex != kOutputPortIndex) { 303 return; 304 } 305 306 switch (mOutputPortSettingsChange) { 307 case NONE: 308 break; 309 310 case AWAITING_DISABLED: 311 { 312 CHECK(!enabled); 313 mOutputPortSettingsChange = AWAITING_ENABLED; 314 break; 315 } 316 317 default: 318 { 319 CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); 320 CHECK(enabled); 321 mOutputPortSettingsChange = NONE; 322 break; 323 } 324 } 325} 326 327} // namespace android 328