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_Venc.c 20 * @brief 21 * @author SeungBeom Kim (sbcrux.kim (at) samsung.com) 22 * Yunji Kim (yunji.kim (at) 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 #include "Exynos_OMX_Macros.h" 32 #include "Exynos_OSAL_Event.h" 33 #include "Exynos_OMX_Venc.h" 34 #include "Exynos_OMX_VencControl.h" 35 #include "Exynos_OMX_Basecomponent.h" 36 #include "Exynos_OSAL_Thread.h" 37 #include "Exynos_OSAL_Semaphore.h" 38 #include "Exynos_OSAL_SharedMemory.h" 39 #include "Exynos_OSAL_Mutex.h" 40 #include "Exynos_OSAL_ETC.h" 41 #include "csc.h" 42 43 #ifdef USE_STOREMETADATA 44 #include <system/window.h> 45 #include "Exynos_OSAL_Android.h" 46 #endif 47 48 #undef EXYNOS_LOG_TAG 49 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENC" 50 #define EXYNOS_LOG_OFF 51 //#define EXYNOS_TRACE_ON 52 #include "Exynos_OSAL_Log.h" 53 54 55 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) 56 { 57 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 58 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 59 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 60 61 if ((exynosOutputPort->portDefinition.format.video.nFrameWidth != 62 exynosInputPort->portDefinition.format.video.nFrameWidth) || 63 (exynosOutputPort->portDefinition.format.video.nFrameHeight != 64 exynosInputPort->portDefinition.format.video.nFrameHeight)) { 65 OMX_U32 width = 0, height = 0; 66 67 exynosOutputPort->portDefinition.format.video.nFrameWidth = 68 exynosInputPort->portDefinition.format.video.nFrameWidth; 69 exynosOutputPort->portDefinition.format.video.nFrameHeight = 70 exynosInputPort->portDefinition.format.video.nFrameHeight; 71 width = exynosOutputPort->portDefinition.format.video.nStride = 72 exynosInputPort->portDefinition.format.video.nStride; 73 height = exynosOutputPort->portDefinition.format.video.nSliceHeight = 74 exynosInputPort->portDefinition.format.video.nSliceHeight; 75 76 if (width && height) 77 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; 78 } 79 80 return; 81 } 82 83 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) 84 { 85 OMX_BOOL ret = OMX_FALSE; 86 87 if ((pExynosComponent->currentState == OMX_StateExecuting) && 88 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) && 89 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) && 90 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) { 91 ret = OMX_TRUE; 92 } else { 93 ret = OMX_FALSE; 94 } 95 96 return ret; 97 } 98 99 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) 100 { 101 OMX_ERRORTYPE ret = OMX_ErrorNone; 102 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 103 CODEC_ENC_BUFFER *pInputCodecBuffer = (CODEC_ENC_BUFFER*)codecBuffer; 104 105 pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0]; 106 pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1]; 107 pData->buffer.multiPlaneBuffer.fd[0] = pInputCodecBuffer->fd[0]; 108 pData->buffer.multiPlaneBuffer.fd[1] = pInputCodecBuffer->fd[1]; 109 pData->allocSize = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1]; 110 pData->dataLen = pInputCodecBuffer->dataSize; 111 pData->usedDataLen = 0; 112 pData->remainDataLen = pInputCodecBuffer->dataSize; 113 114 pData->nFlags = 0; 115 pData->timeStamp = 0; 116 pData->pPrivate = codecBuffer; 117 pData->bufferHeader = NULL; 118 119 return ret; 120 } 121 122 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData) 123 { 124 OMX_ERRORTYPE ret = OMX_ErrorNone; 125 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 126 OMX_PTR pSrcBuf; 127 OMX_U32 allocSize; 128 129 pVideoEnc->exynos_codec_getCodecOutputPrivateData(codecBuffer, &pSrcBuf, &allocSize); 130 pData->buffer.singlePlaneBuffer.dataBuffer = pSrcBuf; 131 pData->allocSize = allocSize; 132 pData->dataLen = 0; 133 pData->usedDataLen = 0; 134 pData->remainDataLen = 0; 135 136 pData->nFlags = 0; 137 pData->timeStamp = 0; 138 pData->pPrivate = codecBuffer; 139 pData->bufferHeader = NULL; 140 141 return ret; 142 } 143 144 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex) 145 { 146 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 147 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 148 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL; 149 150 FunctionIn(); 151 152 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex]; 153 154 if (((pExynosComponent->currentState == OMX_StatePause) || 155 (pExynosComponent->currentState == OMX_StateIdle) || 156 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) || 157 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) && 158 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) && 159 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) { 160 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME); 161 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent); 162 } 163 164 FunctionOut(); 165 166 return; 167 } 168 169 OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) 170 { 171 OMX_BOOL ret = OMX_FALSE; 172 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 173 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 174 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 175 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; 176 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; 177 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; 178 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; 179 OMX_BYTE checkInputStream = NULL; 180 OMX_BOOL flagEOS = OMX_FALSE; 181 182 FunctionIn(); 183 184 checkInputStream = inputUseBuffer->bufferHeader->pBuffer; 185 186 CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate; 187 codecInputBuffer->dataSize = ((nFrameWidth * nFrameHeight) * 3) / 2; 188 189 unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 190 unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 191 CSC_METHOD csc_method = CSC_METHOD_SW; 192 unsigned int cacheable = 1; 193 194 void *pSrcBuf[3] = {NULL, }; 195 void *pSrcFd[3] = {NULL, }; 196 void *pDstBuf[3] = {NULL, }; 197 void *pDstFd[3] = {NULL, }; 198 199 CSC_ERRORCODE cscRet = CSC_ErrorNone; 200 201 pSrcBuf[0] = checkInputStream; 202 pSrcBuf[1] = checkInputStream + (nFrameWidth * nFrameHeight); 203 pSrcBuf[2] = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4); 204 205 pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]; 206 pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]; 207 pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2]; 208 209 #ifdef USE_METADATABUFFERTYPE 210 OMX_PTR ppBuf[MAX_BUFFER_PLANE]; 211 212 /* kMetadataBufferTypeGrallocSource */ 213 if (exynosInputPort->bStoreMetaData == OMX_TRUE) { 214 /* ARGB8888 converted to YUV420SemiPlanar */ 215 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888); 216 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 217 218 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); 219 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { 220 ExynosVideoPlane planes[MAX_BUFFER_PLANE]; 221 size_t i; 222 223 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)Exynos_OSAL_GetANBColorFormat(ppBuf[0])); 224 Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes); 225 226 #if defined(USE_CSC_GSCALER) || defined(USE_CSC_G2D) 227 csc_method = CSC_METHOD_HW; 228 #endif 229 pSrcBuf[0] = planes[0].addr; 230 pSrcFd[0] = (void *)planes[0].fd; 231 for (i = 0; i < 3; i++) 232 pDstFd[i] = (void *)srcInputData->buffer.multiPlaneBuffer.fd[i]; 233 } 234 } else 235 #endif 236 { 237 switch (eColorFormat) { 238 case OMX_COLOR_FormatYUV420Planar: 239 /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/ 240 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar); 241 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 242 break; 243 case OMX_COLOR_FormatYUV420SemiPlanar: 244 case OMX_SEC_COLOR_FormatNV12Tiled: 245 case OMX_SEC_COLOR_FormatNV21Linear: 246 /* Just copied to MFC input buffer */ 247 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 248 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar); 249 break; 250 default: 251 break; 252 } 253 } 254 255 csc_set_method( 256 pVideoEnc->csc_handle, 257 csc_method); 258 csc_set_src_format( 259 pVideoEnc->csc_handle, /* handle */ 260 nFrameWidth, /* width */ 261 nFrameHeight, /* height */ 262 0, /* crop_left */ 263 0, /* crop_right */ 264 nFrameWidth, /* crop_width */ 265 nFrameHeight, /* crop_height */ 266 csc_src_color_format, /* color_format */ 267 cacheable); /* cacheable */ 268 csc_set_dst_format( 269 pVideoEnc->csc_handle, /* handle */ 270 nFrameWidth, /* width */ 271 nFrameHeight, /* height */ 272 0, /* crop_left */ 273 0, /* crop_right */ 274 nFrameWidth, /* crop_width */ 275 nFrameHeight, /* crop_height */ 276 csc_dst_color_format, /* color_format */ 277 cacheable); /* cacheable */ 278 if (csc_method == CSC_METHOD_SW) { 279 csc_set_src_buffer( 280 pVideoEnc->csc_handle, /* handle */ 281 pSrcBuf); 282 csc_set_dst_buffer( 283 pVideoEnc->csc_handle, /* handle */ 284 pDstBuf); 285 } else { 286 csc_set_src_buffer( 287 pVideoEnc->csc_handle, /* handle */ 288 pSrcFd); 289 csc_set_dst_buffer( 290 pVideoEnc->csc_handle, /* handle */ 291 pDstFd); 292 } 293 cscRet = csc_convert(pVideoEnc->csc_handle); 294 if (cscRet != CSC_ErrorNone) 295 ret = OMX_FALSE; 296 else 297 ret = OMX_TRUE; 298 299 #ifdef USE_METADATABUFFERTYPE 300 if (exynosInputPort->bStoreMetaData == OMX_TRUE) { 301 Exynos_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]); 302 } 303 #endif 304 305 EXIT: 306 FunctionOut(); 307 308 return ret; 309 } 310 311 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData) 312 { 313 OMX_BOOL ret = OMX_FALSE; 314 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 315 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 316 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 317 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; 318 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth; 319 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight; 320 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; 321 OMX_U32 copySize = 0; 322 OMX_BYTE checkInputStream = NULL; 323 OMX_U32 checkInputStreamLen = 0; 324 OMX_BOOL flagEOS = OMX_FALSE; 325 326 FunctionIn(); 327 328 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 329 if ((srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || 330 (srcInputData->pPrivate == NULL)) { 331 ret = OMX_FALSE; 332 goto EXIT; 333 } 334 } 335 336 if (inputUseBuffer->dataValid == OMX_TRUE) { 337 if (exynosInputPort->bufferProcessType == BUFFER_SHARE) { 338 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE); 339 #ifdef USE_METADATABUFFERTYPE 340 if (exynosInputPort->bStoreMetaData == OMX_TRUE) { 341 OMX_PTR ppBuf[MAX_BUFFER_PLANE]; 342 OMX_PTR allocSize[MAX_BUFFER_PLANE]; 343 int plane = 0; 344 345 if (inputUseBuffer->dataLen <= 0) { 346 if (!(inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { 347 Exynos_InputBufferReturn(pOMXComponent); 348 349 /* reset dataBuffer */ 350 Exynos_ResetDataBuffer(inputUseBuffer); 351 } else { 352 /* Make EOS Buffer for MFC Processing scheme */ 353 /* Use ION Allocator */ 354 /*Alloc Y-Buffer */ 355 allocSize[0] = nFrameWidth * nFrameHeight; 356 srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[0], NORMAL_MEMORY); 357 srcInputData->buffer.multiPlaneBuffer.fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[0]); 358 /*Alloc C-Buffer */ 359 allocSize[1] = nFrameWidth * nFrameHeight >> 1; 360 srcInputData->buffer.multiPlaneBuffer.dataBuffer[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, allocSize[1], NORMAL_MEMORY); 361 srcInputData->buffer.multiPlaneBuffer.fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.dataBuffer[1]); 362 /* input buffers are 2 plane. */ 363 srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; 364 srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; 365 } 366 } else { 367 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf); 368 369 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { 370 ExynosVideoPlane planes[MAX_BUFFER_PLANE]; 371 372 Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatYUV420SemiPlanar, planes); 373 374 srcInputData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd; 375 srcInputData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd; 376 } else { 377 /* kMetadataBufferTypeCameraSource */ 378 srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0]; 379 srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1]; 380 } 381 allocSize[0] = nFrameWidth * nFrameHeight; 382 allocSize[1] = nFrameWidth * nFrameHeight >> 1; 383 384 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) { 385 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = 386 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]); 387 if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) { 388 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = 389 Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]); 390 } 391 } 392 /* input buffers are 2 plane. */ 393 srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL; 394 srcInputData->buffer.multiPlaneBuffer.fd[2] = -1; 395 } 396 } 397 #endif 398 /* reset dataBuffer */ 399 Exynos_ResetDataBuffer(inputUseBuffer); 400 } else if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 401 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; 402 checkInputStreamLen = inputUseBuffer->remainDataLen; 403 404 pExynosComponent->bUseFlagEOF = OMX_TRUE; 405 406 if (checkInputStreamLen == 0) { 407 inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS; 408 flagEOS = OMX_TRUE; 409 } 410 411 copySize = checkInputStreamLen; 412 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE"); 413 414 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) { 415 if ((copySize > 0) || (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { 416 ret = OMX_TRUE; 417 if (copySize > 0) 418 ret = Exynos_CSC_InputData(pOMXComponent, srcInputData); 419 if (ret) { 420 inputUseBuffer->dataLen -= copySize; 421 inputUseBuffer->remainDataLen -= copySize; 422 inputUseBuffer->usedDataLen += copySize; 423 424 srcInputData->dataLen += copySize; 425 srcInputData->remainDataLen += copySize; 426 427 srcInputData->timeStamp = inputUseBuffer->timeStamp; 428 srcInputData->nFlags = inputUseBuffer->nFlags; 429 srcInputData->bufferHeader = inputUseBuffer->bufferHeader; 430 } else { 431 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure"); 432 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 433 pExynosComponent->callbackData, OMX_EventError, 434 OMX_ErrorUndefined, 0, NULL ); 435 } 436 } else { 437 ret = OMX_FALSE; 438 } 439 } else { 440 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length"); 441 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 442 pExynosComponent->callbackData, 443 OMX_EventError, OMX_ErrorUndefined, 0, NULL); 444 ret = OMX_FALSE; 445 } 446 447 if (((exynosInputPort->bStoreMetaData == OMX_TRUE) && (eColorFormat == OMX_COLOR_FormatAndroidOpaque)) || 448 (exynosInputPort->bStoreMetaData == OMX_FALSE)) { 449 Exynos_InputBufferReturn(pOMXComponent); 450 } else { 451 inputUseBuffer->dataValid = OMX_TRUE; 452 } 453 } 454 455 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { 456 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE"); 457 pExynosComponent->bSaveFlagEOS = OMX_TRUE; 458 if (srcInputData->dataLen != 0) 459 pExynosComponent->bBehaviorEOS = OMX_TRUE; 460 } 461 462 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { 463 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; 464 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp; 465 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags; 466 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; 467 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)", 468 srcInputData->timeStamp, srcInputData->timeStamp / 1E6); 469 } 470 471 ret = OMX_TRUE; 472 } 473 474 EXIT: 475 476 FunctionOut(); 477 478 return ret; 479 } 480 481 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData) 482 { 483 OMX_BOOL ret = OMX_FALSE; 484 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 485 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 486 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; 487 OMX_U32 copySize = 0; 488 489 FunctionIn(); 490 491 if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { 492 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone) 493 outputUseBuffer->dataValid = OMX_TRUE; 494 } 495 496 if (outputUseBuffer->dataValid == OMX_TRUE) { 497 if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { 498 if (pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp){ 499 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123; 500 pExynosComponent->checkTimeStamp.nStartFlags = 0x0; 501 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; 502 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; 503 } else { 504 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "garbage frame drop after flush"); 505 ret = OMX_TRUE; 506 goto EXIT; 507 } 508 } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { 509 ret = OMX_TRUE; 510 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input buffer has not come after flush."); 511 goto EXIT; 512 } 513 514 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 515 if (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { 516 copySize = dstOutputData->remainDataLen; 517 if (copySize > 0) 518 Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), 519 (dstOutputData->buffer.singlePlaneBuffer.dataBuffer + dstOutputData->usedDataLen), 520 copySize); 521 outputUseBuffer->dataLen += copySize; 522 outputUseBuffer->remainDataLen += copySize; 523 outputUseBuffer->nFlags = dstOutputData->nFlags; 524 outputUseBuffer->timeStamp = dstOutputData->timeStamp; 525 526 ret = OMX_TRUE; 527 528 if ((outputUseBuffer->remainDataLen > 0) || 529 (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { 530 Exynos_OutputBufferReturn(pOMXComponent); 531 } 532 } else { 533 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than encoded data size Out Length"); 534 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, 535 pExynosComponent->callbackData, 536 OMX_EventError, OMX_ErrorUndefined, 0, NULL); 537 ret = OMX_FALSE; 538 } 539 } else if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { 540 if ((outputUseBuffer->remainDataLen > 0) || 541 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) || 542 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) 543 Exynos_OutputBufferReturn(pOMXComponent); 544 } 545 } else { 546 ret = OMX_FALSE; 547 } 548 549 EXIT: 550 FunctionOut(); 551 552 return ret; 553 } 554 555 #ifdef USE_METADATABUFFERTYPE 556 OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent) 557 { 558 OMX_ERRORTYPE ret = OMX_ErrorNone; 559 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 560 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 561 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 562 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 563 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; 564 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; 565 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat; 566 567 int i = 0; 568 OMX_PTR ppBuf[MAX_BUFFER_PLANE]; 569 570 /* kMetadataBufferTypeGrallocSource */ 571 if (exynosInputPort->bStoreMetaData == OMX_TRUE) { 572 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf); 573 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) { 574 pVideoEnc->ANBColorFormat = Exynos_OSAL_GetANBColorFormat(ppBuf[0]); 575 if ((pVideoEnc->ANBColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) || 576 (pVideoEnc->ANBColorFormat == OMX_SEC_COLOR_FormatNV12Tiled)) { 577 exynosInputPort->bufferProcessType = BUFFER_SHARE; 578 } else { 579 exynosInputPort->bufferProcessType = BUFFER_COPY; 580 } 581 582 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 583 Exynos_OSAL_SemaphoreCreate(&exynosInputPort->codecSemID); 584 Exynos_OSAL_QueueCreate(&exynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS); 585 586 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) { 587 pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER)); 588 /* Use ION Allocator */ 589 /*Alloc Y-Buffer */ 590 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY); 591 pVideoEnc->pMFCEncInputBuffer[i]->fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); 592 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE; 593 /*Alloc C-Buffer */ 594 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY); 595 pVideoEnc->pMFCEncInputBuffer[i]->fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); 596 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE; 597 598 pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0; 599 600 if ((pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] == NULL) || 601 (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] == NULL)) { 602 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer"); 603 ret = OMX_ErrorInsufficientResources; 604 goto EXIT; 605 } 606 607 /* MFC input buffers are 1 plane. */ 608 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[2] = NULL; 609 pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1; 610 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0; 611 612 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]); 613 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]); 614 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]); 615 616 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]); 617 } 618 } else if (exynosInputPort->bufferProcessType == BUFFER_SHARE) { 619 /*************/ 620 /* TBD */ 621 /*************/ 622 /* Does not require any actions. */ 623 } 624 } 625 } 626 627 EXIT: 628 629 return ret; 630 } 631 #endif 632 633 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent) 634 { 635 OMX_ERRORTYPE ret = OMX_ErrorNone; 636 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 637 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 638 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 639 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 640 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer; 641 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData; 642 OMX_BOOL bCheckInputData = OMX_FALSE; 643 OMX_BOOL bValidCodecData = OMX_FALSE; 644 645 FunctionIn(); 646 647 while (!pVideoEnc->bExitBufferProcessThread) { 648 Exynos_OSAL_SleepMillisec(0); 649 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX); 650 651 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) && 652 (!pVideoEnc->bExitBufferProcessThread)) { 653 Exynos_OSAL_SleepMillisec(0); 654 655 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) 656 break; 657 if (exynosInputPort->portState != OMX_StateIdle) 658 break; 659 660 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex); 661 if (pVideoEnc->bFirstInput == OMX_FALSE) { 662 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 663 OMX_PTR codecBuffer; 664 if ((pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) { 665 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer); 666 if (codecBuffer != NULL) { 667 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData); 668 } 669 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 670 break; 671 } 672 } 673 674 if (srcInputUseBuffer->dataValid == OMX_TRUE) { 675 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData); 676 } else { 677 bCheckInputData = OMX_FALSE; 678 } 679 } 680 if ((bCheckInputData == OMX_FALSE) && 681 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { 682 ret = Exynos_InputBufferGetQueue(pExynosComponent); 683 if (ret != OMX_ErrorNone) { 684 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 685 break; 686 } 687 #ifdef USE_METADATABUFFERTYPE 688 if ((pVideoEnc->bFirstInput == OMX_TRUE) && 689 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) { 690 Exynos_OMX_ExtensionSetup(hComponent); 691 pVideoEnc->bFirstInput = OMX_FALSE; 692 } 693 #endif 694 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 695 break; 696 } 697 698 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) { 699 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 700 break; 701 } 702 703 ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData); 704 Exynos_ResetCodecData(pSrcInputData); 705 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 706 if (ret == OMX_ErrorCodecInit) 707 pVideoEnc->bExitBufferProcessThread = OMX_TRUE; 708 } 709 } 710 711 EXIT: 712 713 FunctionOut(); 714 715 return ret; 716 } 717 718 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent) 719 { 720 OMX_ERRORTYPE ret = OMX_ErrorNone; 721 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 722 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 723 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 724 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 725 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer; 726 EXYNOS_OMX_DATA srcOutputData; 727 728 FunctionIn(); 729 730 while (!pVideoEnc->bExitBufferProcessThread) { 731 Exynos_OSAL_SleepMillisec(0); 732 733 while (!pVideoEnc->bExitBufferProcessThread) { 734 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 735 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE) 736 break; 737 } 738 Exynos_OSAL_SleepMillisec(0); 739 740 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) 741 break; 742 743 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex); 744 ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData); 745 746 if (ret == OMX_ErrorNone) { 747 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 748 OMX_PTR codecBuffer; 749 codecBuffer = srcOutputData.pPrivate; 750 if (codecBuffer != NULL) 751 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer); 752 } 753 if (exynosInputPort->bufferProcessType == BUFFER_SHARE) { 754 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer); 755 Exynos_InputBufferReturn(pOMXComponent); 756 } 757 Exynos_ResetCodecData(&srcOutputData); 758 } 759 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex); 760 } 761 } 762 763 EXIT: 764 765 FunctionOut(); 766 767 return ret; 768 } 769 770 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) 771 { 772 OMX_ERRORTYPE ret = OMX_ErrorNone; 773 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 774 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 775 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 776 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 777 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer; 778 EXYNOS_OMX_DATA dstInputData; 779 780 FunctionIn(); 781 782 while (!pVideoEnc->bExitBufferProcessThread) { 783 Exynos_OSAL_SleepMillisec(0); 784 785 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && 786 (!pVideoEnc->bExitBufferProcessThread)) { 787 Exynos_OSAL_SleepMillisec(0); 788 789 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) || 790 (!CHECK_PORT_POPULATED(exynosOutputPort))) 791 break; 792 if (exynosOutputPort->portState != OMX_StateIdle) 793 break; 794 795 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex); 796 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 797 OMX_PTR codecBuffer; 798 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer); 799 if (ret != OMX_ErrorNone) { 800 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 801 break; 802 } 803 Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData); 804 } 805 806 if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { 807 if ((dstInputUseBuffer->dataValid != OMX_TRUE) && 808 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { 809 ret = Exynos_OutputBufferGetQueue(pExynosComponent); 810 if (ret != OMX_ErrorNone) { 811 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 812 break; 813 } 814 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE); 815 Exynos_ResetDataBuffer(dstInputUseBuffer); 816 } 817 } 818 819 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) { 820 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 821 break; 822 } 823 ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData); 824 825 Exynos_ResetCodecData(&dstInputData); 826 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 827 } 828 } 829 830 EXIT: 831 832 FunctionOut(); 833 834 return ret; 835 } 836 837 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent) 838 { 839 OMX_ERRORTYPE ret = OMX_ErrorNone; 840 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 841 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 842 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 843 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 844 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; 845 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData; 846 847 FunctionIn(); 848 849 while (!pVideoEnc->bExitBufferProcessThread) { 850 Exynos_OSAL_SleepMillisec(0); 851 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX); 852 853 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && 854 (!pVideoEnc->bExitBufferProcessThread)) { 855 Exynos_OSAL_SleepMillisec(0); 856 857 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) 858 break; 859 860 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex); 861 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 862 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) && 863 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { 864 ret = Exynos_OutputBufferGetQueue(pExynosComponent); 865 if (ret != OMX_ErrorNone) { 866 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); 867 break; 868 } 869 } 870 } 871 872 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) || 873 (exynosOutputPort->bufferProcessType == BUFFER_SHARE)) 874 ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData); 875 876 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) || 877 (exynosOutputPort->bufferProcessType == BUFFER_SHARE)) { 878 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData); 879 } 880 881 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 882 OMX_PTR codecBuffer; 883 codecBuffer = pDstOutputData->pPrivate; 884 if (codecBuffer != NULL) { 885 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer); 886 pDstOutputData->pPrivate = NULL; 887 } 888 } 889 890 /* reset outputData */ 891 Exynos_ResetCodecData(pDstOutputData); 892 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); 893 } 894 } 895 896 EXIT: 897 898 FunctionOut(); 899 900 return ret; 901 } 902 903 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData) 904 { 905 OMX_ERRORTYPE ret = OMX_ErrorNone; 906 OMX_COMPONENTTYPE *pOMXComponent = NULL; 907 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 908 EXYNOS_OMX_MESSAGE *message = NULL; 909 910 FunctionIn(); 911 912 if (threadData == NULL) { 913 ret = OMX_ErrorBadParameter; 914 goto EXIT; 915 } 916 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 917 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 918 if (ret != OMX_ErrorNone) { 919 goto EXIT; 920 } 921 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 922 Exynos_OMX_SrcInputBufferProcess(pOMXComponent); 923 924 Exynos_OSAL_ThreadExit(NULL); 925 926 EXIT: 927 FunctionOut(); 928 929 return ret; 930 } 931 932 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData) 933 { 934 OMX_ERRORTYPE ret = OMX_ErrorNone; 935 OMX_COMPONENTTYPE *pOMXComponent = NULL; 936 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 937 EXYNOS_OMX_MESSAGE *message = NULL; 938 939 FunctionIn(); 940 941 if (threadData == NULL) { 942 ret = OMX_ErrorBadParameter; 943 goto EXIT; 944 } 945 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 946 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 947 if (ret != OMX_ErrorNone) { 948 goto EXIT; 949 } 950 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 951 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent); 952 953 Exynos_OSAL_ThreadExit(NULL); 954 955 EXIT: 956 FunctionOut(); 957 958 return ret; 959 } 960 961 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData) 962 { 963 OMX_ERRORTYPE ret = OMX_ErrorNone; 964 OMX_COMPONENTTYPE *pOMXComponent = NULL; 965 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 966 EXYNOS_OMX_MESSAGE *message = NULL; 967 968 FunctionIn(); 969 970 if (threadData == NULL) { 971 ret = OMX_ErrorBadParameter; 972 goto EXIT; 973 } 974 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 975 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 976 if (ret != OMX_ErrorNone) { 977 goto EXIT; 978 } 979 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 980 Exynos_OMX_DstInputBufferProcess(pOMXComponent); 981 982 Exynos_OSAL_ThreadExit(NULL); 983 984 EXIT: 985 FunctionOut(); 986 987 return ret; 988 } 989 990 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData) 991 { 992 OMX_ERRORTYPE ret = OMX_ErrorNone; 993 OMX_COMPONENTTYPE *pOMXComponent = NULL; 994 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 995 EXYNOS_OMX_MESSAGE *message = NULL; 996 997 FunctionIn(); 998 999 if (threadData == NULL) { 1000 ret = OMX_ErrorBadParameter; 1001 goto EXIT; 1002 } 1003 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 1004 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1005 if (ret != OMX_ErrorNone) { 1006 goto EXIT; 1007 } 1008 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1009 Exynos_OMX_DstOutputBufferProcess(pOMXComponent); 1010 1011 Exynos_OSAL_ThreadExit(NULL); 1012 1013 EXIT: 1014 FunctionOut(); 1015 1016 return ret; 1017 } 1018 1019 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent) 1020 { 1021 OMX_ERRORTYPE ret = OMX_ErrorNone; 1022 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1023 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1024 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1025 1026 FunctionIn(); 1027 1028 pVideoEnc->bExitBufferProcessThread = OMX_FALSE; 1029 1030 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread, 1031 Exynos_OMX_DstOutputProcessThread, 1032 pOMXComponent); 1033 if (ret == OMX_ErrorNone) 1034 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread, 1035 Exynos_OMX_SrcOutputProcessThread, 1036 pOMXComponent); 1037 if (ret == OMX_ErrorNone) 1038 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread, 1039 Exynos_OMX_DstInputProcessThread, 1040 pOMXComponent); 1041 if (ret == OMX_ErrorNone) 1042 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread, 1043 Exynos_OMX_SrcInputProcessThread, 1044 pOMXComponent); 1045 1046 EXIT: 1047 FunctionOut(); 1048 1049 return ret; 1050 } 1051 1052 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) 1053 { 1054 OMX_ERRORTYPE ret = OMX_ErrorNone; 1055 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1056 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1057 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1058 OMX_S32 countValue = 0; 1059 unsigned int i = 0; 1060 1061 FunctionIn(); 1062 1063 pVideoEnc->bExitBufferProcessThread = OMX_TRUE; 1064 1065 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue); 1066 if (countValue == 0) 1067 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID); 1068 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue); 1069 if (countValue == 0) 1070 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID); 1071 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); 1072 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread); 1073 pVideoEnc->hSrcInputThread = NULL; 1074 1075 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue); 1076 if (countValue == 0) 1077 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID); 1078 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue); 1079 if (countValue == 0) 1080 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID); 1081 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); 1082 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread); 1083 pVideoEnc->hDstInputThread = NULL; 1084 1085 pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX); 1086 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); 1087 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); 1088 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread); 1089 pVideoEnc->hSrcOutputThread = NULL; 1090 1091 pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX); 1092 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); 1093 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); 1094 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread); 1095 pVideoEnc->hDstOutputThread = NULL; 1096 1097 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; 1098 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; 1099 1100 EXIT: 1101 FunctionOut(); 1102 1103 return ret; 1104 } 1105 1106 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) 1107 { 1108 OMX_ERRORTYPE ret = OMX_ErrorNone; 1109 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1110 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1111 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1112 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; 1113 1114 CSC_METHOD csc_method = CSC_METHOD_SW; 1115 1116 FunctionIn(); 1117 1118 if (hComponent == NULL) { 1119 ret = OMX_ErrorBadParameter; 1120 goto EXIT; 1121 } 1122 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1123 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1124 if (ret != OMX_ErrorNone) { 1125 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1126 goto EXIT; 1127 } 1128 1129 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent); 1130 if (ret != OMX_ErrorNone) { 1131 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1132 goto EXIT; 1133 } 1134 1135 ret = Exynos_OMX_Port_Constructor(pOMXComponent); 1136 if (ret != OMX_ErrorNone) { 1137 Exynos_OMX_BaseComponent_Destructor(pOMXComponent); 1138 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1139 goto EXIT; 1140 } 1141 1142 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1143 1144 pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); 1145 if (pVideoEnc == NULL) { 1146 Exynos_OMX_BaseComponent_Destructor(pOMXComponent); 1147 ret = OMX_ErrorInsufficientResources; 1148 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1149 goto EXIT; 1150 } 1151 1152 Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); 1153 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; 1154 1155 pExynosComponent->bSaveFlagEOS = OMX_FALSE; 1156 pExynosComponent->bBehaviorEOS = OMX_FALSE; 1157 1158 pVideoEnc->bFirstInput = OMX_FALSE; 1159 pVideoEnc->bFirstOutput = OMX_FALSE; 1160 pVideoEnc->configChange = OMX_FALSE; 1161 pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter 1162 pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter 1163 pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter 1164 1165 pVideoEnc->csc_handle = csc_init(csc_method); 1166 if (pVideoEnc->csc_handle == NULL) { 1167 Exynos_OSAL_Free(pVideoEnc); 1168 Exynos_OMX_BaseComponent_Destructor(pOMXComponent); 1169 ret = OMX_ErrorInsufficientResources; 1170 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1171 goto EXIT; 1172 } 1173 pVideoEnc->csc_set_format = OMX_FALSE; 1174 #if defined(USE_CSC_GSCALER) && defined(USE_CSC_G2D) 1175 #error USE_CSC_GSCALER and USE_CSC_G2D are mutually exclusive 1176 #elif defined(USE_CSC_GSCALER) 1177 csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, CSC_GSCALER_IDX); 1178 csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_GSCALER); 1179 #elif defined(USE_CSC_G2D) 1180 csc_set_hw_property(pVideoEnc->csc_handle, CSC_HW_PROPERTY_HW_TYPE, CSC_HW_TYPE_G2D); 1181 #endif 1182 1183 pExynosComponent->bMultiThreadProcess = OMX_TRUE; 1184 1185 /* Input port */ 1186 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1187 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; 1188 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; 1189 pExynosPort->portDefinition.nBufferSize = 0; 1190 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; 1191 1192 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); 1193 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1194 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1195 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1196 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1197 1198 pExynosPort->portDefinition.format.video.nFrameWidth = 0; 1199 pExynosPort->portDefinition.format.video.nFrameHeight= 0; 1200 pExynosPort->portDefinition.format.video.nStride = 0; 1201 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1202 pExynosPort->portDefinition.format.video.nBitrate = 64000; 1203 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); 1204 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1205 pExynosPort->portDefinition.format.video.pNativeWindow = NULL; 1206 pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; 1207 1208 pExynosPort->bStoreMetaData = OMX_FALSE; 1209 1210 /* Output port */ 1211 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1212 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; 1213 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; 1214 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; 1215 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; 1216 1217 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); 1218 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1219 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1220 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1221 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1222 1223 pExynosPort->portDefinition.format.video.nFrameWidth = 0; 1224 pExynosPort->portDefinition.format.video.nFrameHeight= 0; 1225 pExynosPort->portDefinition.format.video.nStride = 0; 1226 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1227 pExynosPort->portDefinition.format.video.nBitrate = 64000; 1228 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); 1229 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1230 pExynosPort->portDefinition.format.video.pNativeWindow = NULL; 1231 pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; 1232 1233 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; 1234 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; 1235 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; 1236 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest; 1237 1238 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer; 1239 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer; 1240 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create; 1241 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; 1242 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; 1243 1244 EXIT: 1245 FunctionOut(); 1246 1247 return ret; 1248 } 1249 1250 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) 1251 { 1252 OMX_ERRORTYPE ret = OMX_ErrorNone; 1253 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1254 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1255 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1256 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; 1257 int i = 0; 1258 1259 FunctionIn(); 1260 1261 if (hComponent == NULL) { 1262 ret = OMX_ErrorBadParameter; 1263 goto EXIT; 1264 } 1265 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1266 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1267 if (ret != OMX_ErrorNone) { 1268 goto EXIT; 1269 } 1270 1271 if (pOMXComponent->pComponentPrivate == NULL) { 1272 ret = OMX_ErrorBadParameter; 1273 goto EXIT; 1274 } 1275 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1276 1277 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1278 1279 if (pVideoEnc->csc_handle != NULL) { 1280 csc_deinit(pVideoEnc->csc_handle); 1281 pVideoEnc->csc_handle = NULL; 1282 } 1283 1284 Exynos_OSAL_Free(pVideoEnc); 1285 pExynosComponent->hComponentHandle = pVideoEnc = NULL; 1286 1287 for(i = 0; i < ALL_PORT_NUM; i++) { 1288 pExynosPort = &pExynosComponent->pExynosPort[i]; 1289 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType); 1290 pExynosPort->portDefinition.format.video.cMIMEType = NULL; 1291 } 1292 1293 ret = Exynos_OMX_Port_Destructor(pOMXComponent); 1294 1295 ret = Exynos_OMX_BaseComponent_Destructor(hComponent); 1296 1297 EXIT: 1298 FunctionOut(); 1299 1300 return ret; 1301 } 1302