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 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 TIZEN_FEATURE_E3250 /* 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 TIZEN_FEATURE_E3250 /* 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;
254 #ifdef TIZEN_FEATURE_E3250
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;
279 #ifdef TIZEN_FEATURE_E3250
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->handle.bo[0] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[0];
305 pSlpOutBuf->handle.bo[1] = dstOutputData->buffer.multiPlaneBuffer.tbm_bo[1];
306 pSlpOutBuf->handle.bo[2] = NULL;
308 //pSlpOutBuf->type = MM_VIDEO_BUFFER_TYPE_DMABUF_FD;
309 dstOutputData->dataLen = sizeof(MMVideoBuffer);
311 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s: using fd instead of csc", __FUNCTION__);
312 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fd (%d, %d, %d) received from MFC", pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1],
313 pSlpOutBuf->handle.dmabuf_fd[2]);
319 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[0];
320 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[1];
321 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.dataBuffer[2];
323 pYUVBuf[0] = (unsigned char *)pOutputBuf;
324 pYUVBuf[1] = (unsigned char *)pOutputBuf + imageSize;
325 pYUVBuf[2] = (unsigned char *)pOutputBuf + imageSize + imageSize / 4;
327 csc_get_method(pVideoDec->csc_handle, &csc_method);
329 if (csc_method == CSC_METHOD_HW) {
330 pSrcBuf[0] = dstOutputData->buffer.multiPlaneBuffer.fd[0];
331 pSrcBuf[1] = dstOutputData->buffer.multiPlaneBuffer.fd[1];
332 pSrcBuf[2] = dstOutputData->buffer.multiPlaneBuffer.fd[2];
337 if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
338 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
340 Exynos_OSAL_LockPB(pOutputBuf, width, height, exynosOutputPort->portDefinition.format.video.eColorFormat, &stride, planes);
342 outputUseBuffer->dataLen = sizeof(void *);
344 pYUVBuf[0] = (unsigned char *)planes[0].addr;
345 pYUVBuf[1] = (unsigned char *)planes[1].addr;
346 pYUVBuf[2] = (unsigned char *)planes[2].addr;
348 if (csc_method == CSC_METHOD_HW) {
349 pYUVBuf[0] = (unsigned char *)planes[0].fd;
350 pYUVBuf[1] = (unsigned char *)planes[1].fd;
351 pYUVBuf[2] = (unsigned char *)planes[2].fd;
357 if ((exynosOutputPort->bIsPBEnabled == OMX_FALSE) &&
358 (csc_method == CSC_METHOD_HW)) {
359 pYUVBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pOutputBuf);
365 if (pVideoDec->csc_set_format == OMX_FALSE) {
367 pVideoDec->csc_handle, /* handle */
372 width, /* crop_width */
373 height, /* crop_height */
374 omx_2_hal_pixel_format(colorFormat), /* color_format */
375 cacheable); /* cacheable */
377 pVideoDec->csc_handle, /* handle */
382 width, /* crop_width */
383 height, /* crop_height */
384 omx_2_hal_pixel_format(exynosOutputPort->portDefinition.format.video.eColorFormat), /* color_format */
385 cacheable); /* cacheable */
386 pVideoDec->csc_set_format = OMX_TRUE;
389 pVideoDec->csc_handle, /* handle */
390 pSrcBuf[0], /* y addr */
391 pSrcBuf[1], /* u addr or uv addr */
392 pSrcBuf[2], /* v addr or none */
395 pVideoDec->csc_handle, /* handle */
396 pYUVBuf[0], /* y addr */
397 pYUVBuf[1], /* u addr or uv addr */
398 pYUVBuf[2], /* v addr or none */
400 cscRet = csc_convert(pVideoDec->csc_handle);
401 if (cscRet != CSC_ErrorNone)
407 if (exynosOutputPort->bIsPBEnabled == OMX_TRUE) {
408 #ifdef TIZEN_FEATURE_E3250
409 Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData, exynosOutputPort, exynosInputPort);
411 Exynos_OSAL_UnlockPB(pOutputBuf, dstOutputData);
422 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
424 OMX_BOOL ret = OMX_FALSE;
425 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
426 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
427 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
428 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
429 OMX_U32 copySize = 0;
430 OMX_BYTE checkInputStream = NULL;
431 OMX_U32 checkInputStreamLen = 0;
435 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
436 if ((srcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) ||
437 (srcInputData->pPrivate == NULL)) {
443 if (inputUseBuffer->dataValid == OMX_TRUE) {
444 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
445 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
447 #ifndef TIZEN_FEATURE_E3250
448 if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
449 OMX_PTR dataBuffer = NULL;
451 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
452 srcInputData->buffer.singlePlaneBuffer.dataBuffer);
453 if (dataBuffer == NULL) {
458 srcInputData->buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
461 /* reset dataBuffer */
462 Exynos_ResetDataBuffer(inputUseBuffer);
463 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
464 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
465 checkInputStreamLen = inputUseBuffer->remainDataLen;
467 pExynosComponent->bUseFlagEOF = OMX_TRUE;
469 copySize = checkInputStreamLen;
470 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
472 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
474 Exynos_OSAL_Memcpy(srcInputData->buffer.singlePlaneBuffer.dataBuffer + srcInputData->dataLen,
475 checkInputStream, copySize);
478 inputUseBuffer->dataLen -= copySize;
479 inputUseBuffer->remainDataLen -= copySize;
480 inputUseBuffer->usedDataLen += copySize;
482 srcInputData->dataLen += copySize;
483 srcInputData->remainDataLen += copySize;
485 srcInputData->timeStamp = inputUseBuffer->timeStamp;
486 srcInputData->nFlags = inputUseBuffer->nFlags;
487 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
489 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
490 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
491 pExynosComponent->callbackData,
492 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
496 Exynos_InputBufferReturn(pOMXComponent);
499 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
500 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
501 srcInputData->dataLen = 0;
502 srcInputData->remainDataLen = 0;
503 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
506 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
507 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
508 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
509 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
510 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
511 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
512 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
525 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
527 OMX_BOOL ret = OMX_FALSE;
528 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
529 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
530 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
531 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
532 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
533 OMX_U32 copySize = 0;
534 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
538 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
539 if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
540 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer) == OMX_ErrorNone)
541 outputUseBuffer->dataValid = OMX_TRUE;
544 #ifdef TIZEN_FEATURE_E3250
545 if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort,exynosInputPort) == OMX_ErrorNone) {
547 if (Exynos_Shared_DataToPlatformBuffer(dstOutputData, outputUseBuffer, exynosOutputPort) == OMX_ErrorNone) {
549 outputUseBuffer->dataValid = OMX_TRUE;
555 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s Should not come here", __FUNCTION__);
562 if (outputUseBuffer->dataValid == OMX_TRUE) {
563 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out timestamp after seeking %lld us (%.2f secs)",
564 dstOutputData->timeStamp, dstOutputData->timeStamp / 1E6);
565 if ((pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) &&
566 ((dstOutputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS)) {
567 if ((pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp) &&
568 (pExynosComponent->checkTimeStamp.nStartFlags == dstOutputData->nFlags)){
569 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
570 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
571 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
572 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
573 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_FALSE;
575 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "drop frame after seeking", pExynosComponent);
576 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE)
577 Exynos_OMX_FillThisBuffer(pOMXComponent, outputUseBuffer->bufferHeader);
581 } else if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE)) {
583 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "not set check timestame after seeking");
587 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
588 OMX_U32 width = 0, height = 0;
590 void *pOutputBuf = (void *)outputUseBuffer->bufferHeader->pBuffer;
592 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)dstOutputData->extInfo;
594 width = pBufferInfo->imageWidth;
595 height = pBufferInfo->imageHeight;
596 imageSize = width * height;
598 if ((dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) &&
599 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
600 copySize = dstOutputData->remainDataLen;
601 Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"copySize: %d", copySize);
603 outputUseBuffer->dataLen += copySize;
604 outputUseBuffer->remainDataLen += copySize;
605 outputUseBuffer->nFlags = dstOutputData->nFlags;
606 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
608 if (outputUseBuffer->remainDataLen > 0) {
609 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
614 if (ret == OMX_TRUE) {
615 if ((outputUseBuffer->remainDataLen > 0) ||
616 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
617 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
618 Exynos_OutputBufferReturn(pOMXComponent);
621 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "csc_convert Error");
622 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
623 pExynosComponent->callbackData,
624 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
627 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
628 outputUseBuffer->dataLen = 0;
629 outputUseBuffer->remainDataLen = 0;
630 outputUseBuffer->nFlags = dstOutputData->nFlags;
631 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
632 Exynos_OutputBufferReturn(pOMXComponent);
634 #ifdef TIZEN_FEATURE_E3250
635 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is SCMN_IMGB type.");
636 copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen;
638 outputUseBuffer->dataLen += copySize;
639 outputUseBuffer->remainDataLen += copySize;
640 outputUseBuffer->nFlags = 0; /* need to check */
641 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
643 if (outputUseBuffer->remainDataLen > 0) {
644 ret = Exynos_CSC_OutputData(pOMXComponent, dstOutputData);
649 dstOutputData->remainDataLen -= copySize; /* need to check */
650 dstOutputData->usedDataLen += copySize;
652 Exynos_OutputBufferReturn(pOMXComponent);
654 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than decoded data size Out Length");
655 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
656 pExynosComponent->callbackData,
657 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
661 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
662 if ((outputUseBuffer->remainDataLen > 0) ||
663 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
664 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
665 Exynos_OutputBufferReturn(pOMXComponent);
677 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
679 OMX_ERRORTYPE ret = OMX_ErrorNone;
680 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
681 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
682 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
683 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
684 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
685 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
686 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
687 OMX_BOOL bCheckInputData = OMX_FALSE;
688 OMX_BOOL bValidCodecData = OMX_FALSE;
689 OMX_BOOL bCodecConfigured = OMX_FALSE;
693 while (!pVideoDec->bExitBufferProcessThread) {
694 Exynos_OSAL_SleepMillisec(0);
695 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
697 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
698 (!pVideoDec->bExitBufferProcessThread)) {
699 Exynos_OSAL_SleepMillisec(0);
701 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort)) ||
702 ((exynosOutputPort->exceptionFlag == NEED_PORT_DISABLE) && (ret == OMX_ErrorInputDataDecodeYet)))
704 if (exynosInputPort->portState != OMX_StateIdle)
707 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
708 if (ret != OMX_ErrorInputDataDecodeYet) {
709 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
712 if ((pVideoDec->exynos_process_codecConfigData) && !bCodecConfigured) {
713 EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
714 ret = Exynos_InputBufferGetQueue(pExynosComponent);
716 inputUseBuffer = &(exynosInputPort->way.port2WayDataBuffer.inputDataBuffer);
717 pVideoDec->exynos_process_codecConfigData(pOMXComponent, inputUseBuffer); /* TIZEN_FEATURE_E3250 */
718 // pVideoDec->exynos_process_codecConfigData(pOMXComponent, pSrcInputData);
720 bCodecConfigured = OMX_TRUE;
723 if ((pSrcInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) || (pSrcInputData->pPrivate == NULL)) {
724 Exynos_CodecBufferDeQueue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
725 if (codecBuffer != NULL) {
726 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
728 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
733 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
734 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
736 bCheckInputData = OMX_FALSE;
739 if ((bCheckInputData == OMX_FALSE) &&
740 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
741 ret = Exynos_InputBufferGetQueue(pExynosComponent);
742 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
746 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
747 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
752 ret = pVideoDec->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
754 if (ret == OMX_ErrorCorruptedFrame) {
755 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
757 codecBuffer = pSrcInputData->pPrivate;
758 if (codecBuffer != NULL)
759 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
762 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
763 Exynos_OMX_InputBufferReturn(pOMXComponent, pSrcInputData->bufferHeader);
767 if (ret != OMX_ErrorInputDataDecodeYet) {
768 Exynos_ResetCodecData(pSrcInputData);
770 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
771 if (ret == OMX_ErrorCodecInit)
772 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
783 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
785 OMX_ERRORTYPE ret = OMX_ErrorNone;
786 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
787 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
788 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
789 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
790 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
791 EXYNOS_OMX_DATA srcOutputData;
795 while (!pVideoDec->bExitBufferProcessThread) {
796 Exynos_OSAL_SleepMillisec(0);
798 while (!pVideoDec->bExitBufferProcessThread) {
799 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
800 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
803 Exynos_OSAL_SleepMillisec(0);
805 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
808 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
809 ret = pVideoDec->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
811 if (ret == OMX_ErrorNone) {
812 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
814 codecBuffer = srcOutputData.pPrivate;
815 if (codecBuffer != NULL)
816 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
818 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
819 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer);
820 Exynos_InputBufferReturn(pOMXComponent);
822 Exynos_ResetCodecData(&srcOutputData);
824 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
835 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
837 OMX_ERRORTYPE ret = OMX_ErrorNone;
838 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
839 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
840 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
841 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
842 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
843 EXYNOS_OMX_DATA dstInputData;
847 while (!pVideoDec->bExitBufferProcessThread) {
848 Exynos_OSAL_SleepMillisec(0);
850 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
851 (!pVideoDec->bExitBufferProcessThread)) {
852 Exynos_OSAL_SleepMillisec(0);
854 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
855 (!CHECK_PORT_POPULATED(exynosOutputPort)))
857 if (exynosOutputPort->portState != OMX_StateIdle)
860 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
861 if (ret != OMX_ErrorOutputBufferUseYet) {
862 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
864 ret = Exynos_CodecBufferDeQueue(pExynosComponent, OUTPUT_PORT_INDEX, &codecBuffer);
865 if (ret != OMX_ErrorNone) {
866 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
869 Exynos_Output_CodecBufferToData(pExynosComponent, codecBuffer, &dstInputData);
872 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
873 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
874 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
875 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
876 if (ret != OMX_ErrorNone) {
877 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
880 if (exynosOutputPort->bIsPBEnabled == OMX_FALSE) {
881 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, TWO_PLANE);
884 ret = Exynos_Shared_PlatformBufferToData(dstInputUseBuffer, &dstInputData, exynosOutputPort, TWO_PLANE);
886 if (ret != OMX_ErrorNone) {
887 dstInputUseBuffer->dataValid = OMX_FALSE;
888 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
892 Exynos_ResetDataBuffer(dstInputUseBuffer);
896 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
897 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
902 ret = pVideoDec->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
903 if (ret != OMX_ErrorOutputBufferUseYet) {
904 Exynos_ResetCodecData(&dstInputData);
906 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
917 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
919 OMX_ERRORTYPE ret = OMX_ErrorNone;
920 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
921 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
922 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
923 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
924 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
925 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
929 while (!pVideoDec->bExitBufferProcessThread) {
930 Exynos_OSAL_SleepMillisec(0);
931 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
933 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
934 (!pVideoDec->bExitBufferProcessThread)) {
935 Exynos_OSAL_SleepMillisec(0);
937 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
940 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
941 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
942 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
943 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
944 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
945 if (ret != OMX_ErrorNone) {
946 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
952 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
953 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
954 ret = pVideoDec->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
956 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
957 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
958 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
961 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
963 codecBuffer = pDstOutputData->pPrivate;
964 if (codecBuffer != NULL) {
965 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, codecBuffer);
966 pDstOutputData->pPrivate = NULL;
970 /* reset outputData */
971 Exynos_ResetCodecData(pDstOutputData);
972 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
983 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
985 OMX_ERRORTYPE ret = OMX_ErrorNone;
986 OMX_COMPONENTTYPE *pOMXComponent = NULL;
987 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
988 EXYNOS_OMX_MESSAGE *message = NULL;
992 if (threadData == NULL) {
993 ret = OMX_ErrorBadParameter;
996 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
997 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
998 if (ret != OMX_ErrorNone) {
1001 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1002 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1004 Exynos_OSAL_ThreadExit(NULL);
1012 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1014 OMX_ERRORTYPE ret = OMX_ErrorNone;
1015 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1016 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1017 EXYNOS_OMX_MESSAGE *message = NULL;
1021 if (threadData == NULL) {
1022 ret = OMX_ErrorBadParameter;
1025 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1026 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1027 if (ret != OMX_ErrorNone) {
1030 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1031 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1033 Exynos_OSAL_ThreadExit(NULL);
1041 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1043 OMX_ERRORTYPE ret = OMX_ErrorNone;
1044 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1045 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1046 EXYNOS_OMX_MESSAGE *message = NULL;
1050 if (threadData == NULL) {
1051 ret = OMX_ErrorBadParameter;
1054 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1055 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1056 if (ret != OMX_ErrorNone) {
1059 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1060 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1062 Exynos_OSAL_ThreadExit(NULL);
1070 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1072 OMX_ERRORTYPE ret = OMX_ErrorNone;
1073 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1074 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1075 EXYNOS_OMX_MESSAGE *message = NULL;
1079 if (threadData == NULL) {
1080 ret = OMX_ErrorBadParameter;
1083 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1084 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1085 if (ret != OMX_ErrorNone) {
1088 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1089 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1091 Exynos_OSAL_ThreadExit(NULL);
1099 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1101 OMX_ERRORTYPE ret = OMX_ErrorNone;
1102 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1103 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1104 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1108 pVideoDec->bExitBufferProcessThread = OMX_FALSE;
1110 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstOutputThread,
1111 Exynos_OMX_DstOutputProcessThread,
1113 if (ret == OMX_ErrorNone)
1114 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcOutputThread,
1115 Exynos_OMX_SrcOutputProcessThread,
1117 if (ret == OMX_ErrorNone)
1118 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hDstInputThread,
1119 Exynos_OMX_DstInputProcessThread,
1121 if (ret == OMX_ErrorNone)
1122 ret = Exynos_OSAL_ThreadCreate(&pVideoDec->hSrcInputThread,
1123 Exynos_OMX_SrcInputProcessThread,
1132 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1134 OMX_ERRORTYPE ret = OMX_ErrorNone;
1135 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1136 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1137 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1138 OMX_S32 countValue = 0;
1143 pVideoDec->bExitBufferProcessThread = OMX_TRUE;
1145 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1146 if (countValue == 0)
1147 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1148 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1149 if (countValue == 0)
1150 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1151 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1152 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcInputThread);
1153 pVideoDec->hSrcInputThread = NULL;
1155 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1156 if (countValue == 0)
1157 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1158 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1159 if (countValue == 0)
1160 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1161 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1162 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstInputThread);
1163 pVideoDec->hDstInputThread = NULL;
1165 pVideoDec->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1166 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1167 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1168 Exynos_OSAL_ThreadTerminate(pVideoDec->hSrcOutputThread);
1169 pVideoDec->hSrcOutputThread = NULL;
1171 pVideoDec->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1172 pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1173 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1174 Exynos_OSAL_ThreadTerminate(pVideoDec->hDstOutputThread);
1175 pVideoDec->hDstOutputThread = NULL;
1183 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1185 OMX_ERRORTYPE ret = OMX_ErrorNone;
1186 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1187 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1188 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1189 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1193 if (hComponent == NULL) {
1194 ret = OMX_ErrorBadParameter;
1197 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1198 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1199 if (ret != OMX_ErrorNone) {
1200 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1204 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1205 if (ret != OMX_ErrorNone) {
1206 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1210 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1211 if (ret != OMX_ErrorNone) {
1212 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1213 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1217 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1219 pVideoDec = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1220 if (pVideoDec == NULL) {
1221 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1222 ret = OMX_ErrorInsufficientResources;
1223 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1227 Exynos_OSAL_Memset(pVideoDec, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT));
1228 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoDec;
1230 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1231 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1234 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1235 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1236 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1237 pExynosPort->portDefinition.nBufferSize = 0;
1238 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1240 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1241 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1242 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1243 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1244 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1246 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1247 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1248 pExynosPort->portDefinition.format.video.nStride = 0;
1249 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1250 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1251 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1252 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1253 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1256 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1257 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1258 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1259 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1260 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1262 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1263 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1264 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1265 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1266 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1268 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1269 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1270 pExynosPort->portDefinition.format.video.nStride = 0;
1271 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1272 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1273 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1274 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1275 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1277 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO));
1279 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1280 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1281 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1282 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1284 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1285 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1286 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1287 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1288 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1296 OMX_ERRORTYPE Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1298 OMX_ERRORTYPE ret = OMX_ErrorNone;
1299 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1300 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1301 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1302 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
1307 if (hComponent == NULL) {
1308 ret = OMX_ErrorBadParameter;
1311 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1312 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1313 if (ret != OMX_ErrorNone) {
1317 if (pOMXComponent->pComponentPrivate == NULL) {
1318 ret = OMX_ErrorBadParameter;
1321 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1323 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1325 Exynos_OSAL_Free(pVideoDec);
1326 pExynosComponent->hComponentHandle = pVideoDec = NULL;
1328 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1329 if (pExynosPort->processData.extInfo != NULL) {
1330 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1331 pExynosPort->processData.extInfo = NULL;
1334 for(i = 0; i < ALL_PORT_NUM; i++) {
1335 pExynosPort = &pExynosComponent->pExynosPort[i];
1336 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1337 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1340 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1342 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);