Exynos_OMX_Vp8dec.c revision 20d3e6e3118a6e19627296e9247e948d54ec0fb8
1/* 2 * 3 * Copyright 2011 Samsung Electronics S.LSI Co. LTD 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/* 19 * @file Exynos_OMX_Vp8dec.c 20 * @brief 21 * @author Satish Kumar Reddy (palli.satish@samsung.com) 22 * @version 1.1.0 23 * @history 24 * 2011.11.15 : Create 25 */ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30 31#include "Exynos_OMX_Macros.h" 32#include "Exynos_OMX_Basecomponent.h" 33#include "Exynos_OMX_Baseport.h" 34#include "Exynos_OMX_Vdec.h" 35#include "Exynos_OSAL_ETC.h" 36#include "Exynos_OSAL_Semaphore.h" 37#include "Exynos_OSAL_Thread.h" 38#include "library_register.h" 39#include "Exynos_OMX_Vp8dec.h" 40#include "ExynosVideoApi.h" 41 42#ifdef USE_ANB 43#include "Exynos_OSAL_Android.h" 44#endif 45 46/* To use CSC_METHOD_PREFER_HW or CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */ 47/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ 48#include "csc.h" 49 50#undef EXYNOS_LOG_TAG 51#define EXYNOS_LOG_TAG "EXYNOS_VP8_DEC" 52#define EXYNOS_LOG_OFF 53#include "Exynos_OSAL_Log.h" 54 55#define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7 56 57//#define FULL_FRAME_SEARCH /* Full frame search not support*/ 58 59static int Check_VP8_Frame( 60 OMX_U8 *pInputStream, 61 int buffSize, 62 OMX_U32 flag, 63 OMX_BOOL bPreviousFrameEOF, 64 OMX_BOOL *pbEndOfFrame) 65{ 66 /* Uncompressed data Chunk comprises a common 67 (for key frames and interframes) 3-byte frame tag that 68 contains four fields 69 - 1-bit frame type (0 - key frame, 1 - inter frame) 70 - 3-bit version number (0 - 3 are defined as four different 71 profiles with different decoding complexity) 72 - 1-bit show_frame flag ( 0 - current frame not for display, 73 1 - current frame is for dispaly) 74 - 19-bit field - size of the first data partition in bytes 75 76 Key Frames : frame tag followed by 7 bytes of uncompressed 77 data 78 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a) 79 Next 4-bytes: Width & height, Horizontal and vertical scale information 80 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) 81 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) 82 */ 83 int width, height; 84 int horizSscale, vertScale; 85 86 FunctionIn(); 87 88 *pbEndOfFrame = OMX_TRUE; 89 90 /*Check for Key frame*/ 91 if (!(pInputStream[0] & 0x01)){ 92 /* Key Frame Start code*/ 93 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { 94 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found"); 95 *pbEndOfFrame = OMX_FALSE; 96 } 97 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code"); 98 width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff; 99 horizSscale = pInputStream[7] >> 6; 100 height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff; 101 vertScale = pInputStream[9] >> 6; 102 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale); 103 } 104 105 FunctionOut(); 106 return buffSize; 107} 108 109OMX_BOOL Check_VP8_StartCode( 110 OMX_U8 *pInputStream, 111 OMX_U32 streamSize) 112{ 113 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize); 114 if (streamSize < 3) { 115 return OMX_FALSE; 116 } 117 118 if (!(pInputStream[0] & 0x01)){ 119 /* Key Frame Start code*/ 120 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { 121 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found"); 122 return OMX_FALSE; 123 } 124 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code"); 125 } 126 127 return OMX_TRUE; 128} 129 130OMX_ERRORTYPE Exynos_MFC_VP8Dec_GetParameter( 131 OMX_IN OMX_HANDLETYPE hComponent, 132 OMX_IN OMX_INDEXTYPE nParamIndex, 133 OMX_INOUT OMX_PTR pComponentParameterStructure) 134{ 135 OMX_ERRORTYPE ret = OMX_ErrorNone; 136 OMX_COMPONENTTYPE *pOMXComponent = NULL; 137 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 138 139 FunctionIn(); 140 141 if (hComponent == NULL || pComponentParameterStructure == NULL) { 142 ret = OMX_ErrorBadParameter; 143 goto EXIT; 144 } 145 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 146 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 147 if (ret != OMX_ErrorNone) { 148 goto EXIT; 149 } 150 if (pOMXComponent->pComponentPrivate == NULL) { 151 ret = OMX_ErrorBadParameter; 152 goto EXIT; 153 } 154 155 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 156 if (pExynosComponent->currentState == OMX_StateInvalid ) { 157 ret = OMX_ErrorInvalidState; 158 goto EXIT; 159 } 160 161 switch (nParamIndex) { 162 case OMX_IndexParamStandardComponentRole: 163 { 164 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 165 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); 166 if (ret != OMX_ErrorNone) { 167 goto EXIT; 168 } 169 170 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE); 171 } 172 break; 173 case OMX_IndexParamVideoErrorCorrection: 174 { 175 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; 176 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; 177 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 178 179 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); 180 if (ret != OMX_ErrorNone) { 181 goto EXIT; 182 } 183 184 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { 185 ret = OMX_ErrorBadPortIndex; 186 goto EXIT; 187 } 188 189 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 190 pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; 191 192 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; 193 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; 194 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; 195 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; 196 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; 197 } 198 break; 199 default: 200 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); 201 break; 202 } 203EXIT: 204 FunctionOut(); 205 206 return ret; 207} 208 209OMX_ERRORTYPE Exynos_MFC_VP8Dec_SetParameter( 210 OMX_IN OMX_HANDLETYPE hComponent, 211 OMX_IN OMX_INDEXTYPE nIndex, 212 OMX_IN OMX_PTR pComponentParameterStructure) 213{ 214 OMX_ERRORTYPE ret = OMX_ErrorNone; 215 OMX_COMPONENTTYPE *pOMXComponent = NULL; 216 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 217 218 FunctionIn(); 219 220 if (hComponent == NULL || pComponentParameterStructure == NULL) { 221 ret = OMX_ErrorBadParameter; 222 goto EXIT; 223 } 224 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 225 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 226 if (ret != OMX_ErrorNone) { 227 goto EXIT; 228 } 229 if (pOMXComponent->pComponentPrivate == NULL) { 230 ret = OMX_ErrorBadParameter; 231 goto EXIT; 232 } 233 234 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 235 if (pExynosComponent->currentState == OMX_StateInvalid ) { 236 ret = OMX_ErrorInvalidState; 237 goto EXIT; 238 } 239 240 switch (nIndex) { 241 case OMX_IndexParamStandardComponentRole: 242 { 243 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; 244 245 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); 246 if (ret != OMX_ErrorNone) { 247 goto EXIT; 248 } 249 250 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 251 ret = OMX_ErrorIncorrectStateOperation; 252 goto EXIT; 253 } 254 255 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) { 256 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; 257 } else { 258 ret = OMX_ErrorBadParameter; 259 goto EXIT; 260 } 261 } 262 break; 263 case OMX_IndexParamPortDefinition: 264 { 265 OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; 266 OMX_U32 portIndex = pPortDefinition->nPortIndex; 267 EXYNOS_OMX_BASEPORT *pExynosPort; 268 OMX_U32 width, height, size; 269 OMX_U32 realWidth, realHeight; 270 271 if (portIndex >= pExynosComponent->portParam.nPorts) { 272 ret = OMX_ErrorBadPortIndex; 273 goto EXIT; 274 } 275 ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 276 if (ret != OMX_ErrorNone) { 277 goto EXIT; 278 } 279 280 pExynosPort = &pExynosComponent->pExynosPort[portIndex]; 281 282 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 283 if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) { 284 ret = OMX_ErrorIncorrectStateOperation; 285 goto EXIT; 286 } 287 } 288 if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) { 289 ret = OMX_ErrorBadParameter; 290 goto EXIT; 291 } 292 293 Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize); 294 295 realWidth = pExynosPort->portDefinition.format.video.nFrameWidth; 296 realHeight = pExynosPort->portDefinition.format.video.nFrameHeight; 297 width = ((realWidth + 15) & (~15)); 298 height = ((realHeight + 15) & (~15)); 299 size = (width * height * 3) / 2; 300 pExynosPort->portDefinition.format.video.nStride = width; 301 pExynosPort->portDefinition.format.video.nSliceHeight = height; 302 pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize; 303 304 if (portIndex == INPUT_PORT_INDEX) { 305 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 306 pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth; 307 pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight; 308 pExynosOutputPort->portDefinition.format.video.nStride = width; 309 pExynosOutputPort->portDefinition.format.video.nSliceHeight = height; 310 311 switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) { 312 case OMX_COLOR_FormatYUV420Planar: 313 case OMX_COLOR_FormatYUV420SemiPlanar: 314 case OMX_SEC_COLOR_FormatNV12TPhysicalAddress: 315 case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: 316 pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; 317 break; 318 case OMX_SEC_COLOR_FormatNV12Tiled: 319 pExynosOutputPort->portDefinition.nBufferSize = 320 ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight)) \ 321 + ALIGN_TO_8KB(ALIGN_TO_128B(realWidth) * ALIGN_TO_32B(realHeight/2)); 322 break; 323 default: 324 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!"); 325 ret = OMX_ErrorUnsupportedSetting; 326 break; 327 } 328 } 329 } 330 break; 331 case OMX_IndexParamVideoErrorCorrection: 332 { 333 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; 334 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; 335 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 336 337 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); 338 if (ret != OMX_ErrorNone) { 339 goto EXIT; 340 } 341 342 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { 343 ret = OMX_ErrorBadPortIndex; 344 goto EXIT; 345 } 346 347 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 348 pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; 349 350 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; 351 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; 352 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; 353 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; 354 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; 355 } 356 break; 357 default: 358 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); 359 break; 360 } 361EXIT: 362 FunctionOut(); 363 364 return ret; 365} 366 367OMX_ERRORTYPE Exynos_MFC_VP8Dec_GetConfig( 368 OMX_HANDLETYPE hComponent, 369 OMX_INDEXTYPE nIndex, 370 OMX_PTR pComponentConfigStructure) 371{ 372 OMX_ERRORTYPE ret = OMX_ErrorNone; 373 OMX_COMPONENTTYPE *pOMXComponent = NULL; 374 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 375 376 FunctionIn(); 377 378 if (hComponent == NULL) { 379 ret = OMX_ErrorBadParameter; 380 goto EXIT; 381 } 382 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 383 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 384 if (ret != OMX_ErrorNone) { 385 goto EXIT; 386 } 387 388 if (pOMXComponent->pComponentPrivate == NULL) { 389 ret = OMX_ErrorBadParameter; 390 goto EXIT; 391 } 392 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 393 394 if (pComponentConfigStructure == NULL) { 395 ret = OMX_ErrorBadParameter; 396 goto EXIT; 397 } 398 if (pExynosComponent->currentState == OMX_StateInvalid) { 399 ret = OMX_ErrorInvalidState; 400 goto EXIT; 401 } 402 403 switch (nIndex) { 404 default: 405 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); 406 break; 407 } 408 409EXIT: 410 FunctionOut(); 411 412 return ret; 413} 414 415OMX_ERRORTYPE Exynos_MFC_VP8Dec_SetConfig( 416 OMX_HANDLETYPE hComponent, 417 OMX_INDEXTYPE nIndex, 418 OMX_PTR pComponentConfigStructure) 419{ 420 OMX_ERRORTYPE ret = OMX_ErrorNone; 421 OMX_COMPONENTTYPE *pOMXComponent = NULL; 422 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 423 424 FunctionIn(); 425 426 if (hComponent == NULL) { 427 ret = OMX_ErrorBadParameter; 428 goto EXIT; 429 } 430 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 431 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 432 if (ret != OMX_ErrorNone) { 433 goto EXIT; 434 } 435 436 if (pOMXComponent->pComponentPrivate == NULL) { 437 ret = OMX_ErrorBadParameter; 438 goto EXIT; 439 } 440 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 441 442 if (pComponentConfigStructure == NULL) { 443 ret = OMX_ErrorBadParameter; 444 goto EXIT; 445 } 446 if (pExynosComponent->currentState == OMX_StateInvalid) { 447 ret = OMX_ErrorInvalidState; 448 goto EXIT; 449 } 450 451 switch (nIndex) { 452 default: 453 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); 454 break; 455 } 456 457EXIT: 458 FunctionOut(); 459 460 return ret; 461} 462 463OMX_ERRORTYPE Exynos_MFC_VP8Dec_GetExtensionIndex( 464 OMX_IN OMX_HANDLETYPE hComponent, 465 OMX_IN OMX_STRING cParameterName, 466 OMX_OUT OMX_INDEXTYPE *pIndexType) 467{ 468 OMX_ERRORTYPE ret = OMX_ErrorNone; 469 OMX_COMPONENTTYPE *pOMXComponent = NULL; 470 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 471 472 FunctionIn(); 473 474 if (hComponent == NULL) { 475 ret = OMX_ErrorBadParameter; 476 goto EXIT; 477 } 478 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 479 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 480 if (ret != OMX_ErrorNone) { 481 goto EXIT; 482 } 483 484 if (pOMXComponent->pComponentPrivate == NULL) { 485 ret = OMX_ErrorBadParameter; 486 goto EXIT; 487 } 488 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 489 490 if ((cParameterName == NULL) || (pIndexType == NULL)) { 491 ret = OMX_ErrorBadParameter; 492 goto EXIT; 493 } 494 if (pExynosComponent->currentState == OMX_StateInvalid) { 495 ret = OMX_ErrorInvalidState; 496 goto EXIT; 497 } 498 499 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { 500 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 501 502 *pIndexType = OMX_IndexVendorThumbnailMode; 503 504 ret = OMX_ErrorNone; 505 } else { 506 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); 507 } 508 509EXIT: 510 FunctionOut(); 511 512 return ret; 513} 514 515OMX_ERRORTYPE Exynos_MFC_VP8Dec_ComponentRoleEnum( 516 OMX_HANDLETYPE hComponent, 517 OMX_U8 *cRole, 518 OMX_U32 nIndex) 519{ 520 OMX_ERRORTYPE ret = OMX_ErrorNone; 521 OMX_COMPONENTTYPE *pOMXComponent = NULL; 522 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 523 524 FunctionIn(); 525 526 if ((hComponent == NULL) || (cRole == NULL)) { 527 ret = OMX_ErrorBadParameter; 528 goto EXIT; 529 } 530 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { 531 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE); 532 ret = OMX_ErrorNone; 533 } else { 534 ret = OMX_ErrorNoMore; 535 } 536 537EXIT: 538 FunctionOut(); 539 540 return ret; 541} 542 543OMX_ERRORTYPE Exynos_MFC_DecodeThread( 544 OMX_HANDLETYPE hComponent) 545{ 546 OMX_ERRORTYPE ret = OMX_ErrorNone; 547 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 548 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 549 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 550 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 551 ExynosVideoDecOps *pDecOps = pVideoDec->pDecOps; 552 ExynosVideoDecBufferOps *pInbufOps = pVideoDec->pInbufOps; 553 ExynosVideoDecBufferOps *pOutbufOps = pVideoDec->pOutbufOps; 554 555 FunctionIn(); 556 557 if (hComponent == NULL) { 558 ret = OMX_ErrorBadParameter; 559 goto EXIT; 560 } 561 562 while (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { 563 Exynos_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameStart); 564 565 if (pVideoDec->NBDecThread.bExitDecodeThread == OMX_FALSE) { 566#ifdef CONFIG_MFC_FPS 567 Exynos_OSAL_PerfStart(PERF_ID_DEC); 568#endif 569 if (pVideoDec->NBDecThread.oneFrameSize > 0) { 570 /* queue work for input buffer */ 571 pInbufOps->Enqueue(pVp8Dec->hMFCVp8Handle.hMFCHandle, 572 (unsigned char **)&pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, 573 (unsigned int *)&pVideoDec->NBDecThread.oneFrameSize, 574 1, NULL); 575 576 pVideoDec->indexInputBuffer++; 577 pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; 578 pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; 579 pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; 580 pExynosComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; 581 pExynosComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; 582 583 pInbufOps->Dequeue(pVp8Dec->hMFCVp8Handle.hMFCHandle); 584 pVideoDec->pOutbuf = pOutbufOps->Dequeue(pVp8Dec->hMFCVp8Handle.hMFCHandle); 585 } 586 587 pVp8Dec->hMFCVp8Handle.returnCodec = VIDEO_TRUE; 588#ifdef CONFIG_MFC_FPS 589 Exynos_OSAL_PerfStop(PERF_ID_DEC); 590#endif 591 Exynos_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameEnd); 592 } 593 } 594 595EXIT: 596 Exynos_OSAL_ThreadExit(NULL); 597 FunctionOut(); 598 599 return ret; 600} 601 602/* MFC Init */ 603OMX_ERRORTYPE Exynos_MFC_VP8Dec_Init( 604 OMX_COMPONENTTYPE *pOMXComponent) 605{ 606 OMX_ERRORTYPE ret = OMX_ErrorNone; 607 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 608 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 609 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 610 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 611 OMX_PTR hMFCHandle = NULL; 612 OMX_PTR pStreamBuffer = NULL; 613 OMX_PTR pStreamPhyBuffer = NULL; 614 ExynosVideoDecOps *pDecOps = NULL; 615 ExynosVideoDecBufferOps *pInbufOps = NULL; 616 ExynosVideoDecBufferOps *pOutbufOps = NULL; 617 ExynosVideoBuffer bufferInfo; 618 ExynosVideoGeometry bufferConf; 619 620 CSC_METHOD csc_method = CSC_METHOD_SW; 621 int i = 0; 622 623 FunctionIn(); 624 625#ifdef CONFIG_MFC_FPS 626 Exynos_OSAL_PerfInit(PERF_ID_DEC); 627 Exynos_OSAL_PerfInit(PERF_ID_CSC); 628#endif 629 630 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 631 pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_FALSE; 632 pExynosComponent->bUseFlagEOF = OMX_FALSE; 633 pExynosComponent->bSaveFlagEOS = OMX_FALSE; 634 635 /* alloc ops structure */ 636 pDecOps = (ExynosVideoDecOps *)malloc(sizeof(*pDecOps)); 637 pInbufOps = (ExynosVideoDecBufferOps *)malloc(sizeof(*pInbufOps)); 638 pOutbufOps = (ExynosVideoDecBufferOps *)malloc(sizeof(*pOutbufOps)); 639 640 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { 641 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); 642 ret = OMX_ErrorInsufficientResources; 643 goto EXIT; 644 } 645 646 pVideoDec->pDecOps = pDecOps; 647 pVideoDec->pInbufOps = pInbufOps; 648 pVideoDec->pOutbufOps = pOutbufOps; 649 650 /* function pointer mapping */ 651 pDecOps->nSize = sizeof(*pDecOps); 652 pInbufOps->nSize = sizeof(*pInbufOps); 653 pOutbufOps->nSize = sizeof(*pOutbufOps); 654 655 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); 656 657 /* check mandatory functions for decoder ops */ 658 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || 659 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || 660 (pDecOps->Get_FrameTag == NULL)) { 661 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); 662 ret = OMX_ErrorInsufficientResources; 663 goto EXIT; 664 } 665 666 /* check mandatory functions for buffer ops */ 667 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || 668 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || 669 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || 670 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || 671 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { 672 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); 673 ret = OMX_ErrorInsufficientResources; 674 goto EXIT; 675 } 676 677 /* alloc context, open, querycap */ 678 pVp8Dec->hMFCVp8Handle.hMFCHandle = pVideoDec->pDecOps->Init(); 679 if (pVp8Dec->hMFCVp8Handle.hMFCHandle == NULL) { 680 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); 681 ret = OMX_ErrorInsufficientResources; 682 goto EXIT; 683 } 684 685 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); 686 687 /* input buffer info: only 2 config values needed */ 688 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE / 2; 689 bufferConf.eCompressionFormat = VIDEO_CODING_VP8; 690 691 /* set input buffer geometry */ 692 if (pInbufOps->Set_Geometry) { 693 if (pInbufOps->Set_Geometry(pVp8Dec->hMFCVp8Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { 694 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); 695 ret = OMX_ErrorInsufficientResources; 696 goto EXIT; 697 } 698 } 699 700 /* setup input buffer */ 701 if (pInbufOps->Setup(pVp8Dec->hMFCVp8Handle.hMFCHandle, MFC_INPUT_BUFFER_NUM_MAX) != VIDEO_ERROR_NONE) { 702 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); 703 ret = OMX_ErrorInsufficientResources; 704 goto EXIT; 705 } 706 707 /* get input buffer info */ 708 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 709 Exynos_OSAL_Memset(&bufferInfo, 0, sizeof(bufferInfo)); 710 711 if (pInbufOps->Get_BufferInfo) { 712 if (pInbufOps->Get_BufferInfo(pVp8Dec->hMFCVp8Handle.hMFCHandle, i, &bufferInfo) != VIDEO_ERROR_NONE) { 713 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info"); 714 ret = OMX_ErrorInsufficientResources; 715 goto EXIT; 716 } 717 } 718 719 pVideoDec->MFCDecInputBuffer[i].VirAddr = (void *)bufferInfo.planes[0].addr; 720 pVideoDec->MFCDecInputBuffer[i].PhyAddr = NULL; 721 pVideoDec->MFCDecInputBuffer[i].bufferSize = bufferInfo.planes[0].allocSize; 722 pVideoDec->MFCDecInputBuffer[i].dataSize = 0; 723 } 724 725 pVideoDec->indexInputBuffer = 0; 726 pVideoDec->bFirstFrame = OMX_TRUE; 727 728 pVideoDec->NBDecThread.bExitDecodeThread = OMX_FALSE; 729 pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; 730 pVideoDec->NBDecThread.oneFrameSize = 0; 731 Exynos_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameStart)); 732 Exynos_OSAL_SemaphoreCreate(&(pVideoDec->NBDecThread.hDecFrameEnd)); 733 if (OMX_ErrorNone == Exynos_OSAL_ThreadCreate(&pVideoDec->NBDecThread.hNBDecodeThread, 734 Exynos_MFC_DecodeThread, 735 pOMXComponent)) { 736 pVp8Dec->hMFCVp8Handle.returnCodec = VIDEO_TRUE; 737 } 738 739 pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; 740 pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[0].PhyAddr; 741 pExynosComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[0].VirAddr; 742 pExynosComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[0].bufferSize; 743 744 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); 745 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); 746 pVp8Dec->hMFCVp8Handle.indexTimestamp = 0; 747 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0; 748 749 pExynosComponent->getAllDelayBuffer = OMX_FALSE; 750 751#ifdef USE_ANB 752#if defined(USE_CSC_FIMC) || defined(USE_CSC_GSCALER) 753 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { 754 csc_method = CSC_METHOD_PREFER_HW; 755 } 756#endif 757#endif 758 pVideoDec->csc_handle = csc_init(&csc_method); 759 pVideoDec->csc_set_format = OMX_FALSE; 760 761EXIT: 762 FunctionOut(); 763 764 return ret; 765} 766 767/* MFC Terminate */ 768OMX_ERRORTYPE Exynos_MFC_VP8Dec_Terminate( 769 OMX_COMPONENTTYPE *pOMXComponent) 770{ 771 OMX_ERRORTYPE ret = OMX_ErrorNone; 772 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 773 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 774 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 775 OMX_PTR hMFCHandle = NULL; 776 ExynosVideoDecOps *pDecOps = pVideoDec->pDecOps; 777 ExynosVideoDecBufferOps *pInbufOps = pVideoDec->pInbufOps; 778 ExynosVideoDecBufferOps *pOutbufOps = pVideoDec->pOutbufOps; 779 780 FunctionIn(); 781 782#ifdef CONFIG_MFC_FPS 783 Exynos_OSAL_PerfPrint("[DEC]", PERF_ID_DEC); 784 Exynos_OSAL_PerfPrint("[CSC]", PERF_ID_CSC); 785#endif 786 787 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 788 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 789 790 pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = NULL; 791 pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = NULL; 792 pExynosComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; 793 pExynosComponent->processData[INPUT_PORT_INDEX].allocSize = 0; 794 795 if (pVideoDec->NBDecThread.hNBDecodeThread != NULL) { 796 pVideoDec->NBDecThread.bExitDecodeThread = OMX_TRUE; 797 Exynos_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); 798 Exynos_OSAL_ThreadTerminate(pVideoDec->NBDecThread.hNBDecodeThread); 799 pVideoDec->NBDecThread.hNBDecodeThread = NULL; 800 } 801 802 if(pVideoDec->NBDecThread.hDecFrameEnd != NULL) { 803 Exynos_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameEnd); 804 pVideoDec->NBDecThread.hDecFrameEnd = NULL; 805 } 806 807 if(pVideoDec->NBDecThread.hDecFrameStart != NULL) { 808 Exynos_OSAL_SemaphoreTerminate(pVideoDec->NBDecThread.hDecFrameStart); 809 pVideoDec->NBDecThread.hDecFrameStart = NULL; 810 } 811 812 if (hMFCHandle != NULL) { 813 pInbufOps->Stop(hMFCHandle); 814 pOutbufOps->Stop(hMFCHandle); 815 pDecOps->Finalize(hMFCHandle); 816 817 free(pInbufOps); 818 free(pOutbufOps); 819 free(pDecOps); 820 821 pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL; 822 } 823 824 if (pVideoDec->csc_handle != NULL) { 825 csc_deinit(pVideoDec->csc_handle); 826 pVideoDec->csc_handle = NULL; 827 } 828 829EXIT: 830 FunctionOut(); 831 832 return ret; 833} 834 835OMX_ERRORTYPE Exynos_MFC_VP8_Decode_Configure( 836 OMX_COMPONENTTYPE *pOMXComponent, 837 EXYNOS_OMX_DATA *pInputData, 838 EXYNOS_OMX_DATA *pOutputData) 839{ 840 OMX_ERRORTYPE ret = OMX_ErrorNone; 841 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 842 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 843 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 844 OMX_HANDLETYPE hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 845 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 846 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 847 OMX_U32 oneFrameSize = pInputData->dataLen; 848 OMX_S32 setConfVal = 0; 849 ExynosVideoDecOps *pDecOps = pVideoDec->pDecOps; 850 ExynosVideoDecBufferOps *pInbufOps = pVideoDec->pInbufOps; 851 ExynosVideoDecBufferOps *pOutbufOps = pVideoDec->pOutbufOps; 852 ExynosVideoGeometry bufferConf; 853 854 int i, nOutbufs; 855 856 FunctionIn(); 857 858 if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { 859 pOutputData->timeStamp = pInputData->timeStamp; 860 pOutputData->nFlags = pInputData->nFlags; 861 ret = OMX_ErrorNone; 862 goto EXIT; 863 } 864 865 if (pDecOps->Set_DisplayDelay && (pVideoDec->bThumbnailMode == OMX_TRUE)) { 866 setConfVal = 0; 867 pDecOps->Set_DisplayDelay(hMFCHandle, setConfVal); 868 } 869 870 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); 871 872 /* set geometry for dest */ 873 if (pOutbufOps->Set_Geometry) { 874 /* only output color format is needed to set */ 875 bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; 876 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { 877 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); 878 ret = OMX_ErrorInsufficientResources; 879 goto EXIT; 880 } 881 } 882 883 /* input buffer enqueue for header parsing */ 884 if (pInbufOps->Enqueue(hMFCHandle, 885 (unsigned char **)&pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer, 886 (unsigned int *)&oneFrameSize, 1, NULL) != VIDEO_ERROR_NONE) { 887 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); 888 ret = OMX_ErrorInsufficientResources; 889 goto EXIT; 890 } 891 892 /* start header parsing */ 893 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { 894 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); 895 ret = OMX_ErrorInsufficientResources; 896 goto EXIT; 897 } 898 899 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); 900 901 /* get geometry for output */ 902 if (pOutbufOps->Get_Geometry) { 903 if (pOutbufOps->Get_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { 904 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); 905 ret = OMX_ErrorInsufficientResources; 906 goto EXIT; 907 } 908 } 909 910 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != bufferConf.nFrameWidth) || 911 (pExynosInputPort->portDefinition.format.video.nFrameHeight != bufferConf.nFrameHeight)) { 912 pExynosInputPort->portDefinition.format.video.nFrameWidth = bufferConf.nFrameWidth; 913 pExynosInputPort->portDefinition.format.video.nFrameHeight = bufferConf.nFrameHeight; 914 pExynosInputPort->portDefinition.format.video.nStride = ((bufferConf.nFrameWidth + 15) & (~15)); 915 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((bufferConf.nFrameHeight + 15) & (~15)); 916 917 Exynos_UpdateFrameSize(pOMXComponent); 918 919 /** Send Port Settings changed call back **/ 920 (*(pExynosComponent->pCallbacks->EventHandler)) 921 (pOMXComponent, 922 pExynosComponent->callbackData, 923 OMX_EventPortSettingsChanged, /* The command was completed */ 924 OMX_DirOutput, /* This is the port index */ 925 0, 926 NULL); 927 } 928 929 /* should be done before prepare output buffer */ 930 if (pExynosOutputPort->portDefinition.format.video.eColorFormat != OMX_SEC_COLOR_FormatNV12TPhysicalAddress) { 931 if (pVideoDec->pDecOps->Enable_Cacheable) { 932 if (pVideoDec->pDecOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { 933 ret = OMX_ErrorInsufficientResources; 934 goto EXIT; 935 } 936 } 937 } 938 939 /* get dpb count */ 940 nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); 941 if (nOutbufs < 0) { 942 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Invalid DPB count"); 943 ret = OMX_ErrorInsufficientResources; 944 goto EXIT; 945 } 946 947 if (pVideoDec->bThumbnailMode == OMX_FALSE) 948 nOutbufs += VP8_DEC_NUM_OF_EXTRA_BUFFERS; 949 950 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { 951 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); 952 ret = OMX_ErrorInsufficientResources; 953 goto EXIT; 954 } 955 956 if (pOutbufOps->Enqueue_All) { 957 if (pOutbufOps->Enqueue_All(hMFCHandle) != VIDEO_ERROR_NONE) { 958 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to flush all output buffer"); 959 ret = OMX_ErrorInsufficientResources; 960 goto EXIT; 961 } 962 } 963 964 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { 965 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); 966 ret = OMX_ErrorInsufficientResources; 967 goto EXIT; 968 } 969 970 if (pInbufOps->Dequeue(hMFCHandle) == NULL) { 971 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to wait input buffer"); 972 ret = OMX_ErrorInsufficientResources; 973 goto EXIT; 974 } 975 976 pVp8Dec->hMFCVp8Handle.bConfiguredMFC = OMX_TRUE; 977 pVp8Dec->hMFCVp8Handle.returnCodec = VIDEO_TRUE; 978 pOutputData->timeStamp = pInputData->timeStamp; 979 pOutputData->nFlags = pInputData->nFlags; 980 981 ret = OMX_ErrorInputDataDecodeYet; 982 983EXIT: 984 FunctionOut(); 985 return ret; 986} 987OMX_ERRORTYPE Exynos_MFC_VP8_Decode_Nonblock( 988 OMX_COMPONENTTYPE *pOMXComponent, 989 EXYNOS_OMX_DATA *pInputData, 990 EXYNOS_OMX_DATA *pOutputData) 991{ 992 OMX_ERRORTYPE ret = OMX_ErrorNone; 993 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 994 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 995 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 996 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 997 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 998 OMX_HANDLETYPE hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 999 OMX_U32 oneFrameSize = pInputData->dataLen; 1000 OMX_S32 setConfVal = 0; 1001 OMX_U32 FrameBufferYSize = 0; 1002 OMX_U32 FrameBufferUVSize = 0; 1003 OMX_BOOL outputDataValid = OMX_FALSE; 1004 ExynosVideoDecOps *pDecOps = pVideoDec->pDecOps; 1005 ExynosVideoDecBufferOps *pInbufOps = pVideoDec->pInbufOps; 1006 ExynosVideoDecBufferOps *pOutbufOps = pVideoDec->pOutbufOps; 1007 1008 OMX_PTR outputYPhyAddr, outputCPhyAddr, outputYVirAddr, outputCVirAddr; 1009 int bufWidth, bufHeight, outputImgWidth, outputImgHeight; 1010 1011 FunctionIn(); 1012 1013 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFC == OMX_FALSE) { 1014 ret = Exynos_MFC_VP8_Decode_Configure(pOMXComponent, pInputData, pOutputData); 1015 goto EXIT; 1016 } 1017 1018#ifndef FULL_FRAME_SEARCH 1019 if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && 1020 (pExynosComponent->bUseFlagEOF == OMX_FALSE)) 1021 pExynosComponent->bUseFlagEOF = OMX_TRUE; 1022#endif 1023 1024 pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->timeStamp; 1025 pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pInputData->nFlags; 1026 1027 if (pVideoDec->bFirstFrame == OMX_FALSE) { 1028 ExynosVideoFrameStatusType status = VIDEO_FRAME_STATUS_UNKNOWN; 1029 OMX_S32 indexTimestamp = 0; 1030 1031 /* wait for mfc decode done */ 1032 if (pVideoDec->NBDecThread.bDecoderRun == OMX_TRUE) { 1033 Exynos_OSAL_SemaphoreWait(pVideoDec->NBDecThread.hDecFrameEnd); 1034 pVideoDec->NBDecThread.bDecoderRun = OMX_FALSE; 1035 } 1036 1037 Exynos_OSAL_SleepMillisec(0); 1038 1039 if (pVideoDec->pOutbuf != NULL) { 1040 status = pVideoDec->pOutbuf->displayStatus; 1041 outputYVirAddr = pVideoDec->pOutbuf->planes[0].addr; 1042 outputCVirAddr = pVideoDec->pOutbuf->planes[1].addr; 1043 } 1044 1045 outputImgWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth; 1046 outputImgHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight; 1047 1048 bufWidth = (outputImgWidth + 15) & (~15); 1049 bufHeight = (outputImgHeight + 15) & (~15); 1050 FrameBufferYSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputImgWidth) * ALIGN_TO_32B(outputImgHeight)); 1051 FrameBufferUVSize = ALIGN_TO_8KB(ALIGN_TO_128B(outputImgWidth) * ALIGN_TO_32B(outputImgHeight/2)); 1052 1053 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); 1054 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { 1055 pOutputData->timeStamp = pInputData->timeStamp; 1056 pOutputData->nFlags = pInputData->nFlags; 1057 } else { 1058 /* For timestamp correction. if mfc support frametype detect */ 1059 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoDec->pOutbuf->frameType); 1060#ifdef NEED_TIMESTAMP_REORDER 1061 if (pVideoDec->pOutbuf->frameType == VIDEO_FRAME_I) { 1062 pOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; 1063 pOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; 1064 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; 1065 } else { 1066 pOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1067 pOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1068 } 1069#else 1070 pOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; 1071 pOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; 1072#endif 1073 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs)", pOutputData->timeStamp, pOutputData->timeStamp / 1E6); 1074 } 1075 1076 if ((status == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || 1077 (status == VIDEO_FRAME_STATUS_DISPLAY_ONLY)) { 1078 outputDataValid = OMX_TRUE; 1079 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; 1080 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; 1081 } 1082 if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) 1083 outputDataValid = OMX_FALSE; 1084 1085 if ((status == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || 1086 (pExynosComponent->getAllDelayBuffer == OMX_TRUE)) 1087 ret = OMX_ErrorInputDataDecodeYet; 1088 1089 if (status == VIDEO_FRAME_STATUS_DECODING_ONLY) { 1090 if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && 1091 ((pExynosComponent->bSaveFlagEOS == OMX_TRUE) || (pExynosComponent->getAllDelayBuffer == OMX_TRUE))) { 1092 pInputData->nFlags |= OMX_BUFFERFLAG_EOS; 1093 pExynosComponent->getAllDelayBuffer = OMX_TRUE; 1094 ret = OMX_ErrorInputDataDecodeYet; 1095 } else { 1096 ret = OMX_ErrorNone; 1097 } 1098 outputDataValid = OMX_FALSE; 1099 } 1100 1101#ifdef FULL_FRAME_SEARCH 1102 if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && 1103 (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) { 1104 pInputData->nFlags |= OMX_BUFFERFLAG_EOS; 1105 pExynosComponent->getAllDelayBuffer = OMX_TRUE; 1106 ret = OMX_ErrorInputDataDecodeYet; 1107 } else 1108#endif 1109 if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { 1110 pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); 1111 pExynosComponent->getAllDelayBuffer = OMX_TRUE; 1112 ret = OMX_ErrorInputDataDecodeYet; 1113 } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { 1114 pExynosComponent->getAllDelayBuffer = OMX_FALSE; 1115 ret = OMX_ErrorNone; 1116 } 1117 } else { 1118 pOutputData->timeStamp = pInputData->timeStamp; 1119 pOutputData->nFlags = pInputData->nFlags; 1120 1121 if ((pExynosComponent->bSaveFlagEOS == OMX_TRUE) || 1122 (pExynosComponent->getAllDelayBuffer == OMX_TRUE) || 1123 (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { 1124 pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; 1125 pExynosComponent->getAllDelayBuffer = OMX_FALSE; 1126 } 1127 1128 if ((pVideoDec->bFirstFrame == OMX_TRUE) && 1129 ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && 1130 ((pInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) { 1131 pOutputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); 1132 } 1133 1134 outputDataValid = OMX_FALSE; 1135 1136 /* ret = OMX_ErrorUndefined; */ 1137 ret = OMX_ErrorNone; 1138 } 1139 1140 if (ret == OMX_ErrorInputDataDecodeYet) { 1141 pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; 1142 pVideoDec->indexInputBuffer++; 1143 pVideoDec->indexInputBuffer %= MFC_INPUT_BUFFER_NUM_MAX; 1144 pVp8Dec->hMFCVp8Handle.pMFCStreamBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; 1145 pVp8Dec->hMFCVp8Handle.pMFCStreamPhyBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].PhyAddr; 1146 pExynosComponent->processData[INPUT_PORT_INDEX].dataBuffer = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].VirAddr; 1147 pExynosComponent->processData[INPUT_PORT_INDEX].allocSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].bufferSize; 1148 oneFrameSize = pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize; 1149 } 1150 1151 if ((Check_VP8_StartCode(pInputData->dataBuffer, oneFrameSize) == OMX_TRUE) && 1152 ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) { 1153 if ((ret != OMX_ErrorInputDataDecodeYet) || (pExynosComponent->getAllDelayBuffer == OMX_TRUE)) { 1154 pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp); 1155 pVp8Dec->hMFCVp8Handle.indexTimestamp++; 1156 pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; 1157 } 1158 1159 pVideoDec->MFCDecInputBuffer[pVideoDec->indexInputBuffer].dataSize = oneFrameSize; 1160 pVideoDec->NBDecThread.oneFrameSize = oneFrameSize; 1161 1162 /* mfc decode start */ 1163 Exynos_OSAL_SemaphorePost(pVideoDec->NBDecThread.hDecFrameStart); 1164 pVideoDec->NBDecThread.bDecoderRun = OMX_TRUE; 1165 pVp8Dec->hMFCVp8Handle.returnCodec = VIDEO_TRUE; 1166 1167 Exynos_OSAL_SleepMillisec(0); 1168 1169 if ((pVideoDec->bFirstFrame == OMX_TRUE) && 1170 (pExynosComponent->bSaveFlagEOS == OMX_TRUE) && 1171 (outputDataValid == OMX_FALSE)) { 1172 ret = OMX_ErrorInputDataDecodeYet; 1173 } 1174 1175 pVideoDec->bFirstFrame = OMX_FALSE; 1176 } else { 1177 if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) 1178 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; 1179 } 1180 1181 /** Fill Output Buffer **/ 1182 if (outputDataValid == OMX_TRUE) { 1183 void *pOutputBuf = (void *)pOutputData->dataBuffer; 1184 void *pSrcBuf[3] = {NULL, }; 1185 void *pYUVBuf[3] = {NULL, }; 1186 unsigned int csc_src_color_format, csc_dst_color_format; 1187 CSC_METHOD csc_method = CSC_METHOD_SW; 1188 unsigned int cacheable = 1; 1189 int frameSize = bufWidth * bufHeight; 1190 int width = outputImgWidth; 1191 int height = outputImgHeight; 1192 int imageSize = outputImgWidth * outputImgHeight; 1193 1194 pSrcBuf[0] = outputYVirAddr; 1195 pSrcBuf[1] = outputCVirAddr; 1196 1197 pYUVBuf[0] = (unsigned char *)pOutputBuf; 1198 pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize; 1199 pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4; 1200 pOutputData->dataLen = (imageSize * 3) / 2; 1201 1202#ifdef USE_ANB 1203 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { 1204 unsigned int stride; 1205 Exynos_OSAL_LockANB(pOutputData->dataBuffer, width, height, pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat, &stride, pYUVBuf); 1206 width = stride; 1207 pOutputData->dataLen = sizeof(void *); 1208 } 1209#endif 1210 if ((pVideoDec->bThumbnailMode == OMX_FALSE) && 1211 (pExynosOutputPort->portDefinition.format.video.eColorFormat == OMX_SEC_COLOR_FormatNV12TPhysicalAddress)) { 1212 /* if use Post copy address structure */ 1213 Exynos_OSAL_Memcpy(pYUVBuf[0], &(outputYPhyAddr), sizeof(outputYPhyAddr)); 1214 Exynos_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 1), &(outputCPhyAddr), sizeof(outputCPhyAddr)); 1215 Exynos_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 2), &(outputYVirAddr), sizeof(outputYVirAddr)); 1216 Exynos_OSAL_Memcpy((unsigned char *)pYUVBuf[0] + (sizeof(void *) * 3), &(outputCVirAddr), sizeof(outputCVirAddr)); 1217 pOutputData->dataLen = (width * height * 3) / 2; 1218 } else { 1219 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "YUV420 SP/P Output mode"); 1220#ifdef CONFIG_MFC_FPS 1221 Exynos_OSAL_PerfStart(PERF_ID_CSC); 1222#endif 1223 switch (pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { 1224 case OMX_SEC_COLOR_FormatNV12Tiled: 1225 Exynos_OSAL_Memcpy(pOutputBuf, outputYVirAddr, FrameBufferYSize); 1226 Exynos_OSAL_Memcpy((unsigned char *)pOutputBuf + FrameBufferYSize, outputCVirAddr, FrameBufferUVSize); 1227 pOutputData->dataLen = FrameBufferYSize + FrameBufferUVSize; 1228 break; 1229 case OMX_COLOR_FormatYUV420SemiPlanar: 1230 case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar: 1231 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); 1232 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 1233 break; 1234 case OMX_COLOR_FormatYUV420Planar: 1235 default: 1236 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_SEC_COLOR_FormatNV12Tiled); 1237 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); 1238 break; 1239 } 1240 1241 csc_get_method(pVideoDec->csc_handle, &csc_method); 1242#ifdef ENABLE_PHYSICAL_ADDRESS 1243 if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) && (csc_method == CSC_METHOD_HW)) { 1244 Exynos_OSAL_GetPhysANB(pOutputData->dataBuffer, pYUVBuf); 1245 pSrcBuf[0] = outputYPhyAddr; 1246 pSrcBuf[1] = outputCPhyAddr; 1247 } 1248#endif 1249 if (pVideoDec->csc_set_format == OMX_FALSE) { 1250 csc_set_src_format( 1251 pVideoDec->csc_handle, /* handle */ 1252 width, /* width */ 1253 height, /* height */ 1254 0, /* crop_left */ 1255 0, /* crop_right */ 1256 width, /* crop_width */ 1257 height, /* crop_height */ 1258 csc_src_color_format, /* color_format */ 1259 cacheable); /* cacheable */ 1260 csc_set_dst_format( 1261 pVideoDec->csc_handle, /* handle */ 1262 width, /* width */ 1263 height, /* height */ 1264 0, /* crop_left */ 1265 0, /* crop_right */ 1266 width, /* crop_width */ 1267 height, /* crop_height */ 1268 csc_dst_color_format, /* color_format */ 1269 cacheable); /* cacheable */ 1270 pVideoDec->csc_set_format = OMX_TRUE; 1271 } 1272 csc_set_src_buffer( 1273 pVideoDec->csc_handle, /* handle */ 1274 pSrcBuf[0], /* y addr */ 1275 pSrcBuf[1], /* u addr or uv addr */ 1276 pSrcBuf[2], /* v addr or none */ 1277 0); /* ion fd */ 1278 csc_set_dst_buffer( 1279 pVideoDec->csc_handle, 1280 pYUVBuf[0], /* y addr */ 1281 pYUVBuf[1], /* u addr or uv addr */ 1282 pYUVBuf[2], /* v addr or none */ 1283 0); /* ion fd */ 1284 csc_convert(pVideoDec->csc_handle); 1285 1286#ifdef CONFIG_MFC_FPS 1287 Exynos_OSAL_PerfStop(PERF_ID_CSC); 1288#endif 1289 } 1290#ifdef USE_ANB 1291 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { 1292 Exynos_OSAL_UnlockANB(pOutputData->dataBuffer); 1293 } 1294#endif 1295 /* enqueue all available output buffers */ 1296 pOutbufOps->Enqueue_All(hMFCHandle); 1297 } else { 1298 pOutputData->dataLen = 0; 1299 } 1300 1301EXIT: 1302 FunctionOut(); 1303 1304 return ret; 1305} 1306 1307/* MFC Decode */ 1308OMX_ERRORTYPE Exynos_MFC_VP8Dec_bufferProcess( 1309 OMX_COMPONENTTYPE *pOMXComponent, 1310 EXYNOS_OMX_DATA *pInputData, 1311 EXYNOS_OMX_DATA *pOutputData) 1312{ 1313 OMX_ERRORTYPE ret = OMX_ErrorNone; 1314 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1315 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1316 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1317 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1318 OMX_BOOL endOfFrame = OMX_FALSE; 1319 1320 FunctionIn(); 1321 1322 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_ENABLED(pExynosOutputPort)) || 1323 (!CHECK_PORT_POPULATED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { 1324 ret = OMX_ErrorNone; 1325 goto EXIT; 1326 } 1327 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent)) { 1328 ret = OMX_ErrorNone; 1329 goto EXIT; 1330 } 1331 1332 ret = Exynos_MFC_VP8_Decode_Nonblock(pOMXComponent, pInputData, pOutputData); 1333 if (ret != OMX_ErrorNone) { 1334 if (ret == OMX_ErrorInputDataDecodeYet) { 1335 pOutputData->usedDataLen = 0; 1336 pOutputData->remainDataLen = pOutputData->dataLen; 1337 } else { 1338 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 1339 pExynosComponent->callbackData, 1340 OMX_EventError, ret, 0, NULL); 1341 } 1342 } else { 1343 pInputData->previousDataLen = pInputData->dataLen; 1344 pInputData->usedDataLen += pInputData->dataLen; 1345 pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; 1346 pInputData->dataLen -= pInputData->usedDataLen; 1347 pInputData->usedDataLen = 0; 1348 1349 pOutputData->usedDataLen = 0; 1350 pOutputData->remainDataLen = pOutputData->dataLen; 1351 } 1352 1353EXIT: 1354 FunctionOut(); 1355 1356 return ret; 1357} 1358 1359OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( 1360 OMX_HANDLETYPE hComponent, 1361 OMX_STRING componentName) 1362{ 1363 OMX_ERRORTYPE ret = OMX_ErrorNone; 1364 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1365 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1366 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1367 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 1368 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 1369 1370 int i = 0; 1371 1372 FunctionIn(); 1373 1374 if ((hComponent == NULL) || (componentName == NULL)) { 1375 ret = OMX_ErrorBadParameter; 1376 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 1377 goto EXIT; 1378 } 1379 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) { 1380 ret = OMX_ErrorBadParameter; 1381 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); 1382 goto EXIT; 1383 } 1384 1385 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1386 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); 1387 if (ret != OMX_ErrorNone) { 1388 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1389 goto EXIT; 1390 } 1391 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1392 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; 1393 1394 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); 1395 if (pExynosComponent->componentName == NULL) { 1396 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1397 ret = OMX_ErrorInsufficientResources; 1398 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1399 goto EXIT; 1400 } 1401 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); 1402 1403 pVp8Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8DEC_HANDLE)); 1404 if (pVp8Dec == NULL) { 1405 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1406 ret = OMX_ErrorInsufficientResources; 1407 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1408 goto EXIT; 1409 } 1410 Exynos_OSAL_Memset(pVp8Dec, 0, sizeof(EXYNOS_VP8DEC_HANDLE)); 1411 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1412 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec; 1413 1414 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_DEC); 1415 1416 /* Set componentVersion */ 1417 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; 1418 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; 1419 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; 1420 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; 1421 /* Set specVersion */ 1422 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; 1423 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; 1424 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; 1425 pExynosComponent->specVersion.s.nStep = STEP_NUMBER; 1426 1427 /* Android CapabilityFlags */ 1428 pExynosComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; 1429 pExynosComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; 1430 pExynosComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; 1431 pExynosComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; 1432 pExynosComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; 1433 pExynosComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; 1434 pExynosComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; 1435 pExynosComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; 1436 1437 /* Input port */ 1438 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1439 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; 1440 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; 1441 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ 1442 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1443 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; 1444 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; 1445 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); 1446 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8"); 1447 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1448 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1449 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1450 pExynosPort->portDefinition.bEnabled = OMX_TRUE; 1451 1452 /* Output port */ 1453 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1454 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; 1455 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; 1456 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ 1457 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1458 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; 1459 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1460 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); 1461 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1462 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1463 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1464 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 1465 pExynosPort->portDefinition.bEnabled = OMX_TRUE; 1466 1467 pOMXComponent->GetParameter = &Exynos_MFC_VP8Dec_GetParameter; 1468 pOMXComponent->SetParameter = &Exynos_MFC_VP8Dec_SetParameter; 1469 pOMXComponent->GetConfig = &Exynos_MFC_VP8Dec_GetConfig; 1470 pOMXComponent->SetConfig = &Exynos_MFC_VP8Dec_SetConfig; 1471 pOMXComponent->GetExtensionIndex = &Exynos_MFC_VP8Dec_GetExtensionIndex; 1472 pOMXComponent->ComponentRoleEnum = &Exynos_MFC_VP8Dec_ComponentRoleEnum; 1473 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; 1474 1475 pExynosComponent->exynos_mfc_componentInit = &Exynos_MFC_VP8Dec_Init; 1476 pExynosComponent->exynos_mfc_componentTerminate = &Exynos_MFC_VP8Dec_Terminate; 1477 pExynosComponent->exynos_mfc_bufferProcess = &Exynos_MFC_VP8Dec_bufferProcess; 1478 pExynosComponent->exynos_checkInputFrame = &Check_VP8_Frame; 1479 1480 pExynosComponent->currentState = OMX_StateLoaded; 1481 1482 ret = OMX_ErrorNone; 1483 1484EXIT: 1485 FunctionOut(); 1486 1487 return ret; 1488} 1489 1490OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( 1491 OMX_HANDLETYPE hComponent) 1492{ 1493 OMX_ERRORTYPE ret = OMX_ErrorNone; 1494 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1495 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1496 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 1497 1498 FunctionIn(); 1499 1500 if (hComponent == NULL) { 1501 ret = OMX_ErrorBadParameter; 1502 goto EXIT; 1503 } 1504 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1505 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1506 1507 Exynos_OSAL_Free(pExynosComponent->componentName); 1508 pExynosComponent->componentName = NULL; 1509 1510 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1511 if (pVp8Dec != NULL) { 1512 Exynos_OSAL_Free(pVp8Dec); 1513 pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; 1514 } 1515 1516 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1517 if (ret != OMX_ErrorNone) { 1518 goto EXIT; 1519 } 1520 1521 ret = OMX_ErrorNone; 1522 1523EXIT: 1524 FunctionOut(); 1525 1526 return ret; 1527} 1528