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