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"
57 int calc_plane(int width
, int height
)
61 mbX
= (width
+ 15)/16;
62 mbY
= (height
+ 15)/16;
64 /* Alignment for interlaced processing */
65 mbY
= (mbY
+ 1) / 2 * 2;
67 return (mbX
* 16) * (mbY
* 16);
70 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE
*pOMXComponent
)
72 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
73 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
74 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
76 if ((exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
!=
77 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
) ||
78 (exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
!=
79 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
)) {
80 OMX_U32 width
= 0, height
= 0;
82 exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
=
83 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
;
84 exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
=
85 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
;
86 width
= exynosOutputPort
->portDefinition
.format
.video
.nStride
=
87 exynosInputPort
->portDefinition
.format
.video
.nStride
;
88 height
= exynosOutputPort
->portDefinition
.format
.video
.nSliceHeight
=
89 exynosInputPort
->portDefinition
.format
.video
.nSliceHeight
;
91 switch(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
) {
92 case OMX_COLOR_FormatYUV420Planar
:
93 case OMX_COLOR_FormatYUV420SemiPlanar
:
95 exynosOutputPort
->portDefinition
.nBufferSize
= (width
* height
* 3) / 2;
97 case OMX_SEC_COLOR_FormatNV12Tiled
:
98 width
= exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
;
99 height
= exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
;
100 if (width
&& height
) {
101 int YBufferSize
= calc_plane(width
, height
);
102 int CBufferSize
= calc_plane(width
, height
>> 1);
103 exynosOutputPort
->portDefinition
.nBufferSize
= YBufferSize
+ CBufferSize
;
108 exynosOutputPort
->portDefinition
.nBufferSize
= width
* height
* 2;
116 void Exynos_Free_CodecBuffers(
117 OMX_COMPONENTTYPE
*pOMXComponent
,
120 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
121 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
122 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
123 CODEC_DEC_BUFFER
**ppCodecBuffer
= NULL
;
125 OMX_U32 nPlaneCnt
= 0;
130 if (nPortIndex
== INPUT_PORT_INDEX
) {
131 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
132 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
134 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
135 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
138 for (i
= 0; i
< MFC_OUTPUT_BUFFER_NUM_MAX
; i
++) {
139 if (ppCodecBuffer
[i
] != NULL
) {
140 for (j
= 0; j
< nPlaneCnt
; j
++) {
141 if (ppCodecBuffer
[i
]->pVirAddr
[j
] != NULL
)
142 Exynos_OSAL_SharedMemory_Free(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
145 Exynos_OSAL_Free(ppCodecBuffer
[i
]);
146 ppCodecBuffer
[i
] = NULL
;
153 OMX_ERRORTYPE
Exynos_Allocate_CodecBuffers(
154 OMX_COMPONENTTYPE
*pOMXComponent
,
157 OMX_U32 nPlaneSize
[MFC_OUTPUT_BUFFER_PLANE
])
159 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
160 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
161 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
162 MEMORY_TYPE eMemoryType
= SYSTEM_MEMORY
;
163 CODEC_DEC_BUFFER
**ppCodecBuffer
= NULL
;
165 OMX_U32 nPlaneCnt
= 0;
170 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
)
171 eMemoryType
= SECURE_MEMORY
;
173 if (nPortIndex
== INPUT_PORT_INDEX
) {
174 ppCodecBuffer
= &(pVideoDec
->pMFCDecInputBuffer
[0]);
175 nPlaneCnt
= MFC_INPUT_BUFFER_PLANE
;
177 ppCodecBuffer
= &(pVideoDec
->pMFCDecOutputBuffer
[0]);
178 nPlaneCnt
= MFC_OUTPUT_BUFFER_PLANE
;
180 eMemoryType
= NORMAL_MEMORY
;
184 for (i
= 0; i
< nBufferCnt
; i
++) {
185 ppCodecBuffer
[i
] = (CODEC_DEC_BUFFER
*)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER
));
186 if (ppCodecBuffer
[i
] == NULL
) {
187 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc codec buffer");
188 ret
= OMX_ErrorInsufficientResources
;
191 Exynos_OSAL_Memset(ppCodecBuffer
[i
], 0, sizeof(CODEC_DEC_BUFFER
));
193 for (j
= 0; j
< nPlaneCnt
; j
++) {
194 ppCodecBuffer
[i
]->pVirAddr
[j
] =
195 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec
->hSharedMemory
, nPlaneSize
[j
], eMemoryType
);
196 if (ppCodecBuffer
[i
]->pVirAddr
[j
] == NULL
) {
197 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Failed to Alloc plane");
198 ret
= OMX_ErrorInsufficientResources
;
202 ppCodecBuffer
[i
]->fd
[j
] =
203 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
204 ppCodecBuffer
[i
]->bufferSize
[j
] = nPlaneSize
[j
];
205 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex
, i
, j
, ppCodecBuffer
[i
]->pVirAddr
[j
]);
208 ppCodecBuffer
[i
]->dataSize
= 0;
211 return OMX_ErrorNone
;
214 Exynos_Free_CodecBuffers(pOMXComponent
, nPortIndex
);
221 OMX_BOOL
Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
223 OMX_BOOL ret
= OMX_FALSE
;
225 if ((pExynosComponent
->currentState
== OMX_StateExecuting
) &&
226 (pExynosComponent
->pExynosPort
[nPortIndex
].portState
== OMX_StateIdle
) &&
227 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateExecutingToIdle
) &&
228 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToExecuting
)) {
237 OMX_ERRORTYPE
Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_PTR codecBuffer
, EXYNOS_OMX_DATA
*pData
)
239 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
240 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
241 CODEC_DEC_BUFFER
*pInputCodecBuffer
= (CODEC_DEC_BUFFER
*)codecBuffer
;
243 pData
->buffer
.singlePlaneBuffer
.dataBuffer
= pInputCodecBuffer
->pVirAddr
[0];
244 pData
->buffer
.singlePlaneBuffer
.fd
= pInputCodecBuffer
->fd
[0];
245 pData
->allocSize
= pInputCodecBuffer
->bufferSize
[0];
246 pData
->dataLen
= pInputCodecBuffer
->dataSize
;
247 pData
->usedDataLen
= 0;
248 pData
->remainDataLen
= pInputCodecBuffer
->dataSize
;
251 pData
->timeStamp
= 0;
252 pData
->pPrivate
= codecBuffer
;
253 pData
->bufferHeader
= NULL
;
258 OMX_ERRORTYPE
Exynos_Output_CodecBufferToData(
259 CODEC_DEC_BUFFER
*pCodecBuffer
,
260 EXYNOS_OMX_DATA
*pData
)
262 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
264 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] = pCodecBuffer
->pVirAddr
[0];
265 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[1] = pCodecBuffer
->pVirAddr
[1];
266 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[2] = pCodecBuffer
->pVirAddr
[2];
267 pData
->buffer
.multiPlaneBuffer
.fd
[0] = pCodecBuffer
->fd
[0];
268 pData
->buffer
.multiPlaneBuffer
.fd
[1] = pCodecBuffer
->fd
[1];
269 pData
->buffer
.multiPlaneBuffer
.fd
[2] = pCodecBuffer
->fd
[2];
270 pData
->allocSize
= pCodecBuffer
->bufferSize
[0] + pCodecBuffer
->bufferSize
[1] + pCodecBuffer
->bufferSize
[2];
272 pData
->usedDataLen
= 0;
273 pData
->remainDataLen
= 0;
276 pData
->timeStamp
= 0;
277 pData
->pPrivate
= pCodecBuffer
;
278 pData
->bufferHeader
= NULL
;
283 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
285 EXYNOS_OMX_BASEPORT
*exynosOMXInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
286 EXYNOS_OMX_BASEPORT
*exynosOMXOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
287 EXYNOS_OMX_BASEPORT
*exynosOMXPort
= NULL
;
291 exynosOMXPort
= &pExynosComponent
->pExynosPort
[nPortIndex
];
293 if (((pExynosComponent
->currentState
== OMX_StatePause
) ||
294 (pExynosComponent
->currentState
== OMX_StateIdle
) ||
295 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateLoadedToIdle
) ||
296 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateExecutingToIdle
)) &&
297 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToLoaded
) &&
298 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort
))) {
299 Exynos_OSAL_SignalWait(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
, DEF_MAX_WAIT_TIME
);
300 Exynos_OSAL_SignalReset(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
);
308 OMX_BOOL
Exynos_CSC_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
310 OMX_BOOL ret
= OMX_FALSE
;
311 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
312 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
313 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
314 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
315 OMX_U32 copySize
= 0;
316 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
320 OMX_U32 width
= 0, height
= 0;
322 OMX_COLOR_FORMATTYPE colorFormat
;
324 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
325 void *pSrcBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
326 void *pYUVBuf
[MAX_BUFFER_PLANE
] = {NULL
, };
328 CSC_ERRORCODE cscRet
= CSC_ErrorNone
;
329 CSC_METHOD csc_method
= CSC_METHOD_SW
;
330 unsigned int cacheable
= 1;
332 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
334 width
= pBufferInfo
->imageWidth
;
335 height
= pBufferInfo
->imageHeight
;
336 imageSize
= width
* height
;
337 colorFormat
= pBufferInfo
->ColorFormat
;
339 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[0];
340 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[1];
341 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.dataBuffer
[2];
343 pYUVBuf
[0] = (unsigned char *)pOutputBuf
;
344 pYUVBuf
[1] = (unsigned char *)pOutputBuf
+ imageSize
;
345 pYUVBuf
[2] = (unsigned char *)pOutputBuf
+ imageSize
+ imageSize
/ 4;
348 csc_get_method(pVideoDec
->csc_handle
, &csc_method
);
349 if (csc_method
== CSC_METHOD_HW
) {
350 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[0];
351 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[1];
352 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[2];
357 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
358 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
360 Exynos_OSAL_LockANB(pOutputBuf
, width
, height
, exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
, &stride
, planes
);
362 outputUseBuffer
->dataLen
= sizeof(void *);
364 pYUVBuf
[0] = (unsigned char *)planes
[0].addr
;
365 pYUVBuf
[1] = (unsigned char *)planes
[1].addr
;
366 pYUVBuf
[2] = (unsigned char *)planes
[2].addr
;
368 if (csc_method
== CSC_METHOD_HW
) {
369 pYUVBuf
[0] = (unsigned char *)planes
[0].fd
;
370 pYUVBuf
[1] = (unsigned char *)planes
[1].fd
;
371 pYUVBuf
[2] = (unsigned char *)planes
[2].fd
;
377 if ((exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) &&
378 (csc_method
== CSC_METHOD_HW
)) {
379 pYUVBuf
[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, pOutputBuf
);
385 if (pVideoDec
->csc_set_format
== OMX_FALSE
) {
387 pVideoDec
->csc_handle
, /* handle */
392 width
, /* crop_width */
393 height
, /* crop_height */
394 omx_2_hal_pixel_format(colorFormat
), /* color_format */
395 cacheable
); /* cacheable */
397 pVideoDec
->csc_handle
, /* handle */
402 width
, /* crop_width */
403 height
, /* crop_height */
404 omx_2_hal_pixel_format(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
), /* color_format */
405 cacheable
); /* cacheable */
406 pVideoDec
->csc_set_format
= OMX_TRUE
;
409 pVideoDec
->csc_handle
, /* handle */
411 CSC_MEMORY_DMABUF
); /* YUV Addr or FD */
413 pVideoDec
->csc_handle
, /* handle */
415 CSC_MEMORY_DMABUF
); /* YUV Addr or FD */
416 cscRet
= csc_convert(pVideoDec
->csc_handle
);
417 if (cscRet
!= CSC_ErrorNone
)
423 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
424 Exynos_OSAL_UnlockANB(pOutputBuf
);
434 OMX_BOOL
Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*srcInputData
)
436 OMX_BOOL ret
= OMX_FALSE
;
437 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
438 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
439 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
440 EXYNOS_OMX_DATABUFFER
*inputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
441 OMX_U32 copySize
= 0;
442 OMX_BYTE checkInputStream
= NULL
;
443 OMX_U32 checkInputStreamLen
= 0;
447 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
448 if ((srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) ||
449 (srcInputData
->pPrivate
== NULL
)) {
455 if (inputUseBuffer
->dataValid
== OMX_TRUE
) {
456 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
457 Exynos_Shared_BufferToData(inputUseBuffer
, srcInputData
, ONE_PLANE
);
459 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
) {
460 OMX_PTR dataBuffer
= NULL
;
462 dataBuffer
= Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec
->hSharedMemory
,
463 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
);
464 if (dataBuffer
== NULL
) {
469 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
= dataBuffer
;
472 /* reset dataBuffer */
473 Exynos_ResetDataBuffer(inputUseBuffer
);
474 } else if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
475 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
+ inputUseBuffer
->usedDataLen
;
476 checkInputStreamLen
= inputUseBuffer
->remainDataLen
;
478 pExynosComponent
->bUseFlagEOF
= OMX_TRUE
;
480 copySize
= checkInputStreamLen
;
481 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "exynos_checkInputFrame : OMX_TRUE");
483 if (((srcInputData
->allocSize
) - (srcInputData
->dataLen
)) >= copySize
) {
485 Exynos_OSAL_Memcpy(srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
+ srcInputData
->dataLen
,
486 checkInputStream
, copySize
);
489 inputUseBuffer
->dataLen
-= copySize
;
490 inputUseBuffer
->remainDataLen
-= copySize
;
491 inputUseBuffer
->usedDataLen
+= copySize
;
493 srcInputData
->dataLen
+= copySize
;
494 srcInputData
->remainDataLen
+= copySize
;
496 srcInputData
->timeStamp
= inputUseBuffer
->timeStamp
;
497 srcInputData
->nFlags
= inputUseBuffer
->nFlags
;
498 srcInputData
->bufferHeader
= inputUseBuffer
->bufferHeader
;
500 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "input codec buffer is smaller than decoded input data size Out Length");
501 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
502 pExynosComponent
->callbackData
,
503 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
507 Exynos_InputBufferReturn(pOMXComponent
, inputUseBuffer
);
510 if ((srcInputData
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
511 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "bSaveFlagEOS : OMX_TRUE");
512 srcInputData
->dataLen
= 0;
513 srcInputData
->remainDataLen
= 0;
514 pExynosComponent
->bSaveFlagEOS
= OMX_TRUE
;
517 if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
518 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_TRUE
;
519 pExynosComponent
->checkTimeStamp
.startTimeStamp
= srcInputData
->timeStamp
;
520 pExynosComponent
->checkTimeStamp
.nStartFlags
= srcInputData
->nFlags
;
521 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
522 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "first frame timestamp after seeking %lld us (%.2f secs)",
523 srcInputData
->timeStamp
, srcInputData
->timeStamp
/ 1E6
);
536 OMX_BOOL
Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
538 OMX_BOOL ret
= OMX_FALSE
;
539 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
540 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
541 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
542 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
543 OMX_U32 copySize
= 0;
544 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
548 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
549 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
550 if (Exynos_Shared_DataToBuffer(dstOutputData
, outputUseBuffer
) == OMX_ErrorNone
)
551 outputUseBuffer
->dataValid
= OMX_TRUE
;
553 if (Exynos_Shared_DataToANBBuffer(dstOutputData
, outputUseBuffer
, exynosOutputPort
) == OMX_ErrorNone
) {
554 outputUseBuffer
->dataValid
= OMX_TRUE
;
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
;
574 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "drop frame after seeking", pExynosComponent
);
575 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)
576 Exynos_OMX_FillThisBuffer(pOMXComponent
, outputUseBuffer
->bufferHeader
);
578 if (pExynosComponent
->checkTimeStamp
.startTimeStamp
< dstOutputData
->timeStamp
) {
579 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
580 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
581 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
582 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
588 } else if ((pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
)) {
590 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "not set check timestame after seeking");
594 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
595 OMX_U32 width
= 0, height
= 0;
597 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
599 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
601 width
= pBufferInfo
->imageWidth
;
602 height
= pBufferInfo
->imageHeight
;
603 imageSize
= width
* height
;
605 if ((dstOutputData
->remainDataLen
<= (outputUseBuffer
->allocSize
- outputUseBuffer
->dataLen
)) &&
606 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
607 copySize
= dstOutputData
->remainDataLen
;
608 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
,"copySize: %d", copySize
);
610 outputUseBuffer
->dataLen
+= copySize
;
611 outputUseBuffer
->remainDataLen
+= copySize
;
612 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
613 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
615 if (outputUseBuffer
->remainDataLen
> 0) {
616 ret
= Exynos_CSC_OutputData(pOMXComponent
, dstOutputData
);
621 if (ret
== OMX_TRUE
) {
622 if ((outputUseBuffer
->remainDataLen
> 0) ||
623 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
624 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
625 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
628 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "csc_convert Error");
629 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
630 pExynosComponent
->callbackData
,
631 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
634 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
635 outputUseBuffer
->dataLen
= 0;
636 outputUseBuffer
->remainDataLen
= 0;
637 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
638 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
639 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
641 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "output buffer is smaller than decoded data size Out Length");
642 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
643 pExynosComponent
->callbackData
,
644 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
647 } else if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
648 if ((outputUseBuffer
->remainDataLen
> 0) ||
649 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
650 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)))
651 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
663 OMX_ERRORTYPE
Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent
)
665 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
666 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
667 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
668 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
669 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
670 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
671 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
672 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
673 OMX_BOOL bCheckInputData
= OMX_FALSE
;
674 OMX_BOOL bValidCodecData
= OMX_FALSE
;
678 while (!pVideoDec
->bExitBufferProcessThread
) {
679 Exynos_OSAL_SleepMillisec(0);
680 Exynos_Wait_ProcessPause(pExynosComponent
, INPUT_PORT_INDEX
);
682 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
)) &&
683 (!pVideoDec
->bExitBufferProcessThread
)) {
684 Exynos_OSAL_SleepMillisec(0);
686 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) ||
687 ((exynosOutputPort
->exceptionFlag
== NEED_PORT_DISABLE
) && (ret
== OMX_ErrorInputDataDecodeYet
)))
689 if (exynosInputPort
->portState
!= OMX_StateIdle
)
692 Exynos_OSAL_MutexLock(srcInputUseBuffer
->bufferMutex
);
693 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
694 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
696 if ((pSrcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) || (pSrcInputData
->pPrivate
== NULL
)) {
697 Exynos_CodecBufferDeQueue(pExynosComponent
, INPUT_PORT_INDEX
, &codecBuffer
);
698 if (codecBuffer
!= NULL
) {
699 Exynos_Input_CodecBufferToData(pExynosComponent
, codecBuffer
, pSrcInputData
);
701 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
706 if (srcInputUseBuffer
->dataValid
== OMX_TRUE
) {
707 bCheckInputData
= Exynos_Preprocessor_InputData(pOMXComponent
, pSrcInputData
);
709 bCheckInputData
= OMX_FALSE
;
712 if ((bCheckInputData
== OMX_FALSE
) &&
713 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
714 ret
= Exynos_InputBufferGetQueue(pExynosComponent
);
715 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
719 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) {
720 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
725 ret
= pVideoDec
->exynos_codec_srcInputProcess(pOMXComponent
, pSrcInputData
);
726 if (ret
== OMX_ErrorCorruptedFrame
) {
727 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
729 codecBuffer
= pSrcInputData
->pPrivate
;
730 if (codecBuffer
!= NULL
)
731 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
734 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
735 Exynos_OMX_InputBufferReturn(pOMXComponent
, pSrcInputData
->bufferHeader
);
739 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
740 Exynos_ResetCodecData(pSrcInputData
);
742 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
743 if (ret
== OMX_ErrorCodecInit
)
744 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
755 OMX_ERRORTYPE
Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent
)
757 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
758 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
759 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
760 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
761 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
762 EXYNOS_OMX_DATABUFFER
*srcOutputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
763 EXYNOS_OMX_DATA srcOutputData
;
767 while (!pVideoDec
->bExitBufferProcessThread
) {
768 Exynos_OSAL_SleepMillisec(0);
770 while (!pVideoDec
->bExitBufferProcessThread
) {
771 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
772 if (Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
) == OMX_FALSE
)
775 Exynos_OSAL_SleepMillisec(0);
777 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
780 Exynos_OSAL_MutexLock(srcOutputUseBuffer
->bufferMutex
);
781 ret
= pVideoDec
->exynos_codec_srcOutputProcess(pOMXComponent
, &srcOutputData
);
783 if (ret
== OMX_ErrorNone
) {
784 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
786 codecBuffer
= srcOutputData
.pPrivate
;
787 if (codecBuffer
!= NULL
)
788 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
790 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
791 Exynos_Shared_DataToBuffer(&srcOutputData
, srcOutputUseBuffer
);
792 Exynos_InputBufferReturn(pOMXComponent
, srcOutputUseBuffer
);
794 Exynos_ResetCodecData(&srcOutputData
);
796 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer
->bufferMutex
);
807 OMX_ERRORTYPE
Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent
)
809 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
810 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
811 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
812 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
813 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
814 EXYNOS_OMX_DATABUFFER
*dstInputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
815 EXYNOS_OMX_DATA dstInputData
;
819 while (!pVideoDec
->bExitBufferProcessThread
) {
820 Exynos_OSAL_SleepMillisec(0);
822 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
823 (!pVideoDec
->bExitBufferProcessThread
)) {
824 Exynos_OSAL_SleepMillisec(0);
826 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) ||
827 (!CHECK_PORT_POPULATED(exynosOutputPort
)))
829 if (exynosOutputPort
->portState
!= OMX_StateIdle
)
832 Exynos_OSAL_MutexLock(dstInputUseBuffer
->bufferMutex
);
833 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
834 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
835 CODEC_DEC_BUFFER
*pCodecBuffer
= NULL
;
836 ret
= Exynos_CodecBufferDeQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, (OMX_PTR
*)&pCodecBuffer
);
837 if (ret
!= OMX_ErrorNone
) {
838 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
841 Exynos_Output_CodecBufferToData(pCodecBuffer
, &dstInputData
);
844 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
845 if ((dstInputUseBuffer
->dataValid
!= OMX_TRUE
) &&
846 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
847 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
848 if (ret
!= OMX_ErrorNone
) {
849 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
852 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
853 Exynos_Shared_BufferToData(dstInputUseBuffer
, &dstInputData
, TWO_PLANE
);
855 ret
= Exynos_Shared_ANBBufferToData(dstInputUseBuffer
, &dstInputData
, exynosOutputPort
, TWO_PLANE
);
856 if (ret
!= OMX_ErrorNone
) {
857 dstInputUseBuffer
->dataValid
= OMX_FALSE
;
858 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
862 Exynos_ResetDataBuffer(dstInputUseBuffer
);
866 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
867 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
872 ret
= pVideoDec
->exynos_codec_dstInputProcess(pOMXComponent
, &dstInputData
);
873 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
874 Exynos_ResetCodecData(&dstInputData
);
876 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
887 OMX_ERRORTYPE
Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent
)
889 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
890 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
891 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
892 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
893 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
894 EXYNOS_OMX_DATABUFFER
*dstOutputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
895 EXYNOS_OMX_DATA
*pDstOutputData
= &exynosOutputPort
->processData
;
899 while (!pVideoDec
->bExitBufferProcessThread
) {
900 Exynos_OSAL_SleepMillisec(0);
901 Exynos_Wait_ProcessPause(pExynosComponent
, OUTPUT_PORT_INDEX
);
903 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
904 (!pVideoDec
->bExitBufferProcessThread
)) {
905 Exynos_OSAL_SleepMillisec(0);
907 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))
910 Exynos_OSAL_MutexLock(dstOutputUseBuffer
->bufferMutex
);
911 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
912 if ((dstOutputUseBuffer
->dataValid
!= OMX_TRUE
) &&
913 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
914 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
915 if (ret
!= OMX_ErrorNone
) {
916 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
922 if ((dstOutputUseBuffer
->dataValid
== OMX_TRUE
) ||
923 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
))
924 ret
= pVideoDec
->exynos_codec_dstOutputProcess(pOMXComponent
, pDstOutputData
);
926 if (((ret
== OMX_ErrorNone
) && (dstOutputUseBuffer
->dataValid
== OMX_TRUE
)) ||
927 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)) {
928 Exynos_Postprocess_OutputData(pOMXComponent
, pDstOutputData
);
931 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
932 if (pDstOutputData
->pPrivate
!= NULL
) {
933 Exynos_CodecBufferEnQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, pDstOutputData
->pPrivate
);
934 pDstOutputData
->pPrivate
= NULL
;
938 /* reset outputData */
939 Exynos_ResetCodecData(pDstOutputData
);
940 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
951 static OMX_ERRORTYPE
Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData
)
953 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
954 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
955 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
956 EXYNOS_OMX_MESSAGE
*message
= NULL
;
960 if (threadData
== NULL
) {
961 ret
= OMX_ErrorBadParameter
;
964 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
965 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
966 if (ret
!= OMX_ErrorNone
) {
969 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
970 Exynos_OMX_SrcInputBufferProcess(pOMXComponent
);
972 Exynos_OSAL_ThreadExit(NULL
);
980 static OMX_ERRORTYPE
Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData
)
982 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
983 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
984 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
985 EXYNOS_OMX_MESSAGE
*message
= NULL
;
989 if (threadData
== NULL
) {
990 ret
= OMX_ErrorBadParameter
;
993 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
994 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
995 if (ret
!= OMX_ErrorNone
) {
998 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
999 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent
);
1001 Exynos_OSAL_ThreadExit(NULL
);
1009 static OMX_ERRORTYPE
Exynos_OMX_DstInputProcessThread(OMX_PTR threadData
)
1011 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1012 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1013 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1014 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1018 if (threadData
== NULL
) {
1019 ret
= OMX_ErrorBadParameter
;
1022 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1023 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1024 if (ret
!= OMX_ErrorNone
) {
1027 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1028 Exynos_OMX_DstInputBufferProcess(pOMXComponent
);
1030 Exynos_OSAL_ThreadExit(NULL
);
1038 static OMX_ERRORTYPE
Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData
)
1040 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1041 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1042 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1043 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1047 if (threadData
== NULL
) {
1048 ret
= OMX_ErrorBadParameter
;
1051 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1052 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1053 if (ret
!= OMX_ErrorNone
) {
1056 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1057 Exynos_OMX_DstOutputBufferProcess(pOMXComponent
);
1059 Exynos_OSAL_ThreadExit(NULL
);
1067 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent
)
1069 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1070 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1071 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1072 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1076 pVideoDec
->bExitBufferProcessThread
= OMX_FALSE
;
1078 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstOutputThread
,
1079 Exynos_OMX_DstOutputProcessThread
,
1081 if (ret
== OMX_ErrorNone
)
1082 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcOutputThread
,
1083 Exynos_OMX_SrcOutputProcessThread
,
1085 if (ret
== OMX_ErrorNone
)
1086 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstInputThread
,
1087 Exynos_OMX_DstInputProcessThread
,
1089 if (ret
== OMX_ErrorNone
)
1090 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcInputThread
,
1091 Exynos_OMX_SrcInputProcessThread
,
1100 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent
)
1102 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1103 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1104 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1105 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1106 OMX_S32 countValue
= 0;
1111 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
1113 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1114 if (countValue
== 0)
1115 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
);
1116 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
, &countValue
);
1117 if (countValue
== 0)
1118 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
);
1119 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1120 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcInputThread
);
1121 pVideoDec
->hSrcInputThread
= NULL
;
1123 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1124 if (countValue
== 0)
1125 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
);
1126 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
, &countValue
);
1127 if (countValue
== 0)
1128 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
);
1129 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1130 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstInputThread
);
1131 pVideoDec
->hDstInputThread
= NULL
;
1133 pVideoDec
->exynos_codec_stop(pOMXComponent
, INPUT_PORT_INDEX
);
1134 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1135 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1136 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcOutputThread
);
1137 pVideoDec
->hSrcOutputThread
= NULL
;
1139 pVideoDec
->exynos_codec_stop(pOMXComponent
, OUTPUT_PORT_INDEX
);
1140 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1141 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1142 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstOutputThread
);
1143 pVideoDec
->hDstOutputThread
= NULL
;
1151 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent
)
1153 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1154 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1155 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1156 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1157 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1161 if (hComponent
== NULL
) {
1162 ret
= OMX_ErrorBadParameter
;
1165 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1166 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1167 if (ret
!= OMX_ErrorNone
) {
1168 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1172 ret
= Exynos_OMX_BaseComponent_Constructor(pOMXComponent
);
1173 if (ret
!= OMX_ErrorNone
) {
1174 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1178 ret
= Exynos_OMX_Port_Constructor(pOMXComponent
);
1179 if (ret
!= OMX_ErrorNone
) {
1180 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1181 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1185 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1187 pVideoDec
= Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1188 if (pVideoDec
== NULL
) {
1189 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1190 ret
= OMX_ErrorInsufficientResources
;
1191 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1195 Exynos_OSAL_Memset(pVideoDec
, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1196 pVideoDec
->bReconfigDPB
= OMX_FALSE
;
1197 pVideoDec
->nSavedDPBCnt
= 0;
1198 pExynosComponent
->hComponentHandle
= (OMX_HANDLETYPE
)pVideoDec
;
1200 pExynosComponent
->bSaveFlagEOS
= OMX_FALSE
;
1201 pExynosComponent
->bMultiThreadProcess
= OMX_TRUE
;
1204 pExynosPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
1205 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_INPUTBUFFER_NUM
;
1206 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_INPUTBUFFER_NUM
;
1207 pExynosPort
->portDefinition
.nBufferSize
= 0;
1208 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1210 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1211 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1212 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1213 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1214 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1216 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1217 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1218 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1219 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1220 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1221 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1222 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1223 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1226 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1227 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1228 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1229 pExynosPort
->portDefinition
.nBufferSize
= DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE
;
1230 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1232 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1233 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1234 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1235 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1236 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1238 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1239 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1240 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1241 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1242 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1243 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1244 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1245 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1247 pExynosPort
->processData
.extInfo
= (OMX_PTR
)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO
));
1249 pOMXComponent
->UseBuffer
= &Exynos_OMX_UseBuffer
;
1250 pOMXComponent
->AllocateBuffer
= &Exynos_OMX_AllocateBuffer
;
1251 pOMXComponent
->FreeBuffer
= &Exynos_OMX_FreeBuffer
;
1252 pOMXComponent
->ComponentTunnelRequest
= &Exynos_OMX_ComponentTunnelRequest
;
1254 pExynosComponent
->exynos_AllocateTunnelBuffer
= &Exynos_OMX_AllocateTunnelBuffer
;
1255 pExynosComponent
->exynos_FreeTunnelBuffer
= &Exynos_OMX_FreeTunnelBuffer
;
1256 pExynosComponent
->exynos_BufferProcessCreate
= &Exynos_OMX_BufferProcess_Create
;
1257 pExynosComponent
->exynos_BufferProcessTerminate
= &Exynos_OMX_BufferProcess_Terminate
;
1258 pExynosComponent
->exynos_BufferFlush
= &Exynos_OMX_BufferFlush
;
1266 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent
)
1268 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1269 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1270 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1271 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1272 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1277 if (hComponent
== NULL
) {
1278 ret
= OMX_ErrorBadParameter
;
1281 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1282 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1283 if (ret
!= OMX_ErrorNone
) {
1287 if (pOMXComponent
->pComponentPrivate
== NULL
) {
1288 ret
= OMX_ErrorBadParameter
;
1291 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1293 pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1295 Exynos_OSAL_Free(pVideoDec
);
1296 pExynosComponent
->hComponentHandle
= pVideoDec
= NULL
;
1298 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1299 if (pExynosPort
->processData
.extInfo
!= NULL
) {
1300 Exynos_OSAL_Free(pExynosPort
->processData
.extInfo
);
1301 pExynosPort
->processData
.extInfo
= NULL
;
1304 for(i
= 0; i
< ALL_PORT_NUM
; i
++) {
1305 pExynosPort
= &pExynosComponent
->pExynosPort
[i
];
1306 Exynos_OSAL_Free(pExynosPort
->portDefinition
.format
.video
.cMIMEType
);
1307 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= NULL
;
1310 ret
= Exynos_OMX_Port_Destructor(pOMXComponent
);
1312 ret
= Exynos_OMX_BaseComponent_Destructor(hComponent
);