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