3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file Exynos_OMX_Vdec.c
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * HyeYeon Chung (hyeon.chung@samsung.com)
23 * Yunji Kim (yunji.kim@samsung.com)
33 #include "Exynos_OMX_Macros.h"
34 #include "Exynos_OSAL_Event.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OMX_VdecControl.h"
37 #include "Exynos_OMX_Basecomponent.h"
38 #include "Exynos_OSAL_Thread.h"
39 #include "Exynos_OSAL_Semaphore.h"
40 #include "Exynos_OSAL_Mutex.h"
41 #include "Exynos_OSAL_ETC.h"
44 #include "Exynos_OSAL_Platform_Specific.h"
47 #include "ExynosVideoApi.h"
51 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_DEC"
52 #define EXYNOS_LOG_OFF
53 //#define EXYNOS_TRACE_ON
54 #include "Exynos_OSAL_Log.h"
56 int calc_plane(int width, int height)
60 mbX = ALIGN(width, S5P_FIMV_NV12MT_HALIGN);
61 mbY = ALIGN(height, S5P_FIMV_NV12MT_VALIGN);
63 return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
66 int calc_yplane(int width, int height)
70 mbX = ALIGN(width + 24, S5P_FIMV_NV12MT_HALIGN);
71 mbY = ALIGN(height + 16, S5P_FIMV_NV12MT_VALIGN);
73 return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
76 int calc_uvplane(int width, int height)
80 mbX = ALIGN(width + 16, S5P_FIMV_NV12MT_HALIGN);
81 mbY = ALIGN(height + 4, S5P_FIMV_NV12MT_VALIGN);
83 return ALIGN(mbX * mbY, S5P_FIMV_DEC_BUF_ALIGN);
86 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
88 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
89 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
90 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
92 if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
93 exynosInputPort->portDefinition.format.video.nFrameWidth) ||
94 (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
95 exynosInputPort->portDefinition.format.video.nFrameHeight)) {
96 OMX_U32 width = 0, height = 0;
98 exynosOutputPort->portDefinition.format.video.nFrameWidth =
99 exynosInputPort->portDefinition.format.video.nFrameWidth;
100 exynosOutputPort->portDefinition.format.video.nFrameHeight =
101 exynosInputPort->portDefinition.format.video.nFrameHeight;
102 width = exynosOutputPort->portDefinition.format.video.nStride =
103 exynosInputPort->portDefinition.format.video.nStride;
104 height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
105 exynosInputPort->portDefinition.format.video.nSliceHeight;
107 switch(exynosOutputPort->portDefinition.format.video.eColorFormat) {
108 case OMX_COLOR_FormatYUV420Planar:
109 case OMX_COLOR_FormatYUV420SemiPlanar:
111 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
113 #ifdef SLP_PLATFORM /* nv12t fd */
114 case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
116 exynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer);
119 case OMX_SEC_COLOR_FormatNV12Tiled:
120 width = exynosOutputPort->portDefinition.format.video.nFrameWidth;
121 height = exynosOutputPort->portDefinition.format.video.nFrameHeight;
122 if (width && height) {
123 int YBufferSize = calc_plane(width, height);
124 int CBufferSize = calc_plane(width, height >> 1);
125 exynosOutputPort->portDefinition.nBufferSize = YBufferSize + CBufferSize;
130 exynosOutputPort->portDefinition.nBufferSize = width * height * 2;
138 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
140 OMX_BOOL ret = OMX_FALSE;
141 #ifdef SLP_PLATFORM /* check state */
142 if (pExynosComponent->currentState != OMX_StateExecuting)
143 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateExecuting");
145 if (pExynosComponent->pExynosPort[nPortIndex].portState != OMX_StateIdle)
146 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "not OMX_StateIdle");
148 if (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)
149 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateExecutingToIdle");
151 if (pExynosComponent->transientState == EXYNOS_OMX_TransStateIdleToExecuting)
152 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "EXYNOS_OMX_TransStateIdleToExecuting");
154 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
155 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
156 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
157 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
160 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
161 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
162 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
163 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
173 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
175 OMX_ERRORTYPE ret = OMX_ErrorNone;
176 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
177 CODEC_DEC_BUFFER *pInputCodecBuffer = (CODEC_DEC_BUFFER *)codecBuffer;
179 pData->buffer.singlePlaneBuffer.dataBuffer = pInputCodecBuffer->pVirAddr[0];
180 pData->buffer.singlePlaneBuffer.fd = pInputCodecBuffer->fd[0];
181 pData->allocSize = pInputCodecBuffer->bufferSize[0];
182 pData->dataLen = pInputCodecBuffer->dataSize;
183 pData->usedDataLen = 0;
184 pData->remainDataLen = pInputCodecBuffer->dataSize;
187 pData->timeStamp = 0;
188 pData->pPrivate = codecBuffer;
189 pData->bufferHeader = NULL;
194 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
196 OMX_ERRORTYPE ret = OMX_ErrorNone;
197 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
198 OMX_PTR pSrcBuf[MAX_BUFFER_PLANE];
199 OMX_U32 allocSize[MAX_BUFFER_PLANE];
201 pVideoDec->exynos_codec_getCodecOutputPrivateData(codecBuffer, pSrcBuf, allocSize);
202 pData->buffer.multiPlaneBuffer.dataBuffer[0] = pSrcBuf[0];
203 pData->buffer.multiPlaneBuffer.dataBuffer[1] = pSrcBuf[1];
204 pData->buffer.multiPlaneBuffer.dataBuffer[2] = pSrcBuf[2];
205 pData->allocSize = allocSize[0] + allocSize[1] + allocSize[2];
207 pData->usedDataLen = 0;
208 pData->remainDataLen = 0;
211 pData->timeStamp = 0;
212 pData->pPrivate = codecBuffer;
213 pData->bufferHeader = NULL;
218 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
220 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
221 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
222 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
226 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
228 if (((pExynosComponent->currentState == OMX_StatePause) ||
229 (pExynosComponent->currentState == OMX_StateIdle) ||
230 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
231 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
232 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
233 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
234 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
235 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
243 OMX_BOOL Exynos_CSC_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
245 OMX_BOOL ret = OMX_FALSE;
246 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
247 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
248 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
249 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
251 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
252 OMX_U32 copySize = 0;
253 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
255 MMVideoBuffer *pSlpOutBuf = NULL;
260 OMX_U32 width = 0, height = 0;
262 OMX_COLOR_FORMATTYPE colorFormat;
264 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
265 void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
266 void *pYUVBuf[MAX_BUFFER_PLANE] = {NULL, };
268 CSC_ERRORCODE cscRet = CSC_ErrorNone;
269 CSC_METHOD csc_method = CSC_METHOD_SW;
270 unsigned int cacheable = 1;
272 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
274 width = pBufferInfo->imageWidth;
275 height = pBufferInfo->imageHeight;
276 imageSize = width * height;
277 colorFormat = pBufferInfo->ColorFormat;
280 pSlpOutBuf = (MMVideoBuffer *)pOutputBuf;
281 pSlpOutBuf->width[0] = width;
282 pSlpOutBuf->width[1] = width;
283 pSlpOutBuf->height[0] = height;
284 pSlpOutBuf->height[1] = height/2;
285 pSlpOutBuf->stride_width[0] = width; /* need to check. stride */
286 pSlpOutBuf->stride_width[1] = width;
287 pSlpOutBuf->stride_height[0] = height; /* need to check. elevation */
288 pSlpOutBuf->stride_height[1] = height/2;
290 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
291 pSlpOutBuf->data[0] = 0;
292 pSlpOutBuf->data[1] = 0;
294 pSlpOutBuf->data[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
295 pSlpOutBuf->data[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
297 pSlpOutBuf->data[2] = 0; /* omx do not use this plane */
300 pSlpOutBuf->handle.dmabuf_fd[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
301 pSlpOutBuf->handle.dmabuf_fd[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
302 pSlpOutBuf->handle.dmabuf_fd[2] = 0; /* omx do not use this plane */
304 //pSlpOutBuf->buf_share_method = MEMORY_DMABUF;
305 dstOutputData->dataLen = sizeof(MMVideoBuffer);
307 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__);
308 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1],
309 pSlpOutBuf->handle.dmabuf_fd[2]);
315 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
316 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
317 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
319 pYUVBuf[0] = (unsigned char *)pOutputBuf;
320 pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize;
321 pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
323 csc_get_method(pVideoDec->csc_handle, &csc_method);
325 if (csc_method == CSC_METHOD_HW) {
326 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
327 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
328 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
333 if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
334 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
336 Exynos_OSAL_LockPB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
338 outputUseBuffer->dataLen = sizeof(void *);
340 pYUVBuf[0] = (unsigned char *)planes[0].addr;
341 pYUVBuf[1] = (unsigned char *)planes[1].addr;
342 pYUVBuf[2] = (unsigned char *)planes[2].addr;
344 if (csc_method == CSC_METHOD_HW) {
345 pYUVBuf[0] = (unsigned char *)planes[0].fd;
346 pYUVBuf[1] = (unsigned char *)planes[1].fd;
347 pYUVBuf[2] = (unsigned char *)planes[2].fd;
353 if ((exynosOutputPort->bIsPBEnabled == OMX_FALSE) &&
354 (csc_method == CSC_METHOD_HW)) {
355 pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
361 if (pVideoDec->csc_set_format == OMX_FALSE) {
363 pVideoDec->csc_handle, /* handle */
368 width, /* crop_width */
369 height, /* crop_height */
370 omx_2_hal_pixel_format(colorFormat), /* color_format */
371 cacheable); /* cacheable */
373 pVideoDec->csc_handle, /* handle */
378 width, /* crop_width */
379 height, /* crop_height */
380 omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
381 cacheable); /* cacheable */
382 pVideoDec->csc_set_format = OMX_TRUE;
385 pVideoDec->csc_handle, /* handle */
386 pSrcBuf[0], /* y addr */
387 pSrcBuf[1], /* u addr or uv addr */
388 pSrcBuf[2], /* v addr or none */
391 pVideoDec->csc_handle, /* handle */
392 pYUVBuf[0], /* y addr */
393 pYUVBuf[1], /* u addr or uv addr */
394 pYUVBuf[2], /* v addr or none */
396 cscRet = csc_convert(pVideoDec->csc_handle);
397 if (cscRet != CSC_ErrorNone)
403 if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
405 Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData, exynosOutputPort, exynosInputPort);
407 Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData);
418 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
420 OMX_BOOL ret = OMX_FALSE;
421 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
422 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
423 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
424 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
425 OMX_U32 copySize = 0;
426 OMX_BYTE checkInputStream = NULL;
427 OMX_U32 checkInputStreamLen = 0;
431 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
432 if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
433 (srcInputData->pPrivate == NULL)) {
439 if (inputUseBuffer->dataValid == OMX_TRUE) {
440 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
441 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
444 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
445 OMX_PTR dataBuffer = NULL;
447 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
448 srcInputData->buffer.singlePlaneBuffer.dataBuffer);
449 if (dataBuffer == NULL) {
454 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
457 /* reset dataBuffer */
458 Exynos_ResetDataBuffer(inputUseBuffer);
459 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
460 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
461 checkInputStreamLen = inputUseBuffer->remainDataLen;
463 pExynosComponent->bUseFlagEOF = OMX_TRUE;
465 copySize = checkInputStreamLen;
466 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
468 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
470 Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
471 checkInputStream, copySize);
474 inputUseBuffer->dataLen -= copySize;
475 inputUseBuffer->remainDataLen -= copySize;
476 inputUseBuffer->usedDataLen += copySize;
478 srcInputData->dataLen += copySize;
479 srcInputData->remainDataLen += copySize;
481 srcInputData->timeStamp = inputUseBuffer->timeStamp;
482 srcInputData->nFlags = inputUseBuffer->nFlags;
483 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
485 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
486 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
487 pExynosComponent->callbackData,
488 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
492 Exynos_InputBufferReturn(pOMXComponent);
495 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
496 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
497 srcInputData->dataLen = 0;
498 srcInputData->remainDataLen = 0;
499 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
502 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
503 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
504 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
505 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
506 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
507 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
508 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
521 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
523 OMX_BOOL ret = OMX_FALSE;
524 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
525 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
526 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
527 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
528 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
529 OMX_U32 copySize = 0;
530 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
534 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
535 if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
536 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
537 outputUseBuffer->dataValid = OMX_TRUE;
541 if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort,exynosInputPort) == OMX_ErrorNone) {
543 if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
545 outputUseBuffer->dataValid = OMX_TRUE;
551 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s Should not come here", __FUNCTION__);
558 if (outputUseBuffer->dataValid == OMX_TRUE) {
559 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
560 dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
561 if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
562 ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
563 if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
564 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
565 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
566 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
567 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
568 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
569 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE;
571 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
572 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
573 Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
577 } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
579 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
583 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
584 OMX_U32 width = 0, height = 0;
586 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
588 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
590 width = pBufferInfo->imageWidth;
591 height = pBufferInfo->imageHeight;
592 imageSize = width * height;
594 if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
595 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
596 copySize = dstOutputData->remainDataLen;
597 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
599 outputUseBuffer->dataLen += copySize;
600 outputUseBuffer->remainDataLen += copySize;
601 outputUseBuffer->nFlags = dstOutputData->nFlags;
602 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
604 if (outputUseBuffer->remainDataLen > 0) {
605 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
610 if (ret == OMX_TRUE) {
611 if ((outputUseBuffer->remainDataLen > 0) ||
612 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
613 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
614 Exynos_OutputBufferReturn(pOMXComponent);
617 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
618 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
619 pExynosComponent->callbackData,
620 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
623 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
624 outputUseBuffer->dataLen = 0;
625 outputUseBuffer->remainDataLen = 0;
626 outputUseBuffer->nFlags = dstOutputData->nFlags;
627 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
628 Exynos_OutputBufferReturn(pOMXComponent);
631 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is SCMN_IMGB type.");
632 copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen;
634 outputUseBuffer->dataLen += copySize;
635 outputUseBuffer->remainDataLen += copySize;
636 outputUseBuffer->nFlags = 0; /* need to check */
637 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
639 if (outputUseBuffer->remainDataLen > 0) {
640 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
645 dstOutputData->remainDataLen -= copySize; /* need to check */
646 dstOutputData->usedDataLen += copySize;
648 Exynos_OutputBufferReturn(pOMXComponent);
650 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
651 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
652 pExynosComponent->callbackData,
653 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
657 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
658 if ((outputUseBuffer->remainDataLen > 0) ||
659 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
660 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
661 Exynos_OutputBufferReturn(pOMXComponent);
673 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
675 OMX_ERRORTYPE ret = OMX_ErrorNone;
676 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
677 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
678 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
679 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
680 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
681 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
682 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
683 OMX_BOOL bCheckInputData = OMX_FALSE;
684 OMX_BOOL bValidCodecData = OMX_FALSE;
685 OMX_BOOL bCodecConfigured = OMX_FALSE;
689 while (!pVideoDec->bExitBufferProcessThread) {
690 Exynos_OSAL_SleepMillisec(0);
691 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
693 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
694 (!pVideoDec->bExitBufferProcessThread)) {
695 Exynos_OSAL_SleepMillisec(0);
697 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
698 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)))
700 if (exynosInputPort->portState != OMX_StateIdle)
703 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
704 if (ret != OMX_ErrorInputDataDecodeYet) {
705 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
708 if ((pVideoDec->exynos_process_codecConfigData) && !bCodecConfigured) {
709 EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
710 ret = Exynos_InputBufferGetQueue(pExynosComponent);
712 inputUseBuffer = &(exynosInputPort->way.port2WayDataBuffer.inputDataBuffer);
713 pVideoDec->exynos_process_codecConfigData(pOMXComponent, inputUseBuffer); /* SLP_PLATFORM */
714 // pVideoDec->exynos_process_codecConfigData(pOMXComponent, pSrcInputData);
716 bCodecConfigured = OMX_TRUE;
719 if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
720 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
721 if (codecBuffer != NULL) {
722 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
724 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
729 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
730 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
732 bCheckInputData = OMX_FALSE;
735 if ((bCheckInputData == OMX_FALSE) &&
736 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
737 ret = Exynos_InputBufferGetQueue(pExynosComponent);
738 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
742 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
743 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
748 ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
750 if (ret == OMX_ErrorCorruptedFrame) {
751 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
753 codecBuffer = pSrcInputData->pPrivate;
754 if (codecBuffer != NULL)
755 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
758 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
759 Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
763 if (ret != OMX_ErrorInputDataDecodeYet) {
764 Exynos_ResetCodecData(pSrcInputData);
766 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
767 if (ret == OMX_ErrorCodecInit)
768 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
779 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
781 OMX_ERRORTYPE ret = OMX_ErrorNone;
782 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
783 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
784 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
785 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
786 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
787 EXYNOS_OMX_DATA srcOutputData;
791 while (!pVideoDec->bExitBufferProcessThread) {
792 Exynos_OSAL_SleepMillisec(0);
794 while (!pVideoDec->bExitBufferProcessThread) {
795 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
796 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
799 Exynos_OSAL_SleepMillisec(0);
801 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
804 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
805 ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
807 if (ret == OMX_ErrorNone) {
808 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
810 codecBuffer = srcOutputData.pPrivate;
811 if (codecBuffer != NULL)
812 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
814 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
815 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
816 Exynos_InputBufferReturn(pOMXComponent);
818 Exynos_ResetCodecData(&srcOutputData);
820 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
831 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
833 OMX_ERRORTYPE ret = OMX_ErrorNone;
834 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
835 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
836 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
837 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
838 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
839 EXYNOS_OMX_DATA dstInputData;
843 while (!pVideoDec->bExitBufferProcessThread) {
844 Exynos_OSAL_SleepMillisec(0);
846 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
847 (!pVideoDec->bExitBufferProcessThread)) {
848 Exynos_OSAL_SleepMillisec(0);
850 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
851 (!CHECK_PORT_POPULATED(exynosOutputPort)))
853 if (exynosOutputPort->portState != OMX_StateIdle)
856 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
857 if (ret != OMX_ErrorOutputBufferUseYet) {
858 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
860 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer);
861 if (ret != OMX_ErrorNone) {
862 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
865 Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData);
868 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
869 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
870 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
871 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
872 if (ret != OMX_ErrorNone) {
873 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
876 if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
877 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
880 ret = Exynos_Shared_PlatformBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
882 if (ret != OMX_ErrorNone) {
883 dstInputUseBuffer->dataValid = OMX_FALSE;
884 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
888 Exynos_ResetDataBuffer(dstInputUseBuffer);
892 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
893 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
898 ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
899 if (ret != OMX_ErrorOutputBufferUseYet) {
900 Exynos_ResetCodecData(&dstInputData);
902 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
913 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
915 OMX_ERRORTYPE ret = OMX_ErrorNone;
916 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
917 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
918 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
919 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
920 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
921 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
925 while (!pVideoDec->bExitBufferProcessThread) {
926 Exynos_OSAL_SleepMillisec(0);
927 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
929 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
930 (!pVideoDec->bExitBufferProcessThread)) {
931 Exynos_OSAL_SleepMillisec(0);
933 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
936 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
937 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
938 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
939 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
940 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
941 if (ret != OMX_ErrorNone) {
942 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
948 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
949 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
950 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
952 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
953 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
954 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
957 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
959 codecBuffer = pDstOutputData->pPrivate;
960 if (codecBuffer != NULL) {
961 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer);
962 pDstOutputData->pPrivate = NULL;
966 /* reset outputData */
967 Exynos_ResetCodecData(pDstOutputData);
968 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
979 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
981 OMX_ERRORTYPE ret = OMX_ErrorNone;
982 OMX_COMPONENTTYPE *pOMXComponent = NULL;
983 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
984 EXYNOS_OMX_MESSAGE *message = NULL;
988 if (threadData == NULL) {
989 ret = OMX_ErrorBadParameter;
992 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
993 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
994 if (ret != OMX_ErrorNone) {
997 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
998 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1000 Exynos_OSAL_ThreadExit(NULL);
1008 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1010 OMX_ERRORTYPE ret = OMX_ErrorNone;
1011 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1012 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1013 EXYNOS_OMX_MESSAGE *message = NULL;
1017 if (threadData == NULL) {
1018 ret = OMX_ErrorBadParameter;
1021 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1022 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1023 if (ret != OMX_ErrorNone) {
1026 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1027 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1029 Exynos_OSAL_ThreadExit(NULL);
1037 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1039 OMX_ERRORTYPE ret = OMX_ErrorNone;
1040 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1041 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1042 EXYNOS_OMX_MESSAGE *message = NULL;
1046 if (threadData == NULL) {
1047 ret = OMX_ErrorBadParameter;
1050 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1051 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1052 if (ret != OMX_ErrorNone) {
1055 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1056 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1058 Exynos_OSAL_ThreadExit(NULL);
1066 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1068 OMX_ERRORTYPE ret = OMX_ErrorNone;
1069 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1070 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1071 EXYNOS_OMX_MESSAGE *message = NULL;
1075 if (threadData == NULL) {
1076 ret = OMX_ErrorBadParameter;
1079 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1080 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1081 if (ret != OMX_ErrorNone) {
1084 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1085 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1087 Exynos_OSAL_ThreadExit(NULL);
1095 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1097 OMX_ERRORTYPE ret = OMX_ErrorNone;
1098 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1099 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1100 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1104 pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1106 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1107 Exynos_OMX_DstOutputProcessThread,
1109 if (ret == OMX_ErrorNone)
1110 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1111 Exynos_OMX_SrcOutputProcessThread,
1113 if (ret == OMX_ErrorNone)
1114 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1115 Exynos_OMX_DstInputProcessThread,
1117 if (ret == OMX_ErrorNone)
1118 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1119 Exynos_OMX_SrcInputProcessThread,
1128 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1130 OMX_ERRORTYPE ret = OMX_ErrorNone;
1131 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1132 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1133 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1134 OMX_S32 countValue = 0;
1139 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1141 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1142 if (countValue == 0)
1143 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1144 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1145 if (countValue == 0)
1146 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1147 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1148 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1149 pVideoDec->hSrcInputThread = NULL;
1151 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1152 if (countValue == 0)
1153 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1154 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1155 if (countValue == 0)
1156 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1157 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1158 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1159 pVideoDec->hDstInputThread = NULL;
1161 pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1162 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1163 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1164 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1165 pVideoDec->hSrcOutputThread = NULL;
1167 pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1168 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1169 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1170 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1171 pVideoDec->hDstOutputThread = NULL;
1179 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1181 OMX_ERRORTYPE ret = OMX_ErrorNone;
1182 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1183 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1184 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1185 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1189 if (hComponent == NULL) {
1190 ret = OMX_ErrorBadParameter;
1193 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1194 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1195 if (ret != OMX_ErrorNone) {
1196 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1200 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1201 if (ret != OMX_ErrorNone) {
1202 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1206 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1207 if (ret != OMX_ErrorNone) {
1208 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1209 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1213 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1215 pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1216 if (pVideoDec == NULL) {
1217 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1218 ret = OMX_ErrorInsufficientResources;
1219 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1223 Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1224 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1226 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1227 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1230 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1231 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1232 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1233 pExynosPort->portDefinition.nBufferSize = 0;
1234 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1236 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1237 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1238 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1239 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1240 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1242 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1243 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1244 pExynosPort->portDefinition.format.video.nStride = 0;
1245 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1246 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1247 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1248 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1249 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1252 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1253 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1254 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1255 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1256 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1258 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1259 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1260 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1261 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1262 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1264 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1265 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1266 pExynosPort->portDefinition.format.video.nStride = 0;
1267 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1268 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1269 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1270 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1271 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1273 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1275 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1276 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1277 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1278 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1280 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1281 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1282 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1283 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1284 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1292 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1294 OMX_ERRORTYPE ret = OMX_ErrorNone;
1295 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1296 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1297 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1298 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1303 if (hComponent == NULL) {
1304 ret = OMX_ErrorBadParameter;
1307 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1308 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1309 if (ret != OMX_ErrorNone) {
1313 if (pOMXComponent->pComponentPrivate == NULL) {
1314 ret = OMX_ErrorBadParameter;
1317 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1319 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1321 Exynos_OSAL_Free(pVideoDec);
1322 pExynosComponent->hComponentHandle = pVideoDec = NULL;
1324 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1325 if (pExynosPort->processData.extInfo != NULL) {
1326 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1327 pExynosPort->processData.extInfo = NULL;
1330 for(i = 0; i < ALL_PORT_NUM; i++) {
1331 pExynosPort = &pExynosComponent->pExynosPort[i];
1332 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1333 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1336 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1338 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);