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