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