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