Exynos_OMX_Vp8dec.c revision ef059a025332fc3b7d68e1b8bd1f7abe34cf37e9
1/* 2 * 3 * Copyright 2012 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 * @author SeungBeom Kim (sbcrux.kim@samsung.com) 23 * @version 2.0.0 24 * @history 25 * 2012.02.20 : Create 26 */ 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#include "Exynos_OMX_Macros.h" 33#include "Exynos_OMX_Basecomponent.h" 34#include "Exynos_OMX_Baseport.h" 35#include "Exynos_OMX_Vdec.h" 36#include "Exynos_OSAL_ETC.h" 37#include "Exynos_OSAL_Semaphore.h" 38#include "Exynos_OSAL_Thread.h" 39#include "library_register.h" 40#include "Exynos_OMX_Vp8dec.h" 41#include "ExynosVideoApi.h" 42#include "Exynos_OSAL_SharedMemory.h" 43#include "Exynos_OSAL_Event.h" 44 45#ifdef USE_ANB 46#include "Exynos_OSAL_Android.h" 47#endif 48 49/* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */ 50/* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */ 51#include "csc.h" 52 53#undef EXYNOS_LOG_TAG 54#define EXYNOS_LOG_TAG "EXYNOS_VP8_DEC" 55#define EXYNOS_LOG_OFF 56//#define EXYNOS_TRACE_ON 57#include "Exynos_OSAL_Log.h" 58 59#define VP8_DEC_NUM_OF_EXTRA_BUFFERS 7 60 61//#define FULL_FRAME_SEARCH /* Full frame search not support*/ 62 63static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize) 64{ 65 OMX_ERRORTYPE ret = OMX_ErrorNone; 66 67EXIT: 68 return ret; 69} 70 71static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[]) 72{ 73 OMX_ERRORTYPE ret = OMX_ErrorNone; 74 ExynosVideoBuffer *pCodecBuffer; 75 76 if (codecBuffer == NULL) { 77 ret = OMX_ErrorBadParameter; 78 goto EXIT; 79 } 80 81 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer; 82 83 if (addr != NULL) { 84 addr[0] = pCodecBuffer->planes[0].addr; 85 addr[1] = pCodecBuffer->planes[1].addr; 86 addr[2] = pCodecBuffer->planes[2].addr; 87 } 88 89 if (size != NULL) { 90 size[0] = pCodecBuffer->planes[0].allocSize; 91 size[1] = pCodecBuffer->planes[1].allocSize; 92 size[2] = pCodecBuffer->planes[2].allocSize; 93 } 94 95EXIT: 96 return ret; 97} 98 99static int Check_VP8_Frame( 100 OMX_U8 *pInputStream, 101 int buffSize, 102 OMX_U32 flag, 103 OMX_BOOL bPreviousFrameEOF, 104 OMX_BOOL *pbEndOfFrame) 105{ 106 /* Uncompressed data Chunk comprises a common 107 (for key frames and interframes) 3-byte frame tag that 108 contains four fields 109 - 1-bit frame type (0 - key frame, 1 - inter frame) 110 - 3-bit version number (0 - 3 are defined as four different 111 profiles with different decoding complexity) 112 - 1-bit show_frame flag ( 0 - current frame not for display, 113 1 - current frame is for dispaly) 114 - 19-bit field - size of the first data partition in bytes 115 116 Key Frames : frame tag followed by 7 bytes of uncompressed 117 data 118 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a) 119 Next 4-bytes: Width & height, Horizontal and vertical scale information 120 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) 121 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) 122 */ 123 int width, height; 124 int horizSscale, vertScale; 125 126 FunctionIn(); 127 128 *pbEndOfFrame = OMX_TRUE; 129 130 /*Check for Key frame*/ 131 if (!(pInputStream[0] & 0x01)){ 132 /* Key Frame Start code*/ 133 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { 134 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found"); 135 *pbEndOfFrame = OMX_FALSE; 136 } 137 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code"); 138 width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff; 139 horizSscale = pInputStream[7] >> 6; 140 height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff; 141 vertScale = pInputStream[9] >> 6; 142 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale); 143 } 144 145 FunctionOut(); 146 return buffSize; 147} 148 149OMX_BOOL Check_VP8_StartCode( 150 OMX_U8 *pInputStream, 151 OMX_U32 streamSize) 152{ 153 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize); 154 if (streamSize < 3) { 155 return OMX_FALSE; 156 } 157 158 if (!(pInputStream[0] & 0x01)){ 159 /* Key Frame Start code*/ 160 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) { 161 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP8 Key Frame Start Code not Found"); 162 return OMX_FALSE; 163 } 164 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP8 Found Key Frame Start Code"); 165 } 166 167 return OMX_TRUE; 168} 169 170OMX_ERRORTYPE VP8CodecOpen(EXYNOS_VP8DEC_HANDLE *pVp8Dec) 171{ 172 OMX_ERRORTYPE ret = OMX_ErrorNone; 173 ExynosVideoDecOps *pDecOps = NULL; 174 ExynosVideoDecBufferOps *pInbufOps = NULL; 175 ExynosVideoDecBufferOps *pOutbufOps = NULL; 176 177 FunctionIn(); 178 179 if (pVp8Dec == NULL) { 180 ret = OMX_ErrorBadParameter; 181 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 182 goto EXIT; 183 } 184 185 /* alloc ops structure */ 186 pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps)); 187 pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); 188 pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps)); 189 190 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) { 191 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer"); 192 ret = OMX_ErrorInsufficientResources; 193 goto EXIT; 194 } 195 196 pVp8Dec->hMFCVp8Handle.pDecOps = pDecOps; 197 pVp8Dec->hMFCVp8Handle.pInbufOps = pInbufOps; 198 pVp8Dec->hMFCVp8Handle.pOutbufOps = pOutbufOps; 199 200 /* function pointer mapping */ 201 pDecOps->nSize = sizeof(ExynosVideoDecOps); 202 pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps); 203 pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps); 204 205 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps); 206 207 /* check mandatory functions for decoder ops */ 208 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) || 209 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) || 210 (pDecOps->Get_FrameTag == NULL)) { 211 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); 212 ret = OMX_ErrorInsufficientResources; 213 goto EXIT; 214 } 215 216 /* check mandatory functions for buffer ops */ 217 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) || 218 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) || 219 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) || 220 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) || 221 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) { 222 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied"); 223 ret = OMX_ErrorInsufficientResources; 224 goto EXIT; 225 } 226 227 /* alloc context, open, querycap */ 228 pVp8Dec->hMFCVp8Handle.hMFCHandle = pVp8Dec->hMFCVp8Handle.pDecOps->Init(V4L2_MEMORY_DMABUF); 229 if (pVp8Dec->hMFCVp8Handle.hMFCHandle == NULL) { 230 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer"); 231 ret = OMX_ErrorInsufficientResources; 232 goto EXIT; 233 } 234 235 ret = OMX_ErrorNone; 236 237EXIT: 238 if (ret != OMX_ErrorNone) { 239 if (pDecOps != NULL) { 240 Exynos_OSAL_Free(pDecOps); 241 pVp8Dec->hMFCVp8Handle.pDecOps = NULL; 242 } 243 if (pInbufOps != NULL) { 244 Exynos_OSAL_Free(pInbufOps); 245 pVp8Dec->hMFCVp8Handle.pInbufOps = NULL; 246 } 247 if (pOutbufOps != NULL) { 248 Exynos_OSAL_Free(pOutbufOps); 249 pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL; 250 } 251 } 252 253 FunctionOut(); 254 255 return ret; 256} 257 258OMX_ERRORTYPE VP8CodecClose(EXYNOS_VP8DEC_HANDLE *pVp8Dec) 259{ 260 OMX_ERRORTYPE ret = OMX_ErrorNone; 261 void *hMFCHandle = NULL; 262 ExynosVideoDecOps *pDecOps = NULL; 263 ExynosVideoDecBufferOps *pInbufOps = NULL; 264 ExynosVideoDecBufferOps *pOutbufOps = NULL; 265 266 FunctionIn(); 267 268 if (pVp8Dec == NULL) { 269 ret = OMX_ErrorBadParameter; 270 goto EXIT; 271 } 272 273 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 274 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 275 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 276 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 277 278 if (hMFCHandle != NULL) { 279 pDecOps->Finalize(hMFCHandle); 280 pVp8Dec->hMFCVp8Handle.hMFCHandle = NULL; 281 } 282 if (pOutbufOps != NULL) { 283 Exynos_OSAL_Free(pOutbufOps); 284 pVp8Dec->hMFCVp8Handle.pOutbufOps = NULL; 285 } 286 if (pInbufOps != NULL) { 287 Exynos_OSAL_Free(pInbufOps); 288 pVp8Dec->hMFCVp8Handle.pInbufOps = NULL; 289 } 290 if (pDecOps != NULL) { 291 Exynos_OSAL_Free(pDecOps); 292 pVp8Dec->hMFCVp8Handle.pDecOps = NULL; 293 } 294 295 ret = OMX_ErrorNone; 296 297EXIT: 298 FunctionOut(); 299 300 return ret; 301} 302 303OMX_ERRORTYPE VP8CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) 304{ 305 OMX_ERRORTYPE ret = OMX_ErrorNone; 306 void *hMFCHandle = NULL; 307 ExynosVideoDecOps *pDecOps = NULL; 308 ExynosVideoDecBufferOps *pInbufOps = NULL; 309 ExynosVideoDecBufferOps *pOutbufOps = NULL; 310 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 311 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 312 313 FunctionIn(); 314 315 if (pOMXComponent == NULL) { 316 ret = OMX_ErrorBadParameter; 317 goto EXIT; 318 } 319 320 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; 321 if (pVideoDec == NULL) { 322 ret = OMX_ErrorBadParameter; 323 goto EXIT; 324 } 325 326 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 327 if (pVp8Dec == NULL) { 328 ret = OMX_ErrorBadParameter; 329 goto EXIT; 330 } 331 332 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 333 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 334 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 335 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 336 337 if (nPortIndex == INPUT_PORT_INDEX) 338 pInbufOps->Run(hMFCHandle); 339 else if (nPortIndex == OUTPUT_PORT_INDEX) 340 pOutbufOps->Run(hMFCHandle); 341 342 ret = OMX_ErrorNone; 343 344EXIT: 345 FunctionOut(); 346 347 return ret; 348} 349 350OMX_ERRORTYPE VP8CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) 351{ 352 OMX_ERRORTYPE ret = OMX_ErrorNone; 353 void *hMFCHandle = NULL; 354 ExynosVideoDecOps *pDecOps = NULL; 355 ExynosVideoDecBufferOps *pInbufOps = NULL; 356 ExynosVideoDecBufferOps *pOutbufOps = NULL; 357 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 358 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 359 360 FunctionIn(); 361 362 if (pOMXComponent == NULL) { 363 ret = OMX_ErrorBadParameter; 364 goto EXIT; 365 } 366 367 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; 368 if (pVideoDec == NULL) { 369 ret = OMX_ErrorBadParameter; 370 goto EXIT; 371 } 372 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 373 if (pVp8Dec == NULL) { 374 ret = OMX_ErrorBadParameter; 375 goto EXIT; 376 } 377 378 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 379 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 380 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 381 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 382 383 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) 384 pInbufOps->Stop(hMFCHandle); 385 else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) 386 pOutbufOps->Stop(hMFCHandle); 387 388 ret = OMX_ErrorNone; 389 390EXIT: 391 FunctionOut(); 392 393 return ret; 394} 395 396OMX_ERRORTYPE VP8CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) 397{ 398 OMX_ERRORTYPE ret = OMX_ErrorNone; 399 void *hMFCHandle = NULL; 400 ExynosVideoDecOps *pDecOps = NULL; 401 ExynosVideoDecBufferOps *pInbufOps = NULL; 402 ExynosVideoDecBufferOps *pOutbufOps = NULL; 403 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 404 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 405 406 FunctionIn(); 407 408 if (pOMXComponent == NULL) { 409 ret = OMX_ErrorBadParameter; 410 goto EXIT; 411 } 412 413 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle; 414 if (pVideoDec == NULL) { 415 ret = OMX_ErrorBadParameter; 416 goto EXIT; 417 } 418 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 419 if (pVp8Dec == NULL) { 420 ret = OMX_ErrorBadParameter; 421 goto EXIT; 422 } 423 424 hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 425 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 426 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 427 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 428 429 if (nPortIndex == INPUT_PORT_INDEX) { 430 if (pVp8Dec->bSourceStart == OMX_FALSE) { 431 Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent); 432 Exynos_OSAL_SleepMillisec(0); 433 } 434 } 435 436 if (nPortIndex == OUTPUT_PORT_INDEX) { 437 if (pVp8Dec->bDestinationStart == OMX_FALSE) { 438 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent); 439 Exynos_OSAL_SleepMillisec(0); 440 } 441 } 442 443 ret = OMX_ErrorNone; 444 445EXIT: 446 FunctionOut(); 447 448 return ret; 449} 450 451OMX_ERRORTYPE VP8CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex) 452{ 453 OMX_ERRORTYPE ret = OMX_ErrorNone; 454 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 455 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 456 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 457 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 458 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 459 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 460 int i, nOutbufs; 461 462 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 463 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 464 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 465 466 FunctionIn(); 467 468 if ((nPortIndex == INPUT_PORT_INDEX) && 469 (pVp8Dec->bSourceStart == OMX_TRUE)) { 470 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX); 471 472 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 473 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); 474 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]); 475 476 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); 477 } 478 479 pInbufOps->Clear_Queue(hMFCHandle); 480 } else if ((nPortIndex == OUTPUT_PORT_INDEX) && 481 (pVp8Dec->bDestinationStart == OMX_TRUE)) { 482 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; 483 ExynosVideoBuffer *pBuffer = NULL; 484 485 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX); 486 487 nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle); 488 nOutbufs += EXTRA_DPB_NUM; 489 for (i = 0; i < nOutbufs; i++) { 490 pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer); 491 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer); 492 } 493 pOutbufOps->Clear_Queue(hMFCHandle); 494 } else { 495 ret = OMX_ErrorBadParameter; 496 goto EXIT; 497 } 498 499EXIT: 500 FunctionOut(); 501 502 return ret; 503} 504 505OMX_ERRORTYPE VP8CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) 506{ 507 OMX_ERRORTYPE ret = OMX_ErrorNone; 508 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 509 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 510 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 511 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 512 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 513 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 514 OMX_U32 oneFrameSize = pSrcInputData->dataLen; 515 516 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 517 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 518 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 519 ExynosVideoGeometry bufferConf; 520 OMX_U32 inputBufferNumber = 0; 521 int i; 522 523 FunctionIn(); 524 525 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) { 526 OMX_BUFFERHEADERTYPE *OMXBuffer = NULL; 527 OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent); 528 if (OMXBuffer == NULL) { 529 ret = OMX_ErrorUndefined; 530 goto EXIT; 531 } 532 533 OMXBuffer->nTimeStamp = pSrcInputData->timeStamp; 534 OMXBuffer->nFlags = pSrcInputData->nFlags; 535 Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer); 536 537 ret = OMX_ErrorNone; 538 goto EXIT; 539 } 540 541 if (pVideoDec->bThumbnailMode == OMX_TRUE) 542 pDecOps->Set_DisplayDelay(hMFCHandle, 0); 543 544 /* input buffer info */ 545 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); 546 bufferConf.eCompressionFormat = VIDEO_CODING_VP8; 547 pInbufOps->Set_Shareable(hMFCHandle); 548 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { 549 bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth 550 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2; 551 inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM; 552 } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 553 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE; 554 inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX; 555 } 556 557 /* should be done before prepare input buffer */ 558 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { 559 ret = OMX_ErrorInsufficientResources; 560 goto EXIT; 561 } 562 563 /* set input buffer geometry */ 564 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { 565 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer"); 566 ret = OMX_ErrorInsufficientResources; 567 goto EXIT; 568 } 569 570 /* setup input buffer */ 571 if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) { 572 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer"); 573 ret = OMX_ErrorInsufficientResources; 574 goto EXIT; 575 } 576 577 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 578 /* Register input buffer */ 579 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 580 ExynosVideoPlane plane; 581 plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]; 582 plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0]; 583 plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0]; 584 if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { 585 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); 586 ret = OMX_ErrorInsufficientResources; 587 goto EXIT; 588 } 589 } 590 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { 591 /* Register input buffer */ 592 for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) { 593 ExynosVideoPlane plane; 594 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer; 595 plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen; 596 plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0]; 597 if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { 598 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer"); 599 ret = OMX_ErrorInsufficientResources; 600 goto EXIT; 601 } 602 } 603 } 604 605 /* set output geometry */ 606 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf)); 607#if 0 608 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; 609#else /* This is temporal code to fix broken thumbnail until 3D ddk supports tiled mode */ 610 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) 611 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12; 612 else 613 pVp8Dec->hMFCVp8Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED; 614#endif 615 616 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) { 617 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer"); 618 ret = OMX_ErrorInsufficientResources; 619 goto EXIT; 620 } 621 622 /* input buffer enqueue for header parsing */ 623 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize); 624 if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, 625 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) { 626 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing"); 627// ret = OMX_ErrorInsufficientResources; 628 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit; 629 goto EXIT; 630 } 631 632 /* start header parsing */ 633 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { 634 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing"); 635 ret = OMX_ErrorCodecInit; 636 goto EXIT; 637 } 638 639 /* get geometry for output */ 640 Exynos_OSAL_Memset(&pVp8Dec->hMFCVp8Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry)); 641 if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp8Dec->hMFCVp8Handle.codecOutbufConf) != VIDEO_ERROR_NONE) { 642 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info"); 643 ret = OMX_ErrorInsufficientResources; 644 goto EXIT; 645 } 646 647 /* get dpb count */ 648 pVp8Dec->hMFCVp8Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle); 649 if (pVideoDec->bThumbnailMode == OMX_FALSE) 650 pVp8Dec->hMFCVp8Handle.maxDPBNum += EXTRA_DPB_NUM; 651 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Vp8CodecSetup nOutbufs: %d", pVp8Dec->hMFCVp8Handle.maxDPBNum); 652 653 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_TRUE; 654 655 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 656 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || 657 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight)) { 658 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; 659 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; 660 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); 661 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); 662 663 Exynos_UpdateFrameSize(pOMXComponent); 664 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; 665 666 /** Send Port Settings changed call back **/ 667 (*(pExynosComponent->pCallbacks->EventHandler)) 668 (pOMXComponent, 669 pExynosComponent->callbackData, 670 OMX_EventPortSettingsChanged, /* The command was completed */ 671 OMX_DirOutput, /* This is the port index */ 672 0, 673 NULL); 674 } 675 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 676 if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth) || 677 (pExynosInputPort->portDefinition.format.video.nFrameHeight != pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight) || 678 (pExynosOutputPort->portDefinition.nBufferCountActual != pVp8Dec->hMFCVp8Handle.maxDPBNum)) { 679 pExynosInputPort->portDefinition.format.video.nFrameWidth = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth; 680 pExynosInputPort->portDefinition.format.video.nFrameHeight = pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight; 681 pExynosInputPort->portDefinition.format.video.nStride = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth + 15) & (~15)); 682 pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight + 15) & (~15)); 683 684 pExynosOutputPort->portDefinition.nBufferCountActual = pVp8Dec->hMFCVp8Handle.maxDPBNum - 2; 685 pExynosOutputPort->portDefinition.nBufferCountMin = pVp8Dec->hMFCVp8Handle.maxDPBNum - 2; 686 687 Exynos_UpdateFrameSize(pOMXComponent); 688 pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE; 689 690 /** Send Port Settings changed call back **/ 691 (*(pExynosComponent->pCallbacks->EventHandler)) 692 (pOMXComponent, 693 pExynosComponent->callbackData, 694 OMX_EventPortSettingsChanged, /* The command was completed */ 695 OMX_DirOutput, /* This is the port index */ 696 0, 697 NULL); 698 } 699 } 700 Exynos_OSAL_SleepMillisec(0); 701 ret = OMX_ErrorInputDataDecodeYet; 702 VP8CodecStop(pOMXComponent, INPUT_PORT_INDEX); 703 704EXIT: 705 FunctionOut(); 706 707 return ret; 708} 709 710OMX_ERRORTYPE VP8CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent) 711{ 712 OMX_ERRORTYPE ret = OMX_ErrorNone; 713 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 714 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 715 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 716 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 717 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 718 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 719 720 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 721 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 722 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 723 724 int i, nOutbufs; 725 726 FunctionIn(); 727 728 /* get dpb count */ 729 nOutbufs = pVp8Dec->hMFCVp8Handle.maxDPBNum; 730 731 /* should be done before prepare output buffer */ 732 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) { 733 ret = OMX_ErrorInsufficientResources; 734 goto EXIT; 735 } 736 737 pOutbufOps->Set_Shareable(hMFCHandle); 738 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) { 739 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer"); 740 ret = OMX_ErrorInsufficientResources; 741 goto EXIT; 742 } 743 744 ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE]; 745 OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; 746 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0}; 747 int plane; 748 749 nAllocLen[0] = calc_plane(pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth, 750 pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight); 751 nAllocLen[1] = calc_plane(pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameWidth, 752 pVp8Dec->hMFCVp8Handle.codecOutbufConf.nFrameHeight >> 1); 753 754 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 755 /* Register output buffer */ 756 for (i = 0; i < nOutbufs; i++) { 757 pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); 758 Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); 759 760 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { 761 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = 762 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY); 763 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) { 764 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer"); 765 ret = OMX_ErrorInsufficientResources; 766 goto EXIT; 767 } 768 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = 769 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, 770 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); 771 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane]; 772 773 planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]; 774 planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane]; 775 planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane]; 776 } 777 778 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { 779 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); 780 ret = OMX_ErrorInsufficientResources; 781 goto EXIT; 782 } 783 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr, 784 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); 785 } 786 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 787 /* Register output buffer */ 788 /*************/ 789 /* TBD */ 790 /*************/ 791#ifdef USE_ANB 792 if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) { 793 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) { 794 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { 795 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane]; 796 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane]; 797 planes[plane].allocSize = nAllocLen[plane]; 798 } 799 800 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) { 801 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer"); 802 ret = OMX_ErrorInsufficientResources; 803 goto EXIT; 804 } 805 pOutbufOps->Enqueue(hMFCHandle, planes, (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL); 806 } 807 } else { 808 ret = OMX_ErrorNotImplemented; 809 goto EXIT; 810 } 811#else 812 ret = OMX_ErrorNotImplemented; 813 goto EXIT; 814#endif 815 } 816 817 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) { 818 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer"); 819 ret = OMX_ErrorInsufficientResources; 820 goto EXIT; 821 } 822 823 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 824 VP8CodecStop (pOMXComponent, OUTPUT_PORT_INDEX); 825 } 826 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_TRUE; 827 828 ret = OMX_ErrorNone; 829 830EXIT: 831 FunctionOut(); 832 833 return ret; 834} 835 836OMX_ERRORTYPE Exynos_VP8Dec_GetParameter( 837 OMX_IN OMX_HANDLETYPE hComponent, 838 OMX_IN OMX_INDEXTYPE nParamIndex, 839 OMX_INOUT OMX_PTR pComponentParameterStructure) 840{ 841 OMX_ERRORTYPE ret = OMX_ErrorNone; 842 OMX_COMPONENTTYPE *pOMXComponent = NULL; 843 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 844 845 FunctionIn(); 846 847 if (hComponent == NULL || pComponentParameterStructure == NULL) { 848 ret = OMX_ErrorBadParameter; 849 goto EXIT; 850 } 851 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 852 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 853 if (ret != OMX_ErrorNone) { 854 goto EXIT; 855 } 856 if (pOMXComponent->pComponentPrivate == NULL) { 857 ret = OMX_ErrorBadParameter; 858 goto EXIT; 859 } 860 861 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 862 if (pExynosComponent->currentState == OMX_StateInvalid ) { 863 ret = OMX_ErrorInvalidState; 864 goto EXIT; 865 } 866 867 switch (nParamIndex) { 868 case OMX_IndexParamStandardComponentRole: 869 { 870 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; 871 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); 872 if (ret != OMX_ErrorNone) { 873 goto EXIT; 874 } 875 876 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE); 877 } 878 break; 879 case OMX_IndexParamVideoErrorCorrection: 880 { 881 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; 882 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; 883 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 884 885 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); 886 if (ret != OMX_ErrorNone) { 887 goto EXIT; 888 } 889 890 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { 891 ret = OMX_ErrorBadPortIndex; 892 goto EXIT; 893 } 894 895 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 896 pSrcErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; 897 898 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; 899 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; 900 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; 901 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; 902 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; 903 } 904 break; 905 default: 906 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); 907 break; 908 } 909EXIT: 910 FunctionOut(); 911 912 return ret; 913} 914 915OMX_ERRORTYPE Exynos_VP8Dec_SetParameter( 916 OMX_IN OMX_HANDLETYPE hComponent, 917 OMX_IN OMX_INDEXTYPE nIndex, 918 OMX_IN OMX_PTR pComponentParameterStructure) 919{ 920 OMX_ERRORTYPE ret = OMX_ErrorNone; 921 OMX_COMPONENTTYPE *pOMXComponent = NULL; 922 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 923 924 FunctionIn(); 925 926 if (hComponent == NULL || pComponentParameterStructure == NULL) { 927 ret = OMX_ErrorBadParameter; 928 goto EXIT; 929 } 930 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 931 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 932 if (ret != OMX_ErrorNone) { 933 goto EXIT; 934 } 935 if (pOMXComponent->pComponentPrivate == NULL) { 936 ret = OMX_ErrorBadParameter; 937 goto EXIT; 938 } 939 940 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 941 if (pExynosComponent->currentState == OMX_StateInvalid ) { 942 ret = OMX_ErrorInvalidState; 943 goto EXIT; 944 } 945 946 switch (nIndex) { 947 case OMX_IndexParamStandardComponentRole: 948 { 949 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; 950 951 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); 952 if (ret != OMX_ErrorNone) { 953 goto EXIT; 954 } 955 956 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) { 957 ret = OMX_ErrorIncorrectStateOperation; 958 goto EXIT; 959 } 960 961 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE)) { 962 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; 963 } else { 964 ret = OMX_ErrorBadParameter; 965 goto EXIT; 966 } 967 } 968 break; 969 case OMX_IndexParamVideoErrorCorrection: 970 { 971 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; 972 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; 973 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 974 975 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); 976 if (ret != OMX_ErrorNone) { 977 goto EXIT; 978 } 979 980 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { 981 ret = OMX_ErrorBadPortIndex; 982 goto EXIT; 983 } 984 985 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 986 pDstErrorCorrectionType = &pVp8Dec->errorCorrectionType[INPUT_PORT_INDEX]; 987 988 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; 989 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; 990 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; 991 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; 992 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; 993 } 994 break; 995 default: 996 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); 997 break; 998 } 999EXIT: 1000 FunctionOut(); 1001 1002 return ret; 1003} 1004 1005OMX_ERRORTYPE Exynos_VP8Dec_GetConfig( 1006 OMX_HANDLETYPE hComponent, 1007 OMX_INDEXTYPE nIndex, 1008 OMX_PTR pComponentConfigStructure) 1009{ 1010 OMX_ERRORTYPE ret = OMX_ErrorNone; 1011 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1012 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1013 1014 FunctionIn(); 1015 1016 if (hComponent == NULL || pComponentConfigStructure == NULL) { 1017 ret = OMX_ErrorBadParameter; 1018 goto EXIT; 1019 } 1020 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1021 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1022 if (ret != OMX_ErrorNone) { 1023 goto EXIT; 1024 } 1025 if (pOMXComponent->pComponentPrivate == NULL) { 1026 ret = OMX_ErrorBadParameter; 1027 goto EXIT; 1028 } 1029 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1030 if (pExynosComponent->currentState == OMX_StateInvalid) { 1031 ret = OMX_ErrorInvalidState; 1032 goto EXIT; 1033 } 1034 1035 switch (nIndex) { 1036 default: 1037 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure); 1038 break; 1039 } 1040 1041EXIT: 1042 FunctionOut(); 1043 1044 return ret; 1045} 1046 1047OMX_ERRORTYPE Exynos_VP8Dec_SetConfig( 1048 OMX_HANDLETYPE hComponent, 1049 OMX_INDEXTYPE nIndex, 1050 OMX_PTR pComponentConfigStructure) 1051{ 1052 OMX_ERRORTYPE ret = OMX_ErrorNone; 1053 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1054 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1055 1056 FunctionIn(); 1057 1058 if (hComponent == NULL || pComponentConfigStructure == NULL) { 1059 ret = OMX_ErrorBadParameter; 1060 goto EXIT; 1061 } 1062 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1063 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1064 if (ret != OMX_ErrorNone) { 1065 goto EXIT; 1066 } 1067 if (pOMXComponent->pComponentPrivate == NULL) { 1068 ret = OMX_ErrorBadParameter; 1069 goto EXIT; 1070 } 1071 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1072 if (pExynosComponent->currentState == OMX_StateInvalid) { 1073 ret = OMX_ErrorInvalidState; 1074 goto EXIT; 1075 } 1076 1077 switch (nIndex) { 1078 default: 1079 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure); 1080 break; 1081 } 1082 1083EXIT: 1084 FunctionOut(); 1085 1086 return ret; 1087} 1088 1089OMX_ERRORTYPE Exynos_VP8Dec_GetExtensionIndex( 1090 OMX_IN OMX_HANDLETYPE hComponent, 1091 OMX_IN OMX_STRING cParameterName, 1092 OMX_OUT OMX_INDEXTYPE *pIndexType) 1093{ 1094 OMX_ERRORTYPE ret = OMX_ErrorNone; 1095 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1096 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1097 1098 FunctionIn(); 1099 1100 if (hComponent == NULL) { 1101 ret = OMX_ErrorBadParameter; 1102 goto EXIT; 1103 } 1104 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1105 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1106 if (ret != OMX_ErrorNone) { 1107 goto EXIT; 1108 } 1109 if (pOMXComponent->pComponentPrivate == NULL) { 1110 ret = OMX_ErrorBadParameter; 1111 goto EXIT; 1112 } 1113 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1114 if ((cParameterName == NULL) || (pIndexType == NULL)) { 1115 ret = OMX_ErrorBadParameter; 1116 goto EXIT; 1117 } 1118 if (pExynosComponent->currentState == OMX_StateInvalid) { 1119 ret = OMX_ErrorInvalidState; 1120 goto EXIT; 1121 } 1122 1123 if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) { 1124 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1125 *pIndexType = OMX_IndexVendorThumbnailMode; 1126 ret = OMX_ErrorNone; 1127 } else { 1128 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType); 1129 } 1130 1131EXIT: 1132 FunctionOut(); 1133 1134 return ret; 1135} 1136 1137OMX_ERRORTYPE Exynos_VP8Dec_ComponentRoleEnum( 1138 OMX_HANDLETYPE hComponent, 1139 OMX_U8 *cRole, 1140 OMX_U32 nIndex) 1141{ 1142 OMX_ERRORTYPE ret = OMX_ErrorNone; 1143 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1144 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1145 1146 FunctionIn(); 1147 1148 if ((hComponent == NULL) || (cRole == NULL)) { 1149 ret = OMX_ErrorBadParameter; 1150 goto EXIT; 1151 } 1152 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { 1153 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP8_DEC_ROLE); 1154 ret = OMX_ErrorNone; 1155 } else { 1156 ret = OMX_ErrorNoMore; 1157 } 1158 1159EXIT: 1160 FunctionOut(); 1161 1162 return ret; 1163} 1164 1165/* MFC Init */ 1166OMX_ERRORTYPE Exynos_VP8Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) 1167{ 1168 OMX_ERRORTYPE ret = OMX_ErrorNone; 1169 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1170 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1171 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1172 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1173 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 1174 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1175 1176 ExynosVideoDecOps *pDecOps = NULL; 1177 ExynosVideoDecBufferOps *pInbufOps = NULL; 1178 ExynosVideoDecBufferOps *pOutbufOps = NULL; 1179 1180 CSC_METHOD csc_method = CSC_METHOD_SW; 1181 int i, plane; 1182 1183 FunctionIn(); 1184 1185 pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc = OMX_FALSE; 1186 pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst = OMX_FALSE; 1187 pExynosComponent->bUseFlagEOF = OMX_TRUE; 1188 pExynosComponent->bSaveFlagEOS = OMX_FALSE; 1189 1190 /* H.264 Codec Open */ 1191 ret = VP8CodecOpen(pVp8Dec); 1192 if (ret != OMX_ErrorNone) { 1193 goto EXIT; 1194 } 1195 1196 pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1197 pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 1198 pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 1199 1200 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1201 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID); 1202 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); 1203 1204 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 1205 pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER)); 1206 Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER)); 1207 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]); 1208 1209 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { 1210 /* Use ION Allocator */ 1211 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY); 1212 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); 1213 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE; 1214 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; 1215 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) { 1216 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); 1217 ret = OMX_ErrorInsufficientResources; 1218 goto EXIT; 1219 } 1220 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); 1221 } 1222 1223 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]); 1224 } 1225 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { 1226 /*************/ 1227 /* TBD */ 1228 /*************/ 1229 /* Does not require any actions. */ 1230 } 1231 1232 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1233 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID); 1234 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); 1235 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 1236 /*************/ 1237 /* TBD */ 1238 /*************/ 1239 /* Does not require any actions. */ 1240 } 1241 1242 pVp8Dec->bSourceStart = OMX_FALSE; 1243 Exynos_OSAL_SignalCreate(&pVp8Dec->hSourceStartEvent); 1244 pVp8Dec->bDestinationStart = OMX_FALSE; 1245 Exynos_OSAL_SignalCreate(&pVp8Dec->hDestinationStartEvent); 1246 1247 Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); 1248 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); 1249 pVp8Dec->hMFCVp8Handle.indexTimestamp = 0; 1250 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = 0; 1251 1252 pExynosComponent->getAllDelayBuffer = OMX_FALSE; 1253 1254#if 0//defined(USE_CSC_GSCALER) 1255 csc_method = CSC_METHOD_HW; //in case of Use ION buffer. 1256#endif 1257 pVideoDec->csc_handle = csc_init(csc_method); 1258 if (pVideoDec->csc_handle == NULL) { 1259 ret = OMX_ErrorInsufficientResources; 1260 goto EXIT; 1261 } 1262 pVideoDec->csc_set_format = OMX_FALSE; 1263 1264EXIT: 1265 FunctionOut(); 1266 1267 return ret; 1268} 1269 1270/* MFC Terminate */ 1271OMX_ERRORTYPE Exynos_VP8Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) 1272{ 1273 OMX_ERRORTYPE ret = OMX_ErrorNone; 1274 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1275 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1276 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1277 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1278 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1279 OMX_PTR hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1280 1281 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1282 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 1283 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 1284 1285 int i, plane; 1286 1287 FunctionIn(); 1288 1289 if (pVideoDec->csc_handle != NULL) { 1290 csc_deinit(pVideoDec->csc_handle); 1291 pVideoDec->csc_handle = NULL; 1292 } 1293 1294 Exynos_OSAL_SignalTerminate(pVp8Dec->hDestinationStartEvent); 1295 pVp8Dec->hDestinationStartEvent = NULL; 1296 pVp8Dec->bDestinationStart = OMX_FALSE; 1297 Exynos_OSAL_SignalTerminate(pVp8Dec->hSourceStartEvent); 1298 pVp8Dec->hSourceStartEvent = NULL; 1299 pVp8Dec->bSourceStart = OMX_FALSE; 1300 1301 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1302 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) { 1303 if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) { 1304 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { 1305 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL) 1306 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]); 1307 } 1308 1309 Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]); 1310 pVideoDec->pMFCDecOutputBuffer[i] = NULL; 1311 } 1312 } 1313 1314 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ); 1315 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID); 1316 } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 1317 /*************/ 1318 /* TBD */ 1319 /*************/ 1320 /* Does not require any actions. */ 1321 } 1322 1323 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1324 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 1325 if (pVideoDec->pMFCDecInputBuffer[i] != NULL) { 1326 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { 1327 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL) 1328 Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]); 1329 } 1330 1331 Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]); 1332 pVideoDec->pMFCDecInputBuffer[i] = NULL; 1333 } 1334 } 1335 1336 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ); 1337 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID); 1338 } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) { 1339 /*************/ 1340 /* TBD */ 1341 /*************/ 1342 /* Does not require any actions. */ 1343 } 1344 VP8CodecClose(pVp8Dec); 1345 1346EXIT: 1347 FunctionOut(); 1348 1349 return ret; 1350} 1351 1352OMX_ERRORTYPE Exynos_VP8Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) 1353{ 1354 OMX_ERRORTYPE ret = OMX_ErrorNone; 1355 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1356 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1357 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1358 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1359 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1360 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1361 OMX_U32 oneFrameSize = pSrcInputData->dataLen; 1362 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1363 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 1364 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 1365 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; 1366 int i; 1367 1368 FunctionIn(); 1369 1370 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCSrc == OMX_FALSE) { 1371 ret = VP8CodecSrcSetup(pOMXComponent, pSrcInputData); 1372 goto EXIT; 1373 } 1374 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_FALSE) { 1375 ret = VP8CodecDstSetup(pOMXComponent); 1376 } 1377 1378 if ((Check_VP8_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize) == OMX_TRUE) || 1379 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { 1380 pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->timeStamp; 1381 pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.indexTimestamp] = pSrcInputData->nFlags; 1382 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp8Dec->hMFCVp8Handle.indexTimestamp, pSrcInputData->nFlags); 1383 pDecOps->Set_FrameTag(hMFCHandle, pVp8Dec->hMFCVp8Handle.indexTimestamp); 1384 pVp8Dec->hMFCVp8Handle.indexTimestamp++; 1385 pVp8Dec->hMFCVp8Handle.indexTimestamp %= MAX_TIMESTAMP; 1386 1387 /* queue work for input buffer */ 1388 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer); 1389 codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, 1390 (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader); 1391 if (codecReturn != VIDEO_ERROR_NONE) { 1392 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; 1393 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); 1394 goto EXIT; 1395 } 1396 VP8CodecStart(pOMXComponent, INPUT_PORT_INDEX); 1397 if (pVp8Dec->bSourceStart == OMX_FALSE) { 1398 pVp8Dec->bSourceStart = OMX_TRUE; 1399 Exynos_OSAL_SignalSet(pVp8Dec->hSourceStartEvent); 1400 Exynos_OSAL_SleepMillisec(0); 1401 } 1402 if (pVp8Dec->bDestinationStart == OMX_FALSE) { 1403 pVp8Dec->bDestinationStart = OMX_TRUE; 1404 Exynos_OSAL_SignalSet(pVp8Dec->hDestinationStartEvent); 1405 Exynos_OSAL_SleepMillisec(0); 1406 } 1407 } 1408 1409 ret = OMX_ErrorNone; 1410 1411EXIT: 1412 FunctionOut(); 1413 1414 return ret; 1415} 1416 1417OMX_ERRORTYPE Exynos_VP8Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) 1418{ 1419 OMX_ERRORTYPE ret = OMX_ErrorNone; 1420 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1421 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1422 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1423 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1424 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1425 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1426 ExynosVideoDecBufferOps *pInbufOps = pVp8Dec->hMFCVp8Handle.pInbufOps; 1427 ExynosVideoBuffer *pVideoBuffer; 1428 1429 FunctionIn(); 1430 1431 pVideoBuffer = pInbufOps->Dequeue(hMFCHandle); 1432 1433 pSrcOutputData->dataLen = 0; 1434 pSrcOutputData->usedDataLen = 0; 1435 pSrcOutputData->remainDataLen = 0; 1436 pSrcOutputData->nFlags = 0; 1437 pSrcOutputData->timeStamp = 0; 1438 1439 if (pVideoBuffer == NULL) { 1440 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL; 1441 pSrcOutputData->allocSize = 0; 1442 pSrcOutputData->pPrivate = NULL; 1443 pSrcOutputData->bufferHeader = NULL; 1444 } else { 1445 pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr; 1446 pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd; 1447 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize; 1448 1449 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1450 int i = 0; 1451 while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) { 1452 if (i >= MFC_INPUT_BUFFER_NUM_MAX) { 1453 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer"); 1454 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; 1455 goto EXIT; 1456 } 1457 i++; 1458 } 1459 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0; 1460 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i]; 1461 } 1462 1463 /* For Share Buffer */ 1464 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate; 1465 } 1466 1467 ret = OMX_ErrorNone; 1468 1469EXIT: 1470 FunctionOut(); 1471 1472 return ret; 1473} 1474 1475OMX_ERRORTYPE Exynos_VP8Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) 1476{ 1477 OMX_ERRORTYPE ret = OMX_ErrorNone; 1478 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1479 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1480 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1481 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1482 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1483 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1484 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 1485 OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,}; 1486 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE; 1487 1488 FunctionIn(); 1489 1490 if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) { 1491 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer"); 1492 ret = OMX_ErrorBadParameter; 1493 goto EXIT; 1494 } 1495 1496 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__, 1497 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0], 1498 pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]); 1499 1500 codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer, 1501 (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader); 1502 1503 if (codecReturn != VIDEO_ERROR_NONE) { 1504 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__); 1505 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode; 1506 goto EXIT; 1507 } 1508 VP8CodecStart(pOMXComponent, OUTPUT_PORT_INDEX); 1509 1510 ret = OMX_ErrorNone; 1511 1512EXIT: 1513 FunctionOut(); 1514 1515 return ret; 1516} 1517 1518OMX_ERRORTYPE Exynos_VP8Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) 1519{ 1520 OMX_ERRORTYPE ret = OMX_ErrorNone; 1521 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1522 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1523 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1524 void *hMFCHandle = pVp8Dec->hMFCVp8Handle.hMFCHandle; 1525 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1526 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1527 ExynosVideoDecOps *pDecOps = pVp8Dec->hMFCVp8Handle.pDecOps; 1528 ExynosVideoDecBufferOps *pOutbufOps = pVp8Dec->hMFCVp8Handle.pOutbufOps; 1529 ExynosVideoBuffer *pVideoBuffer; 1530 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN; 1531 ExynosVideoGeometry *bufferGeometry; 1532 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL; 1533 OMX_S32 indexTimestamp = 0; 1534 int plane; 1535 1536 FunctionIn(); 1537 1538 if (pVp8Dec->bDestinationStart == OMX_FALSE) { 1539 ret = OMX_ErrorNone; 1540 goto EXIT; 1541 } 1542 1543 while (1) { 1544 if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) { 1545 ret = OMX_ErrorNone; 1546 goto EXIT; 1547 } 1548 displayStatus = pVideoBuffer->displayStatus; 1549 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus); 1550 1551 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) || 1552 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) || 1553 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || 1554 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { 1555 if (pVideoBuffer != NULL) { 1556 ret = OMX_ErrorNone; 1557 break; 1558 } else { 1559 ret = OMX_ErrorUndefined; 1560 break; 1561 } 1562 } 1563 } 1564 1565 if (ret != OMX_ErrorNone) 1566 goto EXIT; 1567 1568 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp++; 1569 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp %= MAX_TIMESTAMP; 1570 1571 pDstOutputData->allocSize = pDstOutputData->dataLen = 0; 1572 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) { 1573 pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr; 1574 pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd; 1575 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize; 1576 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize; 1577 } 1578 pDstOutputData->usedDataLen = 0; 1579 pDstOutputData->pPrivate = pVideoBuffer; 1580 /* For Share Buffer */ 1581 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate; 1582 1583 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo; 1584 bufferGeometry = &pVp8Dec->hMFCVp8Handle.codecOutbufConf; 1585 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth; 1586 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight; 1587 switch (bufferGeometry->eColorFormat) { 1588 case VIDEO_COLORFORMAT_NV12: 1589 pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1590 break; 1591 case VIDEO_COLORFORMAT_NV12_TILED: 1592 default: 1593 pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled; 1594 break; 1595 } 1596 1597 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle); 1598 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp); 1599 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) { 1600 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) && 1601 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) { 1602 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1603 pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1604 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp); 1605 } else { 1606 pDstOutputData->timeStamp = 0x00; 1607 pDstOutputData->nFlags = 0x00; 1608 } 1609 } else { 1610 /* For timestamp correction. if mfc support frametype detect */ 1611 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType); 1612#ifdef NEED_TIMESTAMP_REORDER 1613 if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) { 1614 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; 1615 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; 1616 pVp8Dec->hMFCVp8Handle.outputIndexTimestamp = indexTimestamp; 1617 } else { 1618 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1619 pDstOutputData->nFlags = pExynosComponent->nFlags[pVp8Dec->hMFCVp8Handle.outputIndexTimestamp]; 1620 } 1621#else 1622 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp]; 1623 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp]; 1624#endif 1625 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags); 1626 } 1627 1628 if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) || 1629 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { 1630 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags); 1631 pDstOutputData->remainDataLen = 0; 1632 } else { 1633 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2; 1634 } 1635 1636 ret = OMX_ErrorNone; 1637 1638EXIT: 1639 FunctionOut(); 1640 1641 return ret; 1642} 1643 1644OMX_ERRORTYPE Exynos_VP8Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData) 1645{ 1646 OMX_ERRORTYPE ret = OMX_ErrorNone; 1647 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1648 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1649 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1650 1651 FunctionIn(); 1652 1653 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { 1654 ret = OMX_ErrorNone; 1655 goto EXIT; 1656 } 1657 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { 1658 ret = OMX_ErrorNone; 1659 goto EXIT; 1660 } 1661 1662 ret = Exynos_VP8Dec_SrcIn(pOMXComponent, pSrcInputData); 1663 if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) { 1664 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 1665 pExynosComponent->callbackData, 1666 OMX_EventError, ret, 0, NULL); 1667 } 1668 1669EXIT: 1670 FunctionOut(); 1671 1672 return ret; 1673} 1674 1675OMX_ERRORTYPE Exynos_VP8Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData) 1676{ 1677 OMX_ERRORTYPE ret = OMX_ErrorNone; 1678 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1679 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1680 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1681 1682 FunctionIn(); 1683 1684 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) { 1685 ret = OMX_ErrorNone; 1686 goto EXIT; 1687 } 1688 1689 if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1690 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) { 1691 ret = OMX_ErrorNone; 1692 goto EXIT; 1693 } 1694 } 1695 if ((pVp8Dec->bSourceStart == OMX_FALSE) && 1696 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) { 1697 Exynos_OSAL_SignalWait(pVp8Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME); 1698 Exynos_OSAL_SignalReset(pVp8Dec->hSourceStartEvent); 1699 } 1700 1701 ret = Exynos_VP8Dec_SrcOut(pOMXComponent, pSrcOutputData); 1702 if ((ret != OMX_ErrorNone) && 1703 (pExynosComponent->currentState == OMX_StateExecuting)) { 1704 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 1705 pExynosComponent->callbackData, 1706 OMX_EventError, ret, 0, NULL); 1707 } 1708 1709EXIT: 1710 FunctionOut(); 1711 1712 return ret; 1713} 1714 1715OMX_ERRORTYPE Exynos_VP8Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData) 1716{ 1717 OMX_ERRORTYPE ret = OMX_ErrorNone; 1718 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1719 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1720 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1721 1722 FunctionIn(); 1723 1724 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { 1725 ret = OMX_ErrorNone; 1726 goto EXIT; 1727 } 1728 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { 1729 ret = OMX_ErrorNone; 1730 goto EXIT; 1731 } 1732 if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) { 1733 if ((pVp8Dec->bDestinationStart == OMX_FALSE) && 1734 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { 1735 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); 1736 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent); 1737 } 1738 } 1739 if (pVp8Dec->hMFCVp8Handle.bConfiguredMFCDst == OMX_TRUE) { 1740 ret = Exynos_VP8Dec_DstIn(pOMXComponent, pDstInputData); 1741 if (ret != OMX_ErrorNone) { 1742 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 1743 pExynosComponent->callbackData, 1744 OMX_EventError, ret, 0, NULL); 1745 } 1746 } 1747 1748EXIT: 1749 FunctionOut(); 1750 1751 return ret; 1752} 1753 1754OMX_ERRORTYPE Exynos_VP8Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData) 1755{ 1756 OMX_ERRORTYPE ret = OMX_ErrorNone; 1757 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1758 EXYNOS_VP8DEC_HANDLE *pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle; 1759 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1760 1761 FunctionIn(); 1762 1763 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) { 1764 ret = OMX_ErrorNone; 1765 goto EXIT; 1766 } 1767 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) { 1768 ret = OMX_ErrorNone; 1769 goto EXIT; 1770 } 1771 1772 if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 1773 if ((pVp8Dec->bDestinationStart == OMX_FALSE) && 1774 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) { 1775 Exynos_OSAL_SignalWait(pVp8Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME); 1776 Exynos_OSAL_SignalReset(pVp8Dec->hDestinationStartEvent); 1777 } 1778 } 1779 ret = Exynos_VP8Dec_DstOut(pOMXComponent, pDstOutputData); 1780 if ((ret != OMX_ErrorNone) && 1781 (pExynosComponent->currentState == OMX_StateExecuting)) { 1782 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 1783 pExynosComponent->callbackData, 1784 OMX_EventError, ret, 0, NULL); 1785 } 1786 1787EXIT: 1788 FunctionOut(); 1789 1790 return ret; 1791} 1792 1793OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit( 1794 OMX_HANDLETYPE hComponent, 1795 OMX_STRING componentName) 1796{ 1797 OMX_ERRORTYPE ret = OMX_ErrorNone; 1798 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1799 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1800 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1801 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 1802 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 1803 int i = 0; 1804 1805 FunctionIn(); 1806 1807 if ((hComponent == NULL) || (componentName == NULL)) { 1808 ret = OMX_ErrorBadParameter; 1809 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); 1810 goto EXIT; 1811 } 1812 if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP8_DEC, componentName) != 0) { 1813 ret = OMX_ErrorBadParameter; 1814 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); 1815 goto EXIT; 1816 } 1817 1818 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1819 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent); 1820 if (ret != OMX_ErrorNone) { 1821 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1822 goto EXIT; 1823 } 1824 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1825 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC; 1826 1827 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); 1828 if (pExynosComponent->componentName == NULL) { 1829 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1830 ret = OMX_ErrorInsufficientResources; 1831 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1832 goto EXIT; 1833 } 1834 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); 1835 1836 pVp8Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP8DEC_HANDLE)); 1837 if (pVp8Dec == NULL) { 1838 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1839 ret = OMX_ErrorInsufficientResources; 1840 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1841 goto EXIT; 1842 } 1843 Exynos_OSAL_Memset(pVp8Dec, 0, sizeof(EXYNOS_VP8DEC_HANDLE)); 1844 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1845 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp8Dec; 1846 1847 Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_VP8_DEC); 1848 1849 /* Set componentVersion */ 1850 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; 1851 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; 1852 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER; 1853 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER; 1854 /* Set specVersion */ 1855 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; 1856 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; 1857 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER; 1858 pExynosComponent->specVersion.s.nStep = STEP_NUMBER; 1859 1860 /* Input port */ 1861 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1862 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; 1863 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; 1864 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ 1865 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1866 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; 1867 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; 1868 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); 1869 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp8"); 1870 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1871 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1872 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1873 pExynosPort->portDefinition.bEnabled = OMX_TRUE; 1874 pExynosPort->bufferProcessType = BUFFER_SHARE; 1875 pExynosPort->portWayType = WAY2_PORT; 1876 1877 /* Output port */ 1878 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1879 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; 1880 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; 1881 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ 1882 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1883 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; 1884 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1885 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); 1886 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1887 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1888 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1889 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; 1890 pExynosPort->portDefinition.bEnabled = OMX_TRUE; 1891 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE; 1892 pExynosPort->portWayType = WAY2_PORT; 1893 1894 pOMXComponent->GetParameter = &Exynos_VP8Dec_GetParameter; 1895 pOMXComponent->SetParameter = &Exynos_VP8Dec_SetParameter; 1896 pOMXComponent->GetConfig = &Exynos_VP8Dec_GetConfig; 1897 pOMXComponent->SetConfig = &Exynos_VP8Dec_SetConfig; 1898 pOMXComponent->GetExtensionIndex = &Exynos_VP8Dec_GetExtensionIndex; 1899 pOMXComponent->ComponentRoleEnum = &Exynos_VP8Dec_ComponentRoleEnum; 1900 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit; 1901 1902 pExynosComponent->exynos_codec_componentInit = &Exynos_VP8Dec_Init; 1903 pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP8Dec_Terminate; 1904 1905 pVideoDec->exynos_codec_srcInputProcess = &Exynos_VP8Dec_srcInputBufferProcess; 1906 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP8Dec_srcOutputBufferProcess; 1907 pVideoDec->exynos_codec_dstInputProcess = &Exynos_VP8Dec_dstInputBufferProcess; 1908 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP8Dec_dstOutputBufferProcess; 1909 1910 pVideoDec->exynos_codec_start = &VP8CodecStart; 1911 pVideoDec->exynos_codec_stop = &VP8CodecStop; 1912 pVideoDec->exynos_codec_bufferProcessRun = &VP8CodecOutputBufferProcessRun; 1913 pVideoDec->exynos_codec_enqueueAllBuffer = &VP8CodecEnQueueAllBuffer; 1914 1915 pVideoDec->exynos_checkInputFrame = &Check_VP8_Frame; 1916 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData; 1917 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData; 1918 1919 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open(); 1920 if (pVideoDec->hSharedMemory == NULL) { 1921 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1922 Exynos_OSAL_Free(pVp8Dec); 1923 pVp8Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL; 1924 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1925 ret = OMX_ErrorInsufficientResources; 1926 goto EXIT; 1927 } 1928 1929 pExynosComponent->currentState = OMX_StateLoaded; 1930 1931 ret = OMX_ErrorNone; 1932 1933EXIT: 1934 FunctionOut(); 1935 1936 return ret; 1937} 1938 1939OMX_ERRORTYPE Exynos_OMX_ComponentDeinit( 1940 OMX_HANDLETYPE hComponent) 1941{ 1942 OMX_ERRORTYPE ret = OMX_ErrorNone; 1943 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1944 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1945 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL; 1946 EXYNOS_VP8DEC_HANDLE *pVp8Dec = NULL; 1947 1948 FunctionIn(); 1949 1950 if (hComponent == NULL) { 1951 ret = OMX_ErrorBadParameter; 1952 goto EXIT; 1953 } 1954 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1955 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1956 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle; 1957 1958 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory); 1959 1960 Exynos_OSAL_Free(pExynosComponent->componentName); 1961 pExynosComponent->componentName = NULL; 1962 1963 pVp8Dec = (EXYNOS_VP8DEC_HANDLE *)pVideoDec->hCodecHandle; 1964 if (pVp8Dec != NULL) { 1965 Exynos_OSAL_Free(pVp8Dec); 1966 pVp8Dec = pVideoDec->hCodecHandle = NULL; 1967 } 1968 1969 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent); 1970 if (ret != OMX_ErrorNone) { 1971 goto EXIT; 1972 } 1973 1974 ret = OMX_ErrorNone; 1975 1976EXIT: 1977 FunctionOut(); 1978 1979 return ret; 1980} 1981