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 nBufferCnt
= 0, nPlaneCnt
= 0;
108 if (nPortIndex
== INPUT_PORT_INDEX
) {
109 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
110 nBufferCnt
= MFC_INPUT_BUFFER_NUM_MAX
;
111 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
113 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
114 nBufferCnt
= MFC_OUTPUT_BUFFER_NUM_MAX
;
115 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
118 for (i
= 0; i
< nBufferCnt
; i
++) {
119 if (ppCodecBuffer
[i
] != NULL
) {
120 for (j
= 0; j
< nPlaneCnt
; j
++) {
121 if (ppCodecBuffer
[i
]->pVirAddr
[j
] != NULL
)
122 Exynos_OSAL_SharedMemory_Free(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
125 Exynos_OSAL_Free(ppCodecBuffer
[i
]);
126 ppCodecBuffer
[i
] = NULL
;
133 OMX_ERRORTYPE
Exynos_Allocate_CodecBuffers(
134 OMX_COMPONENTTYPE
*pOMXComponent
,
137 OMX_U32 nPlaneSize
[MFC_OUTPUT_BUFFER_PLANE
])
139 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
140 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
141 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
142 MEMORY_TYPE eMemoryType
= SYSTEM_MEMORY
;
143 CODEC_DEC_BUFFER
**ppCodecBuffer
= NULL
;
145 OMX_U32 nPlaneCnt
= 0;
150 if (nPortIndex
== INPUT_PORT_INDEX
) {
151 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
152 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
154 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
155 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
157 eMemoryType
= NORMAL_MEMORY
;
161 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
)
162 eMemoryType
= SECURE_MEMORY
;
164 for (i
= 0; i
< nBufferCnt
; i
++) {
165 ppCodecBuffer
[i
] = (CODEC_DEC_BUFFER
*)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER
));
166 if (ppCodecBuffer
[i
] == NULL
) {
167 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc codec buffer");
168 ret
= OMX_ErrorInsufficientResources
;
171 Exynos_OSAL_Memset(ppCodecBuffer
[i
], 0, sizeof(CODEC_DEC_BUFFER
));
173 for (j
= 0; j
< nPlaneCnt
; j
++) {
174 ppCodecBuffer
[i
]->pVirAddr
[j
] =
175 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec
->hSharedMemory
, nPlaneSize
[j
], eMemoryType
);
176 if (ppCodecBuffer
[i
]->pVirAddr
[j
] == NULL
) {
177 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc plane");
178 ret
= OMX_ErrorInsufficientResources
;
182 ppCodecBuffer
[i
]->fd
[j
] =
183 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
184 ppCodecBuffer
[i
]->bufferSize
[j
] = nPlaneSize
[j
];
185 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex
, i
, j
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
188 ppCodecBuffer
[i
]->dataSize
= 0;
191 return OMX_ErrorNone
;
194 Exynos_Free_CodecBuffers(pOMXComponent
, nPortIndex
);
201 OMX_BOOL
Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
203 OMX_BOOL ret
= OMX_FALSE
;
205 if ((pExynosComponent
->currentState
== OMX_StateExecuting
) &&
206 (pExynosComponent
->pExynosPort
[nPortIndex
].portState
== OMX_StateIdle
) &&
207 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateExecutingToIdle
) &&
208 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToExecuting
)) {
217 OMX_ERRORTYPE
Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_PTR codecBuffer
, EXYNOS_OMX_DATA
*pData
)
219 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
220 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
221 CODEC_DEC_BUFFER
*pInputCodecBuffer
= (CODEC_DEC_BUFFER
*)codecBuffer
;
223 pData
->buffer
.singlePlaneBuffer
.dataBuffer
= pInputCodecBuffer
->pVirAddr
[0];
224 pData
->buffer
.singlePlaneBuffer
.fd
= pInputCodecBuffer
->fd
[0];
225 pData
->allocSize
= pInputCodecBuffer
->bufferSize
[0];
226 pData
->dataLen
= pInputCodecBuffer
->dataSize
;
227 pData
->usedDataLen
= 0;
228 pData
->remainDataLen
= pInputCodecBuffer
->dataSize
;
231 pData
->timeStamp
= 0;
232 pData
->pPrivate
= codecBuffer
;
233 pData
->bufferHeader
= NULL
;
238 OMX_ERRORTYPE
Exynos_Output_CodecBufferToData(
239 CODEC_DEC_BUFFER
*pCodecBuffer
,
240 EXYNOS_OMX_DATA
*pData
)
242 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
244 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] = pCodecBuffer
->pVirAddr
[0];
245 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[1] = pCodecBuffer
->pVirAddr
[1];
246 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[2] = pCodecBuffer
->pVirAddr
[2];
247 pData
->buffer
.multiPlaneBuffer
.fd
[0] = pCodecBuffer
->fd
[0];
248 pData
->buffer
.multiPlaneBuffer
.fd
[1] = pCodecBuffer
->fd
[1];
249 pData
->buffer
.multiPlaneBuffer
.fd
[2] = pCodecBuffer
->fd
[2];
250 pData
->allocSize
= pCodecBuffer
->bufferSize
[0] + pCodecBuffer
->bufferSize
[1] + pCodecBuffer
->bufferSize
[2];
252 pData
->usedDataLen
= 0;
253 pData
->remainDataLen
= 0;
256 pData
->timeStamp
= 0;
257 pData
->pPrivate
= pCodecBuffer
;
258 pData
->bufferHeader
= NULL
;
263 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
265 EXYNOS_OMX_BASEPORT
*exynosOMXInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
266 EXYNOS_OMX_BASEPORT
*exynosOMXOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
267 EXYNOS_OMX_BASEPORT
*exynosOMXPort
= NULL
;
271 exynosOMXPort
= &pExynosComponent
->pExynosPort
[nPortIndex
];
273 if (((pExynosComponent
->currentState
== OMX_StatePause
) ||
274 (pExynosComponent
->currentState
== OMX_StateIdle
) ||
275 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateLoadedToIdle
) ||
276 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateExecutingToIdle
)) &&
277 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToLoaded
) &&
278 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort
))) {
279 Exynos_OSAL_SignalWait(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
, DEF_MAX_WAIT_TIME
);
280 Exynos_OSAL_SignalReset(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
);
288 OMX_BOOL
Exynos_CSC_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
290 OMX_BOOL ret
= OMX_FALSE
;
291 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
292 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
293 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
294 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
295 OMX_U32 copySize
= 0;
296 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
300 OMX_U32 width
= 0, height
= 0;
302 OMX_COLOR_FORMATTYPE colorFormat
;
304 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
305 void *pSrcBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
306 void *pYUVBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
308 CSC_ERRORCODE cscRet
= CSC_ErrorNone
;
309 CSC_METHOD csc_method
= CSC_METHOD_SW
;
310 CSC_MEMTYPE csc_memType
= CSC_MEMORY_USERPTR
;
312 unsigned int srcCacheable
= 1, dstCacheable
= 1;
314 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
316 width
= pBufferInfo
->imageWidth
;
317 height
= pBufferInfo
->imageHeight
;
318 imageSize
= width
* height
;
319 colorFormat
= pBufferInfo
->ColorFormat
;
321 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[0];
322 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[1];
323 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[2];
325 pYUVBuf
[0] = (unsigned char *)pOutputBuf
;
326 pYUVBuf
[1] = (unsigned char *)pOutputBuf
+ imageSize
;
327 pYUVBuf
[2] = (unsigned char *)pOutputBuf
+ imageSize
+ imageSize
/ 4;
329 csc_get_method(pVideoDec
->csc_handle
, &csc_method
);
330 if (csc_method
== CSC_METHOD_HW
)
334 if (csc_method
== CSC_METHOD_HW
) {
335 csc_memType
= CSC_MEMORY_DMABUF
;
336 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[0];
337 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[1];
338 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[2];
343 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
344 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
346 Exynos_OSAL_LockANB(pOutputBuf
, width
, height
, exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
, &stride
, planes
);
348 outputUseBuffer
->dataLen
= sizeof(void *);
350 pYUVBuf
[0] = (unsigned char *)planes
[0].addr
;
351 pYUVBuf
[1] = (unsigned char *)planes
[1].addr
;
352 pYUVBuf
[2] = (unsigned char *)planes
[2].addr
;
354 if (csc_method
== CSC_METHOD_HW
) {
355 pYUVBuf
[0] = (unsigned char *)planes
[0].fd
;
356 pYUVBuf
[1] = (unsigned char *)planes
[1].fd
;
357 pYUVBuf
[2] = (unsigned char *)planes
[2].fd
;
363 if ((exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) &&
364 (csc_method
== CSC_METHOD_HW
)) {
365 pYUVBuf
[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, pOutputBuf
);
371 if (pVideoDec
->csc_set_format
== OMX_FALSE
) {
373 pVideoDec
->csc_handle
, /* handle */
378 width
, /* crop_width */
379 height
, /* crop_height */
380 omx_2_hal_pixel_format(colorFormat
), /* color_format */
381 srcCacheable
); /* cacheable */
383 pVideoDec
->csc_handle
, /* handle */
388 width
, /* crop_width */
389 height
, /* crop_height */
390 omx_2_hal_pixel_format(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
), /* color_format */
391 dstCacheable
); /* cacheable */
392 pVideoDec
->csc_set_format
= OMX_TRUE
;
395 pVideoDec
->csc_handle
, /* handle */
397 csc_memType
); /* YUV Addr or FD */
399 pVideoDec
->csc_handle
, /* handle */
401 csc_memType
); /* YUV Addr or FD */
402 cscRet
= csc_convert(pVideoDec
->csc_handle
);
403 if (cscRet
!= CSC_ErrorNone
)
409 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
410 Exynos_OSAL_UnlockANB(pOutputBuf
);
420 OMX_BOOL
Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*srcInputData
)
422 OMX_BOOL ret
= OMX_FALSE
;
423 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
424 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
425 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
426 EXYNOS_OMX_DATABUFFER
*inputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
427 OMX_U32 copySize
= 0;
428 OMX_BYTE checkInputStream
= NULL
;
429 OMX_U32 checkInputStreamLen
= 0;
433 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
434 if ((srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) ||
435 (srcInputData
->pPrivate
== NULL
)) {
441 if (inputUseBuffer
->dataValid
== OMX_TRUE
) {
442 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
443 Exynos_Shared_BufferToData(inputUseBuffer
, srcInputData
, ONE_PLANE
);
445 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
) {
446 OMX_PTR dataBuffer
= NULL
;
448 dataBuffer
= Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec
->hSharedMemory
,
449 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
);
450 if (dataBuffer
== NULL
) {
455 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
= dataBuffer
;
458 /* reset dataBuffer */
459 Exynos_ResetDataBuffer(inputUseBuffer
);
460 } else if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
461 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
+ inputUseBuffer
->usedDataLen
;
462 checkInputStreamLen
= inputUseBuffer
->remainDataLen
;
464 pExynosComponent
->bUseFlagEOF
= OMX_TRUE
;
466 copySize
= checkInputStreamLen
;
467 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "exynos_checkInputFrame : OMX_TRUE");
469 if (((srcInputData
->allocSize
) - (srcInputData
->dataLen
)) >= copySize
) {
471 Exynos_OSAL_Memcpy(srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
+ srcInputData
->dataLen
,
472 checkInputStream
, copySize
);
475 inputUseBuffer
->dataLen
-= copySize
;
476 inputUseBuffer
->remainDataLen
-= copySize
;
477 inputUseBuffer
->usedDataLen
+= copySize
;
479 srcInputData
->dataLen
+= copySize
;
480 srcInputData
->remainDataLen
+= copySize
;
482 srcInputData
->timeStamp
= inputUseBuffer
->timeStamp
;
483 srcInputData
->nFlags
= inputUseBuffer
->nFlags
;
484 srcInputData
->bufferHeader
= inputUseBuffer
->bufferHeader
;
486 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "input codec buffer is smaller than decoded input data size Out Length");
487 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
488 pExynosComponent
->callbackData
,
489 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
493 Exynos_InputBufferReturn(pOMXComponent
, inputUseBuffer
);
496 if ((srcInputData
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
497 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "bSaveFlagEOS : OMX_TRUE");
498 srcInputData
->dataLen
= 0;
499 srcInputData
->remainDataLen
= 0;
500 pExynosComponent
->bSaveFlagEOS
= OMX_TRUE
;
503 if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
504 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_TRUE
;
505 pExynosComponent
->checkTimeStamp
.startTimeStamp
= srcInputData
->timeStamp
;
506 pExynosComponent
->checkTimeStamp
.nStartFlags
= srcInputData
->nFlags
;
507 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
508 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "first frame timestamp after seeking %lld us (%.2f secs)",
509 srcInputData
->timeStamp
, srcInputData
->timeStamp
/ 1E6
);
522 OMX_BOOL
Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
524 OMX_BOOL ret
= OMX_FALSE
;
525 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
526 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
527 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_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
->bIsANBEnabled
== OMX_FALSE
) {
536 if (Exynos_Shared_DataToBuffer(dstOutputData
, outputUseBuffer
) == OMX_ErrorNone
)
537 outputUseBuffer
->dataValid
= OMX_TRUE
;
539 if (Exynos_Shared_DataToANBBuffer(dstOutputData
, outputUseBuffer
, exynosOutputPort
) == OMX_ErrorNone
) {
540 outputUseBuffer
->dataValid
= OMX_TRUE
;
548 if (outputUseBuffer
->dataValid
== OMX_TRUE
) {
549 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "out timestamp after seeking %lld us (%.2f secs)",
550 dstOutputData
->timeStamp
, dstOutputData
->timeStamp
/ 1E6
);
551 if ((pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
== OMX_TRUE
) &&
552 ((dstOutputData
->nFlags
& OMX_BUFFERFLAG_EOS
) != OMX_BUFFERFLAG_EOS
)) {
553 if ((pExynosComponent
->checkTimeStamp
.startTimeStamp
== dstOutputData
->timeStamp
) &&
554 (pExynosComponent
->checkTimeStamp
.nStartFlags
== dstOutputData
->nFlags
)){
555 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
556 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
557 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
558 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
560 if (pExynosComponent
->checkTimeStamp
.startTimeStamp
< dstOutputData
->timeStamp
) {
561 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
562 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
563 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
564 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
566 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "drop frame after seeking", pExynosComponent
);
567 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)
568 Exynos_OMX_FillThisBuffer(pOMXComponent
, outputUseBuffer
->bufferHeader
);
574 } else if ((pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
)) {
576 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "not set check timestame after seeking");
580 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
581 OMX_U32 width
= 0, height
= 0;
583 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
585 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
587 width
= pBufferInfo
->imageWidth
;
588 height
= pBufferInfo
->imageHeight
;
589 imageSize
= width
* height
;
591 if ((dstOutputData
->remainDataLen
<= (outputUseBuffer
->allocSize
- outputUseBuffer
->dataLen
)) &&
592 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
593 copySize
= dstOutputData
->remainDataLen
;
594 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
,"copySize: %d", copySize
);
596 outputUseBuffer
->dataLen
+= copySize
;
597 outputUseBuffer
->remainDataLen
+= copySize
;
598 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
599 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
601 if (outputUseBuffer
->remainDataLen
> 0) {
602 ret
= Exynos_CSC_OutputData(pOMXComponent
, dstOutputData
);
607 if (ret
== OMX_TRUE
) {
608 if ((outputUseBuffer
->remainDataLen
> 0) ||
609 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
610 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
611 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
614 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "csc_convert Error");
615 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
616 pExynosComponent
->callbackData
,
617 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
620 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
621 outputUseBuffer
->dataLen
= 0;
622 outputUseBuffer
->remainDataLen
= 0;
623 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
624 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
625 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
627 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "output buffer is smaller than decoded data size Out Length");
628 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
629 pExynosComponent
->callbackData
,
630 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
633 } else if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
634 if ((outputUseBuffer
->remainDataLen
> 0) ||
635 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
636 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)))
637 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
649 OMX_ERRORTYPE
Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent
)
651 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
652 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
653 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
654 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
655 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
656 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
657 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
658 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
659 OMX_BOOL bCheckInputData
= OMX_FALSE
;
660 OMX_BOOL bValidCodecData
= OMX_FALSE
;
664 while (!pVideoDec
->bExitBufferProcessThread
) {
665 Exynos_OSAL_SleepMillisec(0);
666 Exynos_Wait_ProcessPause(pExynosComponent
, INPUT_PORT_INDEX
);
668 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
)) &&
669 (!pVideoDec
->bExitBufferProcessThread
)) {
670 Exynos_OSAL_SleepMillisec(0);
672 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) ||
673 ((exynosOutputPort
->exceptionFlag
== NEED_PORT_DISABLE
) && (ret
== OMX_ErrorInputDataDecodeYet
)))
675 if (exynosInputPort
->portState
!= OMX_StateIdle
)
678 Exynos_OSAL_MutexLock(srcInputUseBuffer
->bufferMutex
);
679 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
680 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
682 if ((pSrcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) || (pSrcInputData
->pPrivate
== NULL
)) {
683 Exynos_CodecBufferDeQueue(pExynosComponent
, INPUT_PORT_INDEX
, &codecBuffer
);
684 if (codecBuffer
!= NULL
) {
685 Exynos_Input_CodecBufferToData(pExynosComponent
, codecBuffer
, pSrcInputData
);
687 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
692 if (srcInputUseBuffer
->dataValid
== OMX_TRUE
) {
693 bCheckInputData
= Exynos_Preprocessor_InputData(pOMXComponent
, pSrcInputData
);
695 bCheckInputData
= OMX_FALSE
;
698 if ((bCheckInputData
== OMX_FALSE
) &&
699 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
700 ret
= Exynos_InputBufferGetQueue(pExynosComponent
);
701 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
705 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) {
706 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
711 ret
= pVideoDec
->exynos_codec_srcInputProcess(pOMXComponent
, pSrcInputData
);
712 if (ret
== OMX_ErrorCorruptedFrame
) {
713 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
715 codecBuffer
= pSrcInputData
->pPrivate
;
716 if (codecBuffer
!= NULL
)
717 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
720 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
721 Exynos_OMX_InputBufferReturn(pOMXComponent
, pSrcInputData
->bufferHeader
);
725 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
726 Exynos_ResetCodecData(pSrcInputData
);
728 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
729 if (ret
== OMX_ErrorCodecInit
)
730 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
741 OMX_ERRORTYPE
Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent
)
743 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
744 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
745 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
746 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
747 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
748 EXYNOS_OMX_DATABUFFER
*srcOutputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
749 EXYNOS_OMX_DATA srcOutputData
;
753 while (!pVideoDec
->bExitBufferProcessThread
) {
754 Exynos_OSAL_SleepMillisec(0);
756 while (!pVideoDec
->bExitBufferProcessThread
) {
757 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
758 if (Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
) == OMX_FALSE
)
761 Exynos_OSAL_SleepMillisec(0);
763 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
766 Exynos_OSAL_MutexLock(srcOutputUseBuffer
->bufferMutex
);
767 ret
= pVideoDec
->exynos_codec_srcOutputProcess(pOMXComponent
, &srcOutputData
);
769 if (ret
== OMX_ErrorNone
) {
770 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
772 codecBuffer
= srcOutputData
.pPrivate
;
773 if (codecBuffer
!= NULL
)
774 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
776 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
777 Exynos_Shared_DataToBuffer(&srcOutputData
, srcOutputUseBuffer
);
778 Exynos_InputBufferReturn(pOMXComponent
, srcOutputUseBuffer
);
780 Exynos_ResetCodecData(&srcOutputData
);
782 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer
->bufferMutex
);
793 OMX_ERRORTYPE
Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent
)
795 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
796 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
797 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
798 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
799 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
800 EXYNOS_OMX_DATABUFFER
*dstInputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
801 EXYNOS_OMX_DATA dstInputData
;
805 while (!pVideoDec
->bExitBufferProcessThread
) {
806 Exynos_OSAL_SleepMillisec(0);
808 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
809 (!pVideoDec
->bExitBufferProcessThread
)) {
810 Exynos_OSAL_SleepMillisec(0);
812 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) ||
813 (!CHECK_PORT_POPULATED(exynosOutputPort
)))
815 if (exynosOutputPort
->portState
!= OMX_StateIdle
)
818 Exynos_OSAL_MutexLock(dstInputUseBuffer
->bufferMutex
);
819 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
820 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
821 CODEC_DEC_BUFFER
*pCodecBuffer
= NULL
;
822 ret
= Exynos_CodecBufferDeQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, (OMX_PTR
*)&pCodecBuffer
);
823 if (ret
!= OMX_ErrorNone
) {
824 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
827 Exynos_Output_CodecBufferToData(pCodecBuffer
, &dstInputData
);
830 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
831 if ((dstInputUseBuffer
->dataValid
!= OMX_TRUE
) &&
832 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
833 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
834 if (ret
!= OMX_ErrorNone
) {
835 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
838 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
839 Exynos_Shared_BufferToData(dstInputUseBuffer
, &dstInputData
, TWO_PLANE
);
841 ret
= Exynos_Shared_ANBBufferToData(dstInputUseBuffer
, &dstInputData
, exynosOutputPort
, TWO_PLANE
);
842 if (ret
!= OMX_ErrorNone
) {
843 dstInputUseBuffer
->dataValid
= OMX_FALSE
;
844 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
848 Exynos_ResetDataBuffer(dstInputUseBuffer
);
852 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
853 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
858 ret
= pVideoDec
->exynos_codec_dstInputProcess(pOMXComponent
, &dstInputData
);
859 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
860 Exynos_ResetCodecData(&dstInputData
);
862 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
873 OMX_ERRORTYPE
Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent
)
875 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
876 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
877 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
878 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
879 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
880 EXYNOS_OMX_DATABUFFER
*dstOutputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
881 EXYNOS_OMX_DATA
*pDstOutputData
= &exynosOutputPort
->processData
;
885 while (!pVideoDec
->bExitBufferProcessThread
) {
886 Exynos_OSAL_SleepMillisec(0);
887 Exynos_Wait_ProcessPause(pExynosComponent
, OUTPUT_PORT_INDEX
);
889 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
890 (!pVideoDec
->bExitBufferProcessThread
)) {
891 Exynos_OSAL_SleepMillisec(0);
893 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))
896 Exynos_OSAL_MutexLock(dstOutputUseBuffer
->bufferMutex
);
897 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
898 if ((dstOutputUseBuffer
->dataValid
!= OMX_TRUE
) &&
899 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
900 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
901 if (ret
!= OMX_ErrorNone
) {
902 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
908 if ((dstOutputUseBuffer
->dataValid
== OMX_TRUE
) ||
909 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
))
910 ret
= pVideoDec
->exynos_codec_dstOutputProcess(pOMXComponent
, pDstOutputData
);
912 if (((ret
== OMX_ErrorNone
) && (dstOutputUseBuffer
->dataValid
== OMX_TRUE
)) ||
913 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)) {
914 Exynos_Postprocess_OutputData(pOMXComponent
, pDstOutputData
);
917 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
918 if (pDstOutputData
->pPrivate
!= NULL
) {
919 Exynos_CodecBufferEnQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, pDstOutputData
->pPrivate
);
920 pDstOutputData
->pPrivate
= NULL
;
924 /* reset outputData */
925 Exynos_ResetCodecData(pDstOutputData
);
926 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
937 static OMX_ERRORTYPE
Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData
)
939 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
940 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
941 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
942 EXYNOS_OMX_MESSAGE
*message
= NULL
;
946 if (threadData
== NULL
) {
947 ret
= OMX_ErrorBadParameter
;
950 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
951 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
952 if (ret
!= OMX_ErrorNone
) {
955 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
956 Exynos_OMX_SrcInputBufferProcess(pOMXComponent
);
958 Exynos_OSAL_ThreadExit(NULL
);
966 static OMX_ERRORTYPE
Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData
)
968 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
969 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
970 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
971 EXYNOS_OMX_MESSAGE
*message
= NULL
;
975 if (threadData
== NULL
) {
976 ret
= OMX_ErrorBadParameter
;
979 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
980 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
981 if (ret
!= OMX_ErrorNone
) {
984 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
985 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent
);
987 Exynos_OSAL_ThreadExit(NULL
);
995 static OMX_ERRORTYPE
Exynos_OMX_DstInputProcessThread(OMX_PTR threadData
)
997 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
998 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
999 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1000 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1004 if (threadData
== NULL
) {
1005 ret
= OMX_ErrorBadParameter
;
1008 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1009 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1010 if (ret
!= OMX_ErrorNone
) {
1013 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1014 Exynos_OMX_DstInputBufferProcess(pOMXComponent
);
1016 Exynos_OSAL_ThreadExit(NULL
);
1024 static OMX_ERRORTYPE
Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData
)
1026 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1027 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1028 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1029 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1033 if (threadData
== NULL
) {
1034 ret
= OMX_ErrorBadParameter
;
1037 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1038 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1039 if (ret
!= OMX_ErrorNone
) {
1042 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1043 Exynos_OMX_DstOutputBufferProcess(pOMXComponent
);
1045 Exynos_OSAL_ThreadExit(NULL
);
1053 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent
)
1055 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1056 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1057 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1058 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1062 pVideoDec
->bExitBufferProcessThread
= OMX_FALSE
;
1064 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstOutputThread
,
1065 Exynos_OMX_DstOutputProcessThread
,
1067 if (ret
== OMX_ErrorNone
)
1068 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcOutputThread
,
1069 Exynos_OMX_SrcOutputProcessThread
,
1071 if (ret
== OMX_ErrorNone
)
1072 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstInputThread
,
1073 Exynos_OMX_DstInputProcessThread
,
1075 if (ret
== OMX_ErrorNone
)
1076 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcInputThread
,
1077 Exynos_OMX_SrcInputProcessThread
,
1086 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent
)
1088 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1089 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1090 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1091 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1092 OMX_S32 countValue
= 0;
1097 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
1099 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1100 if (countValue
== 0)
1101 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
);
1102 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
, &countValue
);
1103 if (countValue
== 0)
1104 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
);
1105 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1106 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcInputThread
);
1107 pVideoDec
->hSrcInputThread
= NULL
;
1109 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1110 if (countValue
== 0)
1111 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
);
1112 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
, &countValue
);
1113 if (countValue
== 0)
1114 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
);
1115 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1116 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstInputThread
);
1117 pVideoDec
->hDstInputThread
= NULL
;
1119 pVideoDec
->exynos_codec_stop(pOMXComponent
, INPUT_PORT_INDEX
);
1120 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1121 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1122 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcOutputThread
);
1123 pVideoDec
->hSrcOutputThread
= NULL
;
1125 pVideoDec
->exynos_codec_stop(pOMXComponent
, OUTPUT_PORT_INDEX
);
1126 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1127 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1128 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstOutputThread
);
1129 pVideoDec
->hDstOutputThread
= NULL
;
1137 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent
)
1139 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1140 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1141 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1142 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1143 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1147 if (hComponent
== NULL
) {
1148 ret
= OMX_ErrorBadParameter
;
1151 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1152 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1153 if (ret
!= OMX_ErrorNone
) {
1154 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1158 ret
= Exynos_OMX_BaseComponent_Constructor(pOMXComponent
);
1159 if (ret
!= OMX_ErrorNone
) {
1160 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1164 ret
= Exynos_OMX_Port_Constructor(pOMXComponent
);
1165 if (ret
!= OMX_ErrorNone
) {
1166 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1167 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1171 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1173 pVideoDec
= Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1174 if (pVideoDec
== NULL
) {
1175 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1176 ret
= OMX_ErrorInsufficientResources
;
1177 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1181 Exynos_OSAL_Memset(pVideoDec
, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1182 pVideoDec
->bReconfigDPB
= OMX_FALSE
;
1183 pVideoDec
->nSavedDPBCnt
= 0;
1184 pVideoDec
->bDTSMode
= OMX_FALSE
;
1185 pExynosComponent
->hComponentHandle
= (OMX_HANDLETYPE
)pVideoDec
;
1187 pExynosComponent
->bSaveFlagEOS
= OMX_FALSE
;
1188 pExynosComponent
->bMultiThreadProcess
= OMX_TRUE
;
1191 pExynosPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
1192 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_INPUTBUFFER_NUM
;
1193 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_INPUTBUFFER_NUM
;
1194 pExynosPort
->portDefinition
.nBufferSize
= 0;
1195 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1197 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1198 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1199 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1200 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1201 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1203 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1204 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1205 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1206 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1207 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1208 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1209 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1210 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1213 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1214 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1215 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1216 pExynosPort
->portDefinition
.nBufferSize
= DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE
;
1217 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1219 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1220 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1221 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1222 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1223 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1225 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1226 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1227 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1228 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1229 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1230 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1231 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1232 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1234 pExynosPort
->processData
.extInfo
= (OMX_PTR
)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO
));
1236 pOMXComponent
->UseBuffer
= &Exynos_OMX_UseBuffer
;
1237 pOMXComponent
->AllocateBuffer
= &Exynos_OMX_AllocateBuffer
;
1238 pOMXComponent
->FreeBuffer
= &Exynos_OMX_FreeBuffer
;
1239 pOMXComponent
->ComponentTunnelRequest
= &Exynos_OMX_ComponentTunnelRequest
;
1241 pExynosComponent
->exynos_AllocateTunnelBuffer
= &Exynos_OMX_AllocateTunnelBuffer
;
1242 pExynosComponent
->exynos_FreeTunnelBuffer
= &Exynos_OMX_FreeTunnelBuffer
;
1243 pExynosComponent
->exynos_BufferProcessCreate
= &Exynos_OMX_BufferProcess_Create
;
1244 pExynosComponent
->exynos_BufferProcessTerminate
= &Exynos_OMX_BufferProcess_Terminate
;
1245 pExynosComponent
->exynos_BufferFlush
= &Exynos_OMX_BufferFlush
;
1253 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent
)
1255 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1256 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1257 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1258 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1259 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1264 if (hComponent
== NULL
) {
1265 ret
= OMX_ErrorBadParameter
;
1268 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1269 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1270 if (ret
!= OMX_ErrorNone
) {
1274 if (pOMXComponent
->pComponentPrivate
== NULL
) {
1275 ret
= OMX_ErrorBadParameter
;
1278 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1280 pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1282 Exynos_OSAL_Free(pVideoDec
);
1283 pExynosComponent
->hComponentHandle
= pVideoDec
= NULL
;
1285 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1286 if (pExynosPort
->processData
.extInfo
!= NULL
) {
1287 Exynos_OSAL_Free(pExynosPort
->processData
.extInfo
);
1288 pExynosPort
->processData
.extInfo
= NULL
;
1291 for(i
= 0; i
< ALL_PORT_NUM
; i
++) {
1292 pExynosPort
= &pExynosComponent
->pExynosPort
[i
];
1293 Exynos_OSAL_Free(pExynosPort
->portDefinition
.format
.video
.cMIMEType
);
1294 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= NULL
;
1297 ret
= Exynos_OMX_Port_Destructor(pOMXComponent
);
1299 ret
= Exynos_OMX_BaseComponent_Destructor(hComponent
);