Exynos_OMX_Venc.c revision 33d6044e338e2ea5c8580b6a52840808e459d998
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_ERROR, "drop frame after seeking"); 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_ERROR, "not set check timestame after seeking"); 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 Exynos_OMX_ExtensionSetup(hComponent); 667 pVideoEnc->bFirstInput = OMX_FALSE; 668 } 669#endif 670 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 671 break; 672 } 673 674 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) { 675 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 676 break; 677 } 678 679 ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData); 680 Exynos_ResetCodecData(pSrcInputData); 681 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex); 682 if (ret == OMX_ErrorCodecInit) 683 pVideoEnc->bExitBufferProcessThread = OMX_TRUE; 684 } 685 } 686 687EXIT: 688 689 FunctionOut(); 690 691 return ret; 692} 693 694OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent) 695{ 696 OMX_ERRORTYPE ret = OMX_ErrorNone; 697 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 698 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 699 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 700 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 701 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer; 702 EXYNOS_OMX_DATA srcOutputData; 703 704 FunctionIn(); 705 706 while (!pVideoEnc->bExitBufferProcessThread) { 707 Exynos_OSAL_SleepMillisec(0); 708 709 while (!pVideoEnc->bExitBufferProcessThread) { 710 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 711 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE) 712 break; 713 } 714 Exynos_OSAL_SleepMillisec(0); 715 716 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) 717 break; 718 719 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex); 720 ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData); 721 722 if (ret == OMX_ErrorNone) { 723 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 724 OMX_PTR codecBuffer; 725 codecBuffer = srcOutputData.pPrivate; 726 if (codecBuffer != NULL) 727 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer); 728 } 729 if (exynosInputPort->bufferProcessType == BUFFER_SHARE) { 730 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer); 731 Exynos_InputBufferReturn(pOMXComponent); 732 } 733 Exynos_ResetCodecData(&srcOutputData); 734 } 735 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex); 736 } 737 } 738 739EXIT: 740 741 FunctionOut(); 742 743 return ret; 744} 745 746OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent) 747{ 748 OMX_ERRORTYPE ret = OMX_ErrorNone; 749 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 750 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 751 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 752 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 753 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer; 754 EXYNOS_OMX_DATA dstInputData; 755 756 FunctionIn(); 757 758 while (!pVideoEnc->bExitBufferProcessThread) { 759 Exynos_OSAL_SleepMillisec(0); 760 761 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && 762 (!pVideoEnc->bExitBufferProcessThread)) { 763 Exynos_OSAL_SleepMillisec(0); 764 765 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) || 766 (!CHECK_PORT_POPULATED(exynosOutputPort))) 767 break; 768 if (exynosOutputPort->portState != OMX_StateIdle) 769 break; 770 771 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex); 772 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 773 OMX_PTR codecBuffer; 774 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer); 775 if (ret != OMX_ErrorNone) { 776 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 777 break; 778 } 779 Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData); 780 } 781 782 if (exynosOutputPort->bufferProcessType == BUFFER_SHARE) { 783 if ((dstInputUseBuffer->dataValid != OMX_TRUE) && 784 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { 785 ret = Exynos_OutputBufferGetQueue(pExynosComponent); 786 if (ret != OMX_ErrorNone) { 787 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 788 break; 789 } 790 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE); 791 Exynos_ResetDataBuffer(dstInputUseBuffer); 792 } 793 } 794 795 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) { 796 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 797 break; 798 } 799 ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData); 800 801 Exynos_ResetCodecData(&dstInputData); 802 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex); 803 } 804 } 805 806EXIT: 807 808 FunctionOut(); 809 810 return ret; 811} 812 813OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent) 814{ 815 OMX_ERRORTYPE ret = OMX_ErrorNone; 816 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 817 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 818 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 819 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 820 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer; 821 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData; 822 823 FunctionIn(); 824 825 while (!pVideoEnc->bExitBufferProcessThread) { 826 Exynos_OSAL_SleepMillisec(0); 827 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX); 828 829 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) && 830 (!pVideoEnc->bExitBufferProcessThread)) { 831 Exynos_OSAL_SleepMillisec(0); 832 833 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) 834 break; 835 836 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex); 837 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 838 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) && 839 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) { 840 ret = Exynos_OutputBufferGetQueue(pExynosComponent); 841 if (ret != OMX_ErrorNone) { 842 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); 843 break; 844 } 845 } 846 } 847 848 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) || 849 (exynosOutputPort->bufferProcessType == BUFFER_SHARE)) 850 ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData); 851 852 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) || 853 (exynosOutputPort->bufferProcessType == BUFFER_SHARE)) { 854 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData); 855 } 856 857 if ((exynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) { 858 OMX_PTR codecBuffer; 859 codecBuffer = pDstOutputData->pPrivate; 860 if (codecBuffer != NULL) { 861 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer); 862 pDstOutputData->pPrivate = NULL; 863 } 864 } 865 866 /* reset outputData */ 867 Exynos_ResetCodecData(pDstOutputData); 868 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex); 869 } 870 } 871 872EXIT: 873 874 FunctionOut(); 875 876 return ret; 877} 878 879static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData) 880{ 881 OMX_ERRORTYPE ret = OMX_ErrorNone; 882 OMX_COMPONENTTYPE *pOMXComponent = NULL; 883 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 884 EXYNOS_OMX_MESSAGE *message = NULL; 885 886 FunctionIn(); 887 888 if (threadData == NULL) { 889 ret = OMX_ErrorBadParameter; 890 goto EXIT; 891 } 892 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 893 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 894 if (ret != OMX_ErrorNone) { 895 goto EXIT; 896 } 897 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 898 Exynos_OMX_SrcInputBufferProcess(pOMXComponent); 899 900 Exynos_OSAL_ThreadExit(NULL); 901 902EXIT: 903 FunctionOut(); 904 905 return ret; 906} 907 908static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData) 909{ 910 OMX_ERRORTYPE ret = OMX_ErrorNone; 911 OMX_COMPONENTTYPE *pOMXComponent = NULL; 912 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 913 EXYNOS_OMX_MESSAGE *message = NULL; 914 915 FunctionIn(); 916 917 if (threadData == NULL) { 918 ret = OMX_ErrorBadParameter; 919 goto EXIT; 920 } 921 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 922 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 923 if (ret != OMX_ErrorNone) { 924 goto EXIT; 925 } 926 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 927 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent); 928 929 Exynos_OSAL_ThreadExit(NULL); 930 931EXIT: 932 FunctionOut(); 933 934 return ret; 935} 936 937static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData) 938{ 939 OMX_ERRORTYPE ret = OMX_ErrorNone; 940 OMX_COMPONENTTYPE *pOMXComponent = NULL; 941 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 942 EXYNOS_OMX_MESSAGE *message = NULL; 943 944 FunctionIn(); 945 946 if (threadData == NULL) { 947 ret = OMX_ErrorBadParameter; 948 goto EXIT; 949 } 950 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 951 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 952 if (ret != OMX_ErrorNone) { 953 goto EXIT; 954 } 955 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 956 Exynos_OMX_DstInputBufferProcess(pOMXComponent); 957 958 Exynos_OSAL_ThreadExit(NULL); 959 960EXIT: 961 FunctionOut(); 962 963 return ret; 964} 965 966static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData) 967{ 968 OMX_ERRORTYPE ret = OMX_ErrorNone; 969 OMX_COMPONENTTYPE *pOMXComponent = NULL; 970 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 971 EXYNOS_OMX_MESSAGE *message = NULL; 972 973 FunctionIn(); 974 975 if (threadData == NULL) { 976 ret = OMX_ErrorBadParameter; 977 goto EXIT; 978 } 979 pOMXComponent = (OMX_COMPONENTTYPE *)threadData; 980 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 981 if (ret != OMX_ErrorNone) { 982 goto EXIT; 983 } 984 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 985 Exynos_OMX_DstOutputBufferProcess(pOMXComponent); 986 987 Exynos_OSAL_ThreadExit(NULL); 988 989EXIT: 990 FunctionOut(); 991 992 return ret; 993} 994 995OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent) 996{ 997 OMX_ERRORTYPE ret = OMX_ErrorNone; 998 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 999 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1000 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1001 1002 FunctionIn(); 1003 1004 pVideoEnc->bExitBufferProcessThread = OMX_FALSE; 1005 1006 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread, 1007 Exynos_OMX_DstOutputProcessThread, 1008 pOMXComponent); 1009 if (ret == OMX_ErrorNone) 1010 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread, 1011 Exynos_OMX_SrcOutputProcessThread, 1012 pOMXComponent); 1013 if (ret == OMX_ErrorNone) 1014 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread, 1015 Exynos_OMX_DstInputProcessThread, 1016 pOMXComponent); 1017 if (ret == OMX_ErrorNone) 1018 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread, 1019 Exynos_OMX_SrcInputProcessThread, 1020 pOMXComponent); 1021 1022EXIT: 1023 FunctionOut(); 1024 1025 return ret; 1026} 1027 1028OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent) 1029{ 1030 OMX_ERRORTYPE ret = OMX_ErrorNone; 1031 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1032 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1033 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1034 OMX_S32 countValue = 0; 1035 unsigned int i = 0; 1036 1037 FunctionIn(); 1038 1039 pVideoEnc->bExitBufferProcessThread = OMX_TRUE; 1040 1041 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue); 1042 if (countValue == 0) 1043 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID); 1044 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue); 1045 if (countValue == 0) 1046 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID); 1047 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); 1048 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread); 1049 pVideoEnc->hSrcInputThread = NULL; 1050 1051 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue); 1052 if (countValue == 0) 1053 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID); 1054 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue); 1055 if (countValue == 0) 1056 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID); 1057 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); 1058 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread); 1059 pVideoEnc->hDstInputThread = NULL; 1060 1061 pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX); 1062 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); 1063 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent); 1064 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread); 1065 pVideoEnc->hSrcOutputThread = NULL; 1066 1067 pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX); 1068 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX); 1069 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent); 1070 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread); 1071 pVideoEnc->hDstOutputThread = NULL; 1072 1073EXIT: 1074 FunctionOut(); 1075 1076 return ret; 1077} 1078 1079OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) 1080{ 1081 OMX_ERRORTYPE ret = OMX_ErrorNone; 1082 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1083 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1084 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1085 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; 1086 1087 FunctionIn(); 1088 1089 if (hComponent == NULL) { 1090 ret = OMX_ErrorBadParameter; 1091 goto EXIT; 1092 } 1093 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1094 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1095 if (ret != OMX_ErrorNone) { 1096 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1097 goto EXIT; 1098 } 1099 1100 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent); 1101 if (ret != OMX_ErrorNone) { 1102 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1103 goto EXIT; 1104 } 1105 1106 ret = Exynos_OMX_Port_Constructor(pOMXComponent); 1107 if (ret != OMX_ErrorNone) { 1108 Exynos_OMX_BaseComponent_Destructor(pOMXComponent); 1109 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); 1110 goto EXIT; 1111 } 1112 1113 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1114 1115 pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); 1116 if (pVideoEnc == NULL) { 1117 Exynos_OMX_BaseComponent_Destructor(pOMXComponent); 1118 ret = OMX_ErrorInsufficientResources; 1119 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); 1120 goto EXIT; 1121 } 1122 1123 Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT)); 1124 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc; 1125 1126 pExynosComponent->bSaveFlagEOS = OMX_FALSE; 1127 1128 pVideoEnc->bFirstInput = OMX_FALSE; 1129 pVideoEnc->bFirstOutput = OMX_FALSE; 1130 pVideoEnc->configChange = OMX_FALSE; 1131 pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter 1132 pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter 1133 pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter 1134 1135 pExynosComponent->bMultiThreadProcess = OMX_TRUE; 1136 1137 /* Input port */ 1138 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX]; 1139 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; 1140 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; 1141 pExynosPort->portDefinition.nBufferSize = 0; 1142 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; 1143 1144 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); 1145 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1146 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1147 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1148 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1149 1150 pExynosPort->portDefinition.format.video.nFrameWidth = 0; 1151 pExynosPort->portDefinition.format.video.nFrameHeight= 0; 1152 pExynosPort->portDefinition.format.video.nStride = 0; 1153 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1154 pExynosPort->portDefinition.format.video.nBitrate = 64000; 1155 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); 1156 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1157 pExynosPort->portDefinition.format.video.pNativeWindow = NULL; 1158 pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; 1159 1160 pExynosPort->bStoreMetaData = OMX_FALSE; 1161 1162 /* Output port */ 1163 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]; 1164 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; 1165 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; 1166 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; 1167 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo; 1168 1169 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); 1170 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video"); 1171 pExynosPort->portDefinition.format.video.pNativeRender = 0; 1172 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; 1173 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; 1174 1175 pExynosPort->portDefinition.format.video.nFrameWidth = 0; 1176 pExynosPort->portDefinition.format.video.nFrameHeight= 0; 1177 pExynosPort->portDefinition.format.video.nStride = 0; 1178 pExynosPort->portDefinition.format.video.nSliceHeight = 0; 1179 pExynosPort->portDefinition.format.video.nBitrate = 64000; 1180 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16); 1181 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; 1182 pExynosPort->portDefinition.format.video.pNativeWindow = NULL; 1183 pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable; 1184 1185 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer; 1186 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer; 1187 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer; 1188 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest; 1189 1190 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer; 1191 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer; 1192 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create; 1193 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate; 1194 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush; 1195 1196EXIT: 1197 FunctionOut(); 1198 1199 return ret; 1200} 1201 1202OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) 1203{ 1204 OMX_ERRORTYPE ret = OMX_ErrorNone; 1205 OMX_COMPONENTTYPE *pOMXComponent = NULL; 1206 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL; 1207 EXYNOS_OMX_BASEPORT *pExynosPort = NULL; 1208 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL; 1209 int i = 0; 1210 1211 FunctionIn(); 1212 1213 if (hComponent == NULL) { 1214 ret = OMX_ErrorBadParameter; 1215 goto EXIT; 1216 } 1217 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; 1218 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); 1219 if (ret != OMX_ErrorNone) { 1220 goto EXIT; 1221 } 1222 1223 if (pOMXComponent->pComponentPrivate == NULL) { 1224 ret = OMX_ErrorBadParameter; 1225 goto EXIT; 1226 } 1227 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; 1228 1229 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle; 1230 1231 Exynos_OSAL_Free(pVideoEnc); 1232 pExynosComponent->hComponentHandle = pVideoEnc = NULL; 1233 1234 for(i = 0; i < ALL_PORT_NUM; i++) { 1235 pExynosPort = &pExynosComponent->pExynosPort[i]; 1236 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType); 1237 pExynosPort->portDefinition.format.video.cMIMEType = NULL; 1238 } 1239 1240 ret = Exynos_OMX_Port_Destructor(pOMXComponent); 1241 1242 ret = Exynos_OMX_BaseComponent_Destructor(hComponent); 1243 1244EXIT: 1245 FunctionOut(); 1246 1247 return ret; 1248} 1249