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