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)
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_SharedMemory.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_Android.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 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE
*pOMXComponent
)
58 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
59 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
60 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
62 if ((exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
!=
63 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
) ||
64 (exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
!=
65 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
)) {
66 OMX_U32 width
= 0, height
= 0;
68 exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
=
69 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
;
70 exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
=
71 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
;
72 width
= exynosOutputPort
->portDefinition
.format
.video
.nStride
=
73 exynosInputPort
->portDefinition
.format
.video
.nStride
;
74 height
= exynosOutputPort
->portDefinition
.format
.video
.nSliceHeight
=
75 exynosInputPort
->portDefinition
.format
.video
.nSliceHeight
;
77 switch(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
) {
78 case OMX_COLOR_FormatYUV420Planar
:
79 case OMX_COLOR_FormatYUV420SemiPlanar
:
80 case OMX_SEC_COLOR_FormatNV12Tiled
:
82 exynosOutputPort
->portDefinition
.nBufferSize
= (width
* height
* 3) / 2;
86 exynosOutputPort
->portDefinition
.nBufferSize
= width
* height
* 2;
94 void Exynos_Free_CodecBuffers(
95 OMX_COMPONENTTYPE
*pOMXComponent
,
98 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
99 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
100 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
101 CODEC_DEC_BUFFER
**ppCodecBuffer
= NULL
;
103 OMX_U32 nPlaneCnt
= 0;
108 if (nPortIndex
== INPUT_PORT_INDEX
) {
109 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
110 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
112 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
113 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
116 for (i
= 0; i
< MFC_OUTPUT_BUFFER_NUM_MAX
; i
++) {
117 if (ppCodecBuffer
[i
] != NULL
) {
118 for (j
= 0; j
< nPlaneCnt
; j
++) {
119 if (ppCodecBuffer
[i
]->pVirAddr
[j
] != NULL
)
120 Exynos_OSAL_SharedMemory_Free(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
123 Exynos_OSAL_Free(ppCodecBuffer
[i
]);
124 ppCodecBuffer
[i
] = NULL
;
131 OMX_ERRORTYPE
Exynos_Allocate_CodecBuffers(
132 OMX_COMPONENTTYPE
*pOMXComponent
,
135 OMX_U32 nPlaneSize
[MFC_OUTPUT_BUFFER_PLANE
])
137 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
138 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
139 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
140 MEMORY_TYPE eMemoryType
= SYSTEM_MEMORY
;
141 CODEC_DEC_BUFFER
**ppCodecBuffer
= NULL
;
143 OMX_U32 nPlaneCnt
= 0;
148 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
)
149 eMemoryType
= SECURE_MEMORY
;
151 if (nPortIndex
== INPUT_PORT_INDEX
) {
152 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
153 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
155 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
156 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
158 eMemoryType
= NORMAL_MEMORY
;
162 for (i
= 0; i
< nBufferCnt
; i
++) {
163 ppCodecBuffer
[i
] = (CODEC_DEC_BUFFER
*)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER
));
164 if (ppCodecBuffer
[i
] == NULL
) {
165 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc codec buffer");
166 ret
= OMX_ErrorInsufficientResources
;
169 Exynos_OSAL_Memset(ppCodecBuffer
[i
], 0, sizeof(CODEC_DEC_BUFFER
));
171 for (j
= 0; j
< nPlaneCnt
; j
++) {
172 ppCodecBuffer
[i
]->pVirAddr
[j
] =
173 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec
->hSharedMemory
, nPlaneSize
[j
], eMemoryType
);
174 if (ppCodecBuffer
[i
]->pVirAddr
[j
] == NULL
) {
175 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc plane");
176 ret
= OMX_ErrorInsufficientResources
;
180 ppCodecBuffer
[i
]->fd
[j
] =
181 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
182 ppCodecBuffer
[i
]->bufferSize
[j
] = nPlaneSize
[j
];
183 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex
, i
, j
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
186 ppCodecBuffer
[i
]->dataSize
= 0;
189 return OMX_ErrorNone
;
192 Exynos_Free_CodecBuffers(pOMXComponent
, nPortIndex
);
199 OMX_BOOL
Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
201 OMX_BOOL ret
= OMX_FALSE
;
203 if ((pExynosComponent
->currentState
== OMX_StateExecuting
) &&
204 (pExynosComponent
->pExynosPort
[nPortIndex
].portState
== OMX_StateIdle
) &&
205 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateExecutingToIdle
) &&
206 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToExecuting
)) {
215 OMX_ERRORTYPE
Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_PTR codecBuffer
, EXYNOS_OMX_DATA
*pData
)
217 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
218 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
219 CODEC_DEC_BUFFER
*pInputCodecBuffer
= (CODEC_DEC_BUFFER
*)codecBuffer
;
221 pData
->buffer
.singlePlaneBuffer
.dataBuffer
= pInputCodecBuffer
->pVirAddr
[0];
222 pData
->buffer
.singlePlaneBuffer
.fd
= pInputCodecBuffer
->fd
[0];
223 pData
->allocSize
= pInputCodecBuffer
->bufferSize
[0];
224 pData
->dataLen
= pInputCodecBuffer
->dataSize
;
225 pData
->usedDataLen
= 0;
226 pData
->remainDataLen
= pInputCodecBuffer
->dataSize
;
229 pData
->timeStamp
= 0;
230 pData
->pPrivate
= codecBuffer
;
231 pData
->bufferHeader
= NULL
;
236 OMX_ERRORTYPE
Exynos_Output_CodecBufferToData(
237 CODEC_DEC_BUFFER
*pCodecBuffer
,
238 EXYNOS_OMX_DATA
*pData
)
240 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
242 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] = pCodecBuffer
->pVirAddr
[0];
243 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[1] = pCodecBuffer
->pVirAddr
[1];
244 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[2] = pCodecBuffer
->pVirAddr
[2];
245 pData
->buffer
.multiPlaneBuffer
.fd
[0] = pCodecBuffer
->fd
[0];
246 pData
->buffer
.multiPlaneBuffer
.fd
[1] = pCodecBuffer
->fd
[1];
247 pData
->buffer
.multiPlaneBuffer
.fd
[2] = pCodecBuffer
->fd
[2];
248 pData
->allocSize
= pCodecBuffer
->bufferSize
[0] + pCodecBuffer
->bufferSize
[1] + pCodecBuffer
->bufferSize
[2];
250 pData
->usedDataLen
= 0;
251 pData
->remainDataLen
= 0;
254 pData
->timeStamp
= 0;
255 pData
->pPrivate
= pCodecBuffer
;
256 pData
->bufferHeader
= NULL
;
261 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
263 EXYNOS_OMX_BASEPORT
*exynosOMXInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
264 EXYNOS_OMX_BASEPORT
*exynosOMXOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
265 EXYNOS_OMX_BASEPORT
*exynosOMXPort
= NULL
;
269 exynosOMXPort
= &pExynosComponent
->pExynosPort
[nPortIndex
];
271 if (((pExynosComponent
->currentState
== OMX_StatePause
) ||
272 (pExynosComponent
->currentState
== OMX_StateIdle
) ||
273 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateLoadedToIdle
) ||
274 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateExecutingToIdle
)) &&
275 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToLoaded
) &&
276 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort
))) {
277 Exynos_OSAL_SignalWait(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
, DEF_MAX_WAIT_TIME
);
278 Exynos_OSAL_SignalReset(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
);
286 OMX_BOOL
Exynos_CSC_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
288 OMX_BOOL ret
= OMX_FALSE
;
289 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
290 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
291 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
292 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
293 OMX_U32 copySize
= 0;
294 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
298 OMX_U32 width
= 0, height
= 0;
300 OMX_COLOR_FORMATTYPE colorFormat
;
302 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
303 void *pSrcBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
304 void *pYUVBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
306 CSC_ERRORCODE cscRet
= CSC_ErrorNone
;
307 CSC_METHOD csc_method
= CSC_METHOD_SW
;
308 CSC_MEMTYPE csc_memType
= CSC_MEMORY_USERPTR
;
310 unsigned int srcCacheable
= 1, dstCacheable
= 1;
312 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
314 width
= pBufferInfo
->imageWidth
;
315 height
= pBufferInfo
->imageHeight
;
316 imageSize
= width
* height
;
317 colorFormat
= pBufferInfo
->ColorFormat
;
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
);
328 if (csc_method
== CSC_METHOD_HW
)
332 if (csc_method
== CSC_METHOD_HW
) {
333 csc_memType
= CSC_MEMORY_DMABUF
;
334 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[0];
335 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[1];
336 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[2];
341 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
342 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
344 Exynos_OSAL_LockANB(pOutputBuf
, width
, height
, exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
, &stride
, planes
);
346 outputUseBuffer
->dataLen
= sizeof(void *);
348 pYUVBuf
[0] = (unsigned char *)planes
[0].addr
;
349 pYUVBuf
[1] = (unsigned char *)planes
[1].addr
;
350 pYUVBuf
[2] = (unsigned char *)planes
[2].addr
;
352 if (csc_method
== CSC_METHOD_HW
) {
353 pYUVBuf
[0] = (unsigned char *)planes
[0].fd
;
354 pYUVBuf
[1] = (unsigned char *)planes
[1].fd
;
355 pYUVBuf
[2] = (unsigned char *)planes
[2].fd
;
361 if ((exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) &&
362 (csc_method
== CSC_METHOD_HW
)) {
363 pYUVBuf
[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, pOutputBuf
);
369 if (pVideoDec
->csc_set_format
== OMX_FALSE
) {
371 pVideoDec
->csc_handle
, /* handle */
376 width
, /* crop_width */
377 height
, /* crop_height */
378 omx_2_hal_pixel_format(colorFormat
), /* color_format */
379 srcCacheable
); /* cacheable */
381 pVideoDec
->csc_handle
, /* handle */
386 width
, /* crop_width */
387 height
, /* crop_height */
388 omx_2_hal_pixel_format(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
), /* color_format */
389 dstCacheable
); /* cacheable */
390 pVideoDec
->csc_set_format
= OMX_TRUE
;
393 pVideoDec
->csc_handle
, /* handle */
395 csc_memType
); /* YUV Addr or FD */
397 pVideoDec
->csc_handle
, /* handle */
399 csc_memType
); /* YUV Addr or FD */
400 cscRet
= csc_convert(pVideoDec
->csc_handle
);
401 if (cscRet
!= CSC_ErrorNone
)
407 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
408 Exynos_OSAL_UnlockANB(pOutputBuf
);
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
);
443 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
) {
444 OMX_PTR dataBuffer
= NULL
;
446 dataBuffer
= Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec
->hSharedMemory
,
447 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
);
448 if (dataBuffer
== NULL
) {
453 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
= dataBuffer
;
456 /* reset dataBuffer */
457 Exynos_ResetDataBuffer(inputUseBuffer
);
458 } else if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
459 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
+ inputUseBuffer
->usedDataLen
;
460 checkInputStreamLen
= inputUseBuffer
->remainDataLen
;
462 pExynosComponent
->bUseFlagEOF
= OMX_TRUE
;
464 copySize
= checkInputStreamLen
;
465 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "exynos_checkInputFrame : OMX_TRUE");
467 if (((srcInputData
->allocSize
) - (srcInputData
->dataLen
)) >= copySize
) {
469 Exynos_OSAL_Memcpy(srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
+ srcInputData
->dataLen
,
470 checkInputStream
, copySize
);
473 inputUseBuffer
->dataLen
-= copySize
;
474 inputUseBuffer
->remainDataLen
-= copySize
;
475 inputUseBuffer
->usedDataLen
+= copySize
;
477 srcInputData
->dataLen
+= copySize
;
478 srcInputData
->remainDataLen
+= copySize
;
480 srcInputData
->timeStamp
= inputUseBuffer
->timeStamp
;
481 srcInputData
->nFlags
= inputUseBuffer
->nFlags
;
482 srcInputData
->bufferHeader
= inputUseBuffer
->bufferHeader
;
484 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "input codec buffer is smaller than decoded input data size Out Length");
485 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
486 pExynosComponent
->callbackData
,
487 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
491 Exynos_InputBufferReturn(pOMXComponent
, inputUseBuffer
);
494 if ((srcInputData
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
495 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "bSaveFlagEOS : OMX_TRUE");
496 srcInputData
->dataLen
= 0;
497 srcInputData
->remainDataLen
= 0;
498 pExynosComponent
->bSaveFlagEOS
= OMX_TRUE
;
501 if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
502 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_TRUE
;
503 pExynosComponent
->checkTimeStamp
.startTimeStamp
= srcInputData
->timeStamp
;
504 pExynosComponent
->checkTimeStamp
.nStartFlags
= srcInputData
->nFlags
;
505 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
506 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "first frame timestamp after seeking %lld us (%.2f secs)",
507 srcInputData
->timeStamp
, srcInputData
->timeStamp
/ 1E6
);
520 OMX_BOOL
Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
522 OMX_BOOL ret
= OMX_FALSE
;
523 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
524 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
525 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
526 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
527 OMX_U32 copySize
= 0;
528 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
532 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
533 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
534 if (Exynos_Shared_DataToBuffer(dstOutputData
, outputUseBuffer
) == OMX_ErrorNone
)
535 outputUseBuffer
->dataValid
= OMX_TRUE
;
537 if (Exynos_Shared_DataToANBBuffer(dstOutputData
, outputUseBuffer
, exynosOutputPort
) == OMX_ErrorNone
) {
538 outputUseBuffer
->dataValid
= OMX_TRUE
;
546 if (outputUseBuffer
->dataValid
== OMX_TRUE
) {
547 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "out timestamp after seeking %lld us (%.2f secs)",
548 dstOutputData
->timeStamp
, dstOutputData
->timeStamp
/ 1E6
);
549 if ((pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
== OMX_TRUE
) &&
550 ((dstOutputData
->nFlags
& OMX_BUFFERFLAG_EOS
) != OMX_BUFFERFLAG_EOS
)) {
551 if ((pExynosComponent
->checkTimeStamp
.startTimeStamp
== dstOutputData
->timeStamp
) &&
552 (pExynosComponent
->checkTimeStamp
.nStartFlags
== dstOutputData
->nFlags
)){
553 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
554 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
555 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
556 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
558 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "drop frame after seeking", pExynosComponent
);
559 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)
560 Exynos_OMX_FillThisBuffer(pOMXComponent
, outputUseBuffer
->bufferHeader
);
562 if (pExynosComponent
->checkTimeStamp
.startTimeStamp
< dstOutputData
->timeStamp
) {
563 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
564 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
565 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
566 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
572 } else if ((pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
)) {
574 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "not set check timestame after seeking");
578 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
579 OMX_U32 width
= 0, height
= 0;
581 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
583 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
585 width
= pBufferInfo
->imageWidth
;
586 height
= pBufferInfo
->imageHeight
;
587 imageSize
= width
* height
;
589 if ((dstOutputData
->remainDataLen
<= (outputUseBuffer
->allocSize
- outputUseBuffer
->dataLen
)) &&
590 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
591 copySize
= dstOutputData
->remainDataLen
;
592 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
,"copySize: %d", copySize
);
594 outputUseBuffer
->dataLen
+= copySize
;
595 outputUseBuffer
->remainDataLen
+= copySize
;
596 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
597 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
599 if (outputUseBuffer
->remainDataLen
> 0) {
600 ret
= Exynos_CSC_OutputData(pOMXComponent
, dstOutputData
);
605 if (ret
== OMX_TRUE
) {
606 if ((outputUseBuffer
->remainDataLen
> 0) ||
607 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
608 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
609 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
612 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "csc_convert Error");
613 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
614 pExynosComponent
->callbackData
,
615 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
618 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
619 outputUseBuffer
->dataLen
= 0;
620 outputUseBuffer
->remainDataLen
= 0;
621 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
622 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
623 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
625 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "output buffer is smaller than decoded data size Out Length");
626 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
627 pExynosComponent
->callbackData
,
628 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
631 } else if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
632 if ((outputUseBuffer
->remainDataLen
> 0) ||
633 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
634 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)))
635 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
647 OMX_ERRORTYPE
Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent
)
649 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
650 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
651 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
652 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
653 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
654 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
655 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
656 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
657 OMX_BOOL bCheckInputData
= OMX_FALSE
;
658 OMX_BOOL bValidCodecData
= OMX_FALSE
;
662 while (!pVideoDec
->bExitBufferProcessThread
) {
663 Exynos_OSAL_SleepMillisec(0);
664 Exynos_Wait_ProcessPause(pExynosComponent
, INPUT_PORT_INDEX
);
666 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
)) &&
667 (!pVideoDec
->bExitBufferProcessThread
)) {
668 Exynos_OSAL_SleepMillisec(0);
670 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) ||
671 ((exynosOutputPort
->exceptionFlag
== NEED_PORT_DISABLE
) && (ret
== OMX_ErrorInputDataDecodeYet
)))
673 if (exynosInputPort
->portState
!= OMX_StateIdle
)
676 Exynos_OSAL_MutexLock(srcInputUseBuffer
->bufferMutex
);
677 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
678 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
680 if ((pSrcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) || (pSrcInputData
->pPrivate
== NULL
)) {
681 Exynos_CodecBufferDeQueue(pExynosComponent
, INPUT_PORT_INDEX
, &codecBuffer
);
682 if (codecBuffer
!= NULL
) {
683 Exynos_Input_CodecBufferToData(pExynosComponent
, codecBuffer
, pSrcInputData
);
685 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
690 if (srcInputUseBuffer
->dataValid
== OMX_TRUE
) {
691 bCheckInputData
= Exynos_Preprocessor_InputData(pOMXComponent
, pSrcInputData
);
693 bCheckInputData
= OMX_FALSE
;
696 if ((bCheckInputData
== OMX_FALSE
) &&
697 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
698 ret
= Exynos_InputBufferGetQueue(pExynosComponent
);
699 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
703 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) {
704 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
709 ret
= pVideoDec
->exynos_codec_srcInputProcess(pOMXComponent
, pSrcInputData
);
710 if (ret
== OMX_ErrorCorruptedFrame
) {
711 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
713 codecBuffer
= pSrcInputData
->pPrivate
;
714 if (codecBuffer
!= NULL
)
715 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
718 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
719 Exynos_OMX_InputBufferReturn(pOMXComponent
, pSrcInputData
->bufferHeader
);
723 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
724 Exynos_ResetCodecData(pSrcInputData
);
726 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
727 if (ret
== OMX_ErrorCodecInit
)
728 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
739 OMX_ERRORTYPE
Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent
)
741 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
742 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
743 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
744 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
745 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
746 EXYNOS_OMX_DATABUFFER
*srcOutputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
747 EXYNOS_OMX_DATA srcOutputData
;
751 while (!pVideoDec
->bExitBufferProcessThread
) {
752 Exynos_OSAL_SleepMillisec(0);
754 while (!pVideoDec
->bExitBufferProcessThread
) {
755 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
756 if (Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
) == OMX_FALSE
)
759 Exynos_OSAL_SleepMillisec(0);
761 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
764 Exynos_OSAL_MutexLock(srcOutputUseBuffer
->bufferMutex
);
765 ret
= pVideoDec
->exynos_codec_srcOutputProcess(pOMXComponent
, &srcOutputData
);
767 if (ret
== OMX_ErrorNone
) {
768 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
770 codecBuffer
= srcOutputData
.pPrivate
;
771 if (codecBuffer
!= NULL
)
772 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
774 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
775 Exynos_Shared_DataToBuffer(&srcOutputData
, srcOutputUseBuffer
);
776 Exynos_InputBufferReturn(pOMXComponent
, srcOutputUseBuffer
);
778 Exynos_ResetCodecData(&srcOutputData
);
780 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer
->bufferMutex
);
791 OMX_ERRORTYPE
Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent
)
793 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
794 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
795 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
796 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
797 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
798 EXYNOS_OMX_DATABUFFER
*dstInputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
799 EXYNOS_OMX_DATA dstInputData
;
803 while (!pVideoDec
->bExitBufferProcessThread
) {
804 Exynos_OSAL_SleepMillisec(0);
806 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
807 (!pVideoDec
->bExitBufferProcessThread
)) {
808 Exynos_OSAL_SleepMillisec(0);
810 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) ||
811 (!CHECK_PORT_POPULATED(exynosOutputPort
)))
813 if (exynosOutputPort
->portState
!= OMX_StateIdle
)
816 Exynos_OSAL_MutexLock(dstInputUseBuffer
->bufferMutex
);
817 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
818 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
819 CODEC_DEC_BUFFER
*pCodecBuffer
= NULL
;
820 ret
= Exynos_CodecBufferDeQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, (OMX_PTR
*)&pCodecBuffer
);
821 if (ret
!= OMX_ErrorNone
) {
822 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
825 Exynos_Output_CodecBufferToData(pCodecBuffer
, &dstInputData
);
828 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
829 if ((dstInputUseBuffer
->dataValid
!= OMX_TRUE
) &&
830 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
831 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
832 if (ret
!= OMX_ErrorNone
) {
833 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
836 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
837 Exynos_Shared_BufferToData(dstInputUseBuffer
, &dstInputData
, TWO_PLANE
);
839 ret
= Exynos_Shared_ANBBufferToData(dstInputUseBuffer
, &dstInputData
, exynosOutputPort
, TWO_PLANE
);
840 if (ret
!= OMX_ErrorNone
) {
841 dstInputUseBuffer
->dataValid
= OMX_FALSE
;
842 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
846 Exynos_ResetDataBuffer(dstInputUseBuffer
);
850 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
851 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
856 ret
= pVideoDec
->exynos_codec_dstInputProcess(pOMXComponent
, &dstInputData
);
857 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
858 Exynos_ResetCodecData(&dstInputData
);
860 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
871 OMX_ERRORTYPE
Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent
)
873 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
874 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
875 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
876 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
877 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
878 EXYNOS_OMX_DATABUFFER
*dstOutputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
879 EXYNOS_OMX_DATA
*pDstOutputData
= &exynosOutputPort
->processData
;
883 while (!pVideoDec
->bExitBufferProcessThread
) {
884 Exynos_OSAL_SleepMillisec(0);
885 Exynos_Wait_ProcessPause(pExynosComponent
, OUTPUT_PORT_INDEX
);
887 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
888 (!pVideoDec
->bExitBufferProcessThread
)) {
889 Exynos_OSAL_SleepMillisec(0);
891 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))
894 Exynos_OSAL_MutexLock(dstOutputUseBuffer
->bufferMutex
);
895 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
896 if ((dstOutputUseBuffer
->dataValid
!= OMX_TRUE
) &&
897 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
898 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
899 if (ret
!= OMX_ErrorNone
) {
900 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
906 if ((dstOutputUseBuffer
->dataValid
== OMX_TRUE
) ||
907 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
))
908 ret
= pVideoDec
->exynos_codec_dstOutputProcess(pOMXComponent
, pDstOutputData
);
910 if (((ret
== OMX_ErrorNone
) && (dstOutputUseBuffer
->dataValid
== OMX_TRUE
)) ||
911 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)) {
912 Exynos_Postprocess_OutputData(pOMXComponent
, pDstOutputData
);
915 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
916 if (pDstOutputData
->pPrivate
!= NULL
) {
917 Exynos_CodecBufferEnQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, pDstOutputData
->pPrivate
);
918 pDstOutputData
->pPrivate
= NULL
;
922 /* reset outputData */
923 Exynos_ResetCodecData(pDstOutputData
);
924 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
935 static OMX_ERRORTYPE
Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData
)
937 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
938 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
939 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
940 EXYNOS_OMX_MESSAGE
*message
= NULL
;
944 if (threadData
== NULL
) {
945 ret
= OMX_ErrorBadParameter
;
948 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
949 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
950 if (ret
!= OMX_ErrorNone
) {
953 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
954 Exynos_OMX_SrcInputBufferProcess(pOMXComponent
);
956 Exynos_OSAL_ThreadExit(NULL
);
964 static OMX_ERRORTYPE
Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData
)
966 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
967 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
968 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
969 EXYNOS_OMX_MESSAGE
*message
= NULL
;
973 if (threadData
== NULL
) {
974 ret
= OMX_ErrorBadParameter
;
977 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
978 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
979 if (ret
!= OMX_ErrorNone
) {
982 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
983 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent
);
985 Exynos_OSAL_ThreadExit(NULL
);
993 static OMX_ERRORTYPE
Exynos_OMX_DstInputProcessThread(OMX_PTR threadData
)
995 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
996 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
997 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
998 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1002 if (threadData
== NULL
) {
1003 ret
= OMX_ErrorBadParameter
;
1006 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1007 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1008 if (ret
!= OMX_ErrorNone
) {
1011 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1012 Exynos_OMX_DstInputBufferProcess(pOMXComponent
);
1014 Exynos_OSAL_ThreadExit(NULL
);
1022 static OMX_ERRORTYPE
Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData
)
1024 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1025 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1026 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1027 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1031 if (threadData
== NULL
) {
1032 ret
= OMX_ErrorBadParameter
;
1035 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1036 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1037 if (ret
!= OMX_ErrorNone
) {
1040 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1041 Exynos_OMX_DstOutputBufferProcess(pOMXComponent
);
1043 Exynos_OSAL_ThreadExit(NULL
);
1051 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent
)
1053 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1054 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1055 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1056 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1060 pVideoDec
->bExitBufferProcessThread
= OMX_FALSE
;
1062 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstOutputThread
,
1063 Exynos_OMX_DstOutputProcessThread
,
1065 if (ret
== OMX_ErrorNone
)
1066 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcOutputThread
,
1067 Exynos_OMX_SrcOutputProcessThread
,
1069 if (ret
== OMX_ErrorNone
)
1070 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstInputThread
,
1071 Exynos_OMX_DstInputProcessThread
,
1073 if (ret
== OMX_ErrorNone
)
1074 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcInputThread
,
1075 Exynos_OMX_SrcInputProcessThread
,
1084 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent
)
1086 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1087 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1088 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1089 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1090 OMX_S32 countValue
= 0;
1095 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
1097 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1098 if (countValue
== 0)
1099 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
);
1100 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
, &countValue
);
1101 if (countValue
== 0)
1102 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
);
1103 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1104 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcInputThread
);
1105 pVideoDec
->hSrcInputThread
= NULL
;
1107 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1108 if (countValue
== 0)
1109 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
);
1110 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
, &countValue
);
1111 if (countValue
== 0)
1112 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
);
1113 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1114 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstInputThread
);
1115 pVideoDec
->hDstInputThread
= NULL
;
1117 pVideoDec
->exynos_codec_stop(pOMXComponent
, INPUT_PORT_INDEX
);
1118 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1119 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1120 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcOutputThread
);
1121 pVideoDec
->hSrcOutputThread
= NULL
;
1123 pVideoDec
->exynos_codec_stop(pOMXComponent
, OUTPUT_PORT_INDEX
);
1124 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1125 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1126 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstOutputThread
);
1127 pVideoDec
->hDstOutputThread
= NULL
;
1135 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent
)
1137 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1138 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1139 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1140 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1141 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1145 if (hComponent
== NULL
) {
1146 ret
= OMX_ErrorBadParameter
;
1149 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1150 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1151 if (ret
!= OMX_ErrorNone
) {
1152 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1156 ret
= Exynos_OMX_BaseComponent_Constructor(pOMXComponent
);
1157 if (ret
!= OMX_ErrorNone
) {
1158 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1162 ret
= Exynos_OMX_Port_Constructor(pOMXComponent
);
1163 if (ret
!= OMX_ErrorNone
) {
1164 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1165 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1169 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1171 pVideoDec
= Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1172 if (pVideoDec
== NULL
) {
1173 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1174 ret
= OMX_ErrorInsufficientResources
;
1175 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1179 Exynos_OSAL_Memset(pVideoDec
, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1180 pVideoDec
->bReconfigDPB
= OMX_FALSE
;
1181 pVideoDec
->nSavedDPBCnt
= 0;
1182 pExynosComponent
->hComponentHandle
= (OMX_HANDLETYPE
)pVideoDec
;
1184 pExynosComponent
->bSaveFlagEOS
= OMX_FALSE
;
1185 pExynosComponent
->bMultiThreadProcess
= OMX_TRUE
;
1188 pExynosPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
1189 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_INPUTBUFFER_NUM
;
1190 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_INPUTBUFFER_NUM
;
1191 pExynosPort
->portDefinition
.nBufferSize
= 0;
1192 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1194 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1195 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1196 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1197 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1198 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1200 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1201 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1202 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1203 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1204 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1205 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1206 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1207 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1210 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1211 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1212 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1213 pExynosPort
->portDefinition
.nBufferSize
= DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE
;
1214 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1216 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1217 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1218 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1219 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1220 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1222 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1223 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1224 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1225 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1226 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1227 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1228 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1229 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1231 pExynosPort
->processData
.extInfo
= (OMX_PTR
)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO
));
1233 pOMXComponent
->UseBuffer
= &Exynos_OMX_UseBuffer
;
1234 pOMXComponent
->AllocateBuffer
= &Exynos_OMX_AllocateBuffer
;
1235 pOMXComponent
->FreeBuffer
= &Exynos_OMX_FreeBuffer
;
1236 pOMXComponent
->ComponentTunnelRequest
= &Exynos_OMX_ComponentTunnelRequest
;
1238 pExynosComponent
->exynos_AllocateTunnelBuffer
= &Exynos_OMX_AllocateTunnelBuffer
;
1239 pExynosComponent
->exynos_FreeTunnelBuffer
= &Exynos_OMX_FreeTunnelBuffer
;
1240 pExynosComponent
->exynos_BufferProcessCreate
= &Exynos_OMX_BufferProcess_Create
;
1241 pExynosComponent
->exynos_BufferProcessTerminate
= &Exynos_OMX_BufferProcess_Terminate
;
1242 pExynosComponent
->exynos_BufferFlush
= &Exynos_OMX_BufferFlush
;
1250 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent
)
1252 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1253 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1254 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1255 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1256 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1261 if (hComponent
== NULL
) {
1262 ret
= OMX_ErrorBadParameter
;
1265 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1266 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1267 if (ret
!= OMX_ErrorNone
) {
1271 if (pOMXComponent
->pComponentPrivate
== NULL
) {
1272 ret
= OMX_ErrorBadParameter
;
1275 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1277 pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1279 Exynos_OSAL_Free(pVideoDec
);
1280 pExynosComponent
->hComponentHandle
= pVideoDec
= NULL
;
1282 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1283 if (pExynosPort
->processData
.extInfo
!= NULL
) {
1284 Exynos_OSAL_Free(pExynosPort
->processData
.extInfo
);
1285 pExynosPort
->processData
.extInfo
= NULL
;
1288 for(i
= 0; i
< ALL_PORT_NUM
; i
++) {
1289 pExynosPort
= &pExynosComponent
->pExynosPort
[i
];
1290 Exynos_OSAL_Free(pExynosPort
->portDefinition
.format
.video
.cMIMEType
);
1291 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= NULL
;
1294 ret
= Exynos_OMX_Port_Destructor(pOMXComponent
);
1296 ret
= Exynos_OMX_BaseComponent_Destructor(hComponent
);