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