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 srcCacheable
= 1, dstCacheable
= 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;
347 csc_get_method(pVideoDec
->csc_handle
, &csc_method
);
348 if (csc_method
== CSC_METHOD_HW
)
352 if (csc_method
== CSC_METHOD_HW
) {
353 pSrcBuf
[0] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[0];
354 pSrcBuf
[1] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[1];
355 pSrcBuf
[2] = dstOutputData
->buffer
.multiPlaneBuffer
.fd
[2];
360 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
361 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
363 Exynos_OSAL_LockANB(pOutputBuf
, width
, height
, exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
, &stride
, planes
);
365 outputUseBuffer
->dataLen
= sizeof(void *);
367 pYUVBuf
[0] = (unsigned char *)planes
[0].addr
;
368 pYUVBuf
[1] = (unsigned char *)planes
[1].addr
;
369 pYUVBuf
[2] = (unsigned char *)planes
[2].addr
;
371 if (csc_method
== CSC_METHOD_HW
) {
372 pYUVBuf
[0] = (unsigned char *)planes
[0].fd
;
373 pYUVBuf
[1] = (unsigned char *)planes
[1].fd
;
374 pYUVBuf
[2] = (unsigned char *)planes
[2].fd
;
380 if ((exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) &&
381 (csc_method
== CSC_METHOD_HW
)) {
382 pYUVBuf
[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec
->hSharedMemory
, pOutputBuf
);
388 if (pVideoDec
->csc_set_format
== OMX_FALSE
) {
390 pVideoDec
->csc_handle
, /* handle */
395 width
, /* crop_width */
396 height
, /* crop_height */
397 omx_2_hal_pixel_format(colorFormat
), /* color_format */
398 srcCacheable
); /* cacheable */
400 pVideoDec
->csc_handle
, /* handle */
405 width
, /* crop_width */
406 height
, /* crop_height */
407 omx_2_hal_pixel_format(exynosOutputPort
->portDefinition
.format
.video
.eColorFormat
), /* color_format */
408 dstCacheable
); /* cacheable */
409 pVideoDec
->csc_set_format
= OMX_TRUE
;
412 pVideoDec
->csc_handle
, /* handle */
414 CSC_MEMORY_DMABUF
); /* YUV Addr or FD */
416 pVideoDec
->csc_handle
, /* handle */
418 CSC_MEMORY_DMABUF
); /* YUV Addr or FD */
419 cscRet
= csc_convert(pVideoDec
->csc_handle
);
420 if (cscRet
!= CSC_ErrorNone
)
426 if (exynosOutputPort
->bIsANBEnabled
== OMX_TRUE
) {
427 Exynos_OSAL_UnlockANB(pOutputBuf
);
437 OMX_BOOL
Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*srcInputData
)
439 OMX_BOOL ret
= OMX_FALSE
;
440 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
441 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
442 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
443 EXYNOS_OMX_DATABUFFER
*inputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
444 OMX_U32 copySize
= 0;
445 OMX_BYTE checkInputStream
= NULL
;
446 OMX_U32 checkInputStreamLen
= 0;
450 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
451 if ((srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) ||
452 (srcInputData
->pPrivate
== NULL
)) {
458 if (inputUseBuffer
->dataValid
== OMX_TRUE
) {
459 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
460 Exynos_Shared_BufferToData(inputUseBuffer
, srcInputData
, ONE_PLANE
);
462 if (pVideoDec
->bDRMPlayerMode
== OMX_TRUE
) {
463 OMX_PTR dataBuffer
= NULL
;
465 dataBuffer
= Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec
->hSharedMemory
,
466 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
);
467 if (dataBuffer
== NULL
) {
472 srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
= dataBuffer
;
475 /* reset dataBuffer */
476 Exynos_ResetDataBuffer(inputUseBuffer
);
477 } else if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
478 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
+ inputUseBuffer
->usedDataLen
;
479 checkInputStreamLen
= inputUseBuffer
->remainDataLen
;
481 pExynosComponent
->bUseFlagEOF
= OMX_TRUE
;
483 copySize
= checkInputStreamLen
;
484 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "exynos_checkInputFrame : OMX_TRUE");
486 if (((srcInputData
->allocSize
) - (srcInputData
->dataLen
)) >= copySize
) {
488 Exynos_OSAL_Memcpy(srcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
+ srcInputData
->dataLen
,
489 checkInputStream
, copySize
);
492 inputUseBuffer
->dataLen
-= copySize
;
493 inputUseBuffer
->remainDataLen
-= copySize
;
494 inputUseBuffer
->usedDataLen
+= copySize
;
496 srcInputData
->dataLen
+= copySize
;
497 srcInputData
->remainDataLen
+= copySize
;
499 srcInputData
->timeStamp
= inputUseBuffer
->timeStamp
;
500 srcInputData
->nFlags
= inputUseBuffer
->nFlags
;
501 srcInputData
->bufferHeader
= inputUseBuffer
->bufferHeader
;
503 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "input codec buffer is smaller than decoded input data size Out Length");
504 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
505 pExynosComponent
->callbackData
,
506 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
510 Exynos_InputBufferReturn(pOMXComponent
, inputUseBuffer
);
513 if ((srcInputData
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
514 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "bSaveFlagEOS : OMX_TRUE");
515 srcInputData
->dataLen
= 0;
516 srcInputData
->remainDataLen
= 0;
517 pExynosComponent
->bSaveFlagEOS
= OMX_TRUE
;
520 if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
521 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_TRUE
;
522 pExynosComponent
->checkTimeStamp
.startTimeStamp
= srcInputData
->timeStamp
;
523 pExynosComponent
->checkTimeStamp
.nStartFlags
= srcInputData
->nFlags
;
524 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
525 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "first frame timestamp after seeking %lld us (%.2f secs)",
526 srcInputData
->timeStamp
, srcInputData
->timeStamp
/ 1E6
);
539 OMX_BOOL
Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
541 OMX_BOOL ret
= OMX_FALSE
;
542 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
543 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
544 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
545 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
546 OMX_U32 copySize
= 0;
547 DECODE_CODEC_EXTRA_BUFFERINFO
*pBufferInfo
= NULL
;
551 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
552 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
553 if (Exynos_Shared_DataToBuffer(dstOutputData
, outputUseBuffer
) == OMX_ErrorNone
)
554 outputUseBuffer
->dataValid
= OMX_TRUE
;
556 if (Exynos_Shared_DataToANBBuffer(dstOutputData
, outputUseBuffer
, exynosOutputPort
) == OMX_ErrorNone
) {
557 outputUseBuffer
->dataValid
= OMX_TRUE
;
565 if (outputUseBuffer
->dataValid
== OMX_TRUE
) {
566 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "out timestamp after seeking %lld us (%.2f secs)",
567 dstOutputData
->timeStamp
, dstOutputData
->timeStamp
/ 1E6
);
568 if ((pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
== OMX_TRUE
) &&
569 ((dstOutputData
->nFlags
& OMX_BUFFERFLAG_EOS
) != OMX_BUFFERFLAG_EOS
)) {
570 if ((pExynosComponent
->checkTimeStamp
.startTimeStamp
== dstOutputData
->timeStamp
) &&
571 (pExynosComponent
->checkTimeStamp
.nStartFlags
== dstOutputData
->nFlags
)){
572 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
573 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
574 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
575 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
577 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "drop frame after seeking", pExynosComponent
);
578 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)
579 Exynos_OMX_FillThisBuffer(pOMXComponent
, outputUseBuffer
->bufferHeader
);
581 if (pExynosComponent
->checkTimeStamp
.startTimeStamp
< dstOutputData
->timeStamp
) {
582 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
583 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
584 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
585 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
591 } else if ((pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
)) {
593 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "not set check timestame after seeking");
597 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
598 OMX_U32 width
= 0, height
= 0;
600 void *pOutputBuf
= (void *)outputUseBuffer
->bufferHeader
->pBuffer
;
602 pBufferInfo
= (DECODE_CODEC_EXTRA_BUFFERINFO
*)dstOutputData
->extInfo
;
604 width
= pBufferInfo
->imageWidth
;
605 height
= pBufferInfo
->imageHeight
;
606 imageSize
= width
* height
;
608 if ((dstOutputData
->remainDataLen
<= (outputUseBuffer
->allocSize
- outputUseBuffer
->dataLen
)) &&
609 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
610 copySize
= dstOutputData
->remainDataLen
;
611 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
,"copySize: %d", copySize
);
613 outputUseBuffer
->dataLen
+= copySize
;
614 outputUseBuffer
->remainDataLen
+= copySize
;
615 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
616 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
618 if (outputUseBuffer
->remainDataLen
> 0) {
619 ret
= Exynos_CSC_OutputData(pOMXComponent
, dstOutputData
);
624 if (ret
== OMX_TRUE
) {
625 if ((outputUseBuffer
->remainDataLen
> 0) ||
626 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
627 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
628 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
631 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "csc_convert Error");
632 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
633 pExynosComponent
->callbackData
,
634 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
637 } else if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
638 outputUseBuffer
->dataLen
= 0;
639 outputUseBuffer
->remainDataLen
= 0;
640 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
641 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
642 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
644 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "output buffer is smaller than decoded data size Out Length");
645 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
646 pExynosComponent
->callbackData
,
647 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
650 } else if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
651 if ((outputUseBuffer
->remainDataLen
> 0) ||
652 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
653 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)))
654 Exynos_OutputBufferReturn(pOMXComponent
, outputUseBuffer
);
666 OMX_ERRORTYPE
Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent
)
668 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
669 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
670 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
671 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
672 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
673 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
674 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
675 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
676 OMX_BOOL bCheckInputData
= OMX_FALSE
;
677 OMX_BOOL bValidCodecData
= OMX_FALSE
;
681 while (!pVideoDec
->bExitBufferProcessThread
) {
682 Exynos_OSAL_SleepMillisec(0);
683 Exynos_Wait_ProcessPause(pExynosComponent
, INPUT_PORT_INDEX
);
685 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
)) &&
686 (!pVideoDec
->bExitBufferProcessThread
)) {
687 Exynos_OSAL_SleepMillisec(0);
689 if ((CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) ||
690 ((exynosOutputPort
->exceptionFlag
== NEED_PORT_DISABLE
) && (ret
== OMX_ErrorInputDataDecodeYet
)))
692 if (exynosInputPort
->portState
!= OMX_StateIdle
)
695 Exynos_OSAL_MutexLock(srcInputUseBuffer
->bufferMutex
);
696 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
697 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
699 if ((pSrcInputData
->buffer
.singlePlaneBuffer
.dataBuffer
== NULL
) || (pSrcInputData
->pPrivate
== NULL
)) {
700 Exynos_CodecBufferDeQueue(pExynosComponent
, INPUT_PORT_INDEX
, &codecBuffer
);
701 if (codecBuffer
!= NULL
) {
702 Exynos_Input_CodecBufferToData(pExynosComponent
, codecBuffer
, pSrcInputData
);
704 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
709 if (srcInputUseBuffer
->dataValid
== OMX_TRUE
) {
710 bCheckInputData
= Exynos_Preprocessor_InputData(pOMXComponent
, pSrcInputData
);
712 bCheckInputData
= OMX_FALSE
;
715 if ((bCheckInputData
== OMX_FALSE
) &&
716 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
717 ret
= Exynos_InputBufferGetQueue(pExynosComponent
);
718 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
722 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) {
723 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
728 ret
= pVideoDec
->exynos_codec_srcInputProcess(pOMXComponent
, pSrcInputData
);
729 if (ret
== OMX_ErrorCorruptedFrame
) {
730 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
732 codecBuffer
= pSrcInputData
->pPrivate
;
733 if (codecBuffer
!= NULL
)
734 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
737 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
738 Exynos_OMX_InputBufferReturn(pOMXComponent
, pSrcInputData
->bufferHeader
);
742 if (ret
!= OMX_ErrorInputDataDecodeYet
) {
743 Exynos_ResetCodecData(pSrcInputData
);
745 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
746 if (ret
== OMX_ErrorCodecInit
)
747 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
758 OMX_ERRORTYPE
Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent
)
760 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
761 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
762 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
763 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
764 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
765 EXYNOS_OMX_DATABUFFER
*srcOutputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
766 EXYNOS_OMX_DATA srcOutputData
;
770 while (!pVideoDec
->bExitBufferProcessThread
) {
771 Exynos_OSAL_SleepMillisec(0);
773 while (!pVideoDec
->bExitBufferProcessThread
) {
774 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
775 if (Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
) == OMX_FALSE
)
778 Exynos_OSAL_SleepMillisec(0);
780 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
783 Exynos_OSAL_MutexLock(srcOutputUseBuffer
->bufferMutex
);
784 ret
= pVideoDec
->exynos_codec_srcOutputProcess(pOMXComponent
, &srcOutputData
);
786 if (ret
== OMX_ErrorNone
) {
787 if (exynosInputPort
->bufferProcessType
& BUFFER_COPY
) {
789 codecBuffer
= srcOutputData
.pPrivate
;
790 if (codecBuffer
!= NULL
)
791 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
793 if (exynosInputPort
->bufferProcessType
& BUFFER_SHARE
) {
794 Exynos_Shared_DataToBuffer(&srcOutputData
, srcOutputUseBuffer
);
795 Exynos_InputBufferReturn(pOMXComponent
, srcOutputUseBuffer
);
797 Exynos_ResetCodecData(&srcOutputData
);
799 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer
->bufferMutex
);
810 OMX_ERRORTYPE
Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent
)
812 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
813 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
814 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
815 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
816 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
817 EXYNOS_OMX_DATABUFFER
*dstInputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
818 EXYNOS_OMX_DATA dstInputData
;
822 while (!pVideoDec
->bExitBufferProcessThread
) {
823 Exynos_OSAL_SleepMillisec(0);
825 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
826 (!pVideoDec
->bExitBufferProcessThread
)) {
827 Exynos_OSAL_SleepMillisec(0);
829 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) ||
830 (!CHECK_PORT_POPULATED(exynosOutputPort
)))
832 if (exynosOutputPort
->portState
!= OMX_StateIdle
)
835 Exynos_OSAL_MutexLock(dstInputUseBuffer
->bufferMutex
);
836 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
837 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
838 CODEC_DEC_BUFFER
*pCodecBuffer
= NULL
;
839 ret
= Exynos_CodecBufferDeQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, (OMX_PTR
*)&pCodecBuffer
);
840 if (ret
!= OMX_ErrorNone
) {
841 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
844 Exynos_Output_CodecBufferToData(pCodecBuffer
, &dstInputData
);
847 if (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
) {
848 if ((dstInputUseBuffer
->dataValid
!= OMX_TRUE
) &&
849 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
850 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
851 if (ret
!= OMX_ErrorNone
) {
852 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
855 if (exynosOutputPort
->bIsANBEnabled
== OMX_FALSE
) {
856 Exynos_Shared_BufferToData(dstInputUseBuffer
, &dstInputData
, TWO_PLANE
);
858 ret
= Exynos_Shared_ANBBufferToData(dstInputUseBuffer
, &dstInputData
, exynosOutputPort
, TWO_PLANE
);
859 if (ret
!= OMX_ErrorNone
) {
860 dstInputUseBuffer
->dataValid
= OMX_FALSE
;
861 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
865 Exynos_ResetDataBuffer(dstInputUseBuffer
);
869 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
870 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
875 ret
= pVideoDec
->exynos_codec_dstInputProcess(pOMXComponent
, &dstInputData
);
876 if (ret
!= OMX_ErrorOutputBufferUseYet
) {
877 Exynos_ResetCodecData(&dstInputData
);
879 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
890 OMX_ERRORTYPE
Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent
)
892 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
893 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
894 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
895 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
896 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
897 EXYNOS_OMX_DATABUFFER
*dstOutputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
898 EXYNOS_OMX_DATA
*pDstOutputData
= &exynosOutputPort
->processData
;
902 while (!pVideoDec
->bExitBufferProcessThread
) {
903 Exynos_OSAL_SleepMillisec(0);
904 Exynos_Wait_ProcessPause(pExynosComponent
, OUTPUT_PORT_INDEX
);
906 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
907 (!pVideoDec
->bExitBufferProcessThread
)) {
908 Exynos_OSAL_SleepMillisec(0);
910 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))
913 Exynos_OSAL_MutexLock(dstOutputUseBuffer
->bufferMutex
);
914 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
915 if ((dstOutputUseBuffer
->dataValid
!= OMX_TRUE
) &&
916 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
917 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
918 if (ret
!= OMX_ErrorNone
) {
919 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
925 if ((dstOutputUseBuffer
->dataValid
== OMX_TRUE
) ||
926 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
))
927 ret
= pVideoDec
->exynos_codec_dstOutputProcess(pOMXComponent
, pDstOutputData
);
929 if (((ret
== OMX_ErrorNone
) && (dstOutputUseBuffer
->dataValid
== OMX_TRUE
)) ||
930 (exynosOutputPort
->bufferProcessType
& BUFFER_SHARE
)) {
931 Exynos_Postprocess_OutputData(pOMXComponent
, pDstOutputData
);
934 if (exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) {
935 if (pDstOutputData
->pPrivate
!= NULL
) {
936 Exynos_CodecBufferEnQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, pDstOutputData
->pPrivate
);
937 pDstOutputData
->pPrivate
= NULL
;
941 /* reset outputData */
942 Exynos_ResetCodecData(pDstOutputData
);
943 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
954 static OMX_ERRORTYPE
Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData
)
956 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
957 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
958 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
959 EXYNOS_OMX_MESSAGE
*message
= NULL
;
963 if (threadData
== NULL
) {
964 ret
= OMX_ErrorBadParameter
;
967 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
968 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
969 if (ret
!= OMX_ErrorNone
) {
972 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
973 Exynos_OMX_SrcInputBufferProcess(pOMXComponent
);
975 Exynos_OSAL_ThreadExit(NULL
);
983 static OMX_ERRORTYPE
Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData
)
985 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
986 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
987 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
988 EXYNOS_OMX_MESSAGE
*message
= NULL
;
992 if (threadData
== NULL
) {
993 ret
= OMX_ErrorBadParameter
;
996 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
997 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
998 if (ret
!= OMX_ErrorNone
) {
1001 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1002 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent
);
1004 Exynos_OSAL_ThreadExit(NULL
);
1012 static OMX_ERRORTYPE
Exynos_OMX_DstInputProcessThread(OMX_PTR threadData
)
1014 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1015 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1016 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1017 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1021 if (threadData
== NULL
) {
1022 ret
= OMX_ErrorBadParameter
;
1025 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1026 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1027 if (ret
!= OMX_ErrorNone
) {
1030 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1031 Exynos_OMX_DstInputBufferProcess(pOMXComponent
);
1033 Exynos_OSAL_ThreadExit(NULL
);
1041 static OMX_ERRORTYPE
Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData
)
1043 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1044 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1045 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1046 EXYNOS_OMX_MESSAGE
*message
= NULL
;
1050 if (threadData
== NULL
) {
1051 ret
= OMX_ErrorBadParameter
;
1054 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
1055 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1056 if (ret
!= OMX_ErrorNone
) {
1059 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1060 Exynos_OMX_DstOutputBufferProcess(pOMXComponent
);
1062 Exynos_OSAL_ThreadExit(NULL
);
1070 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent
)
1072 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1073 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1074 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1075 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1079 pVideoDec
->bExitBufferProcessThread
= OMX_FALSE
;
1081 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstOutputThread
,
1082 Exynos_OMX_DstOutputProcessThread
,
1084 if (ret
== OMX_ErrorNone
)
1085 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcOutputThread
,
1086 Exynos_OMX_SrcOutputProcessThread
,
1088 if (ret
== OMX_ErrorNone
)
1089 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hDstInputThread
,
1090 Exynos_OMX_DstInputProcessThread
,
1092 if (ret
== OMX_ErrorNone
)
1093 ret
= Exynos_OSAL_ThreadCreate(&pVideoDec
->hSrcInputThread
,
1094 Exynos_OMX_SrcInputProcessThread
,
1103 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent
)
1105 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1106 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1107 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1108 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1109 OMX_S32 countValue
= 0;
1114 pVideoDec
->bExitBufferProcessThread
= OMX_TRUE
;
1116 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1117 if (countValue
== 0)
1118 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
);
1119 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
, &countValue
);
1120 if (countValue
== 0)
1121 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
);
1122 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1123 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcInputThread
);
1124 pVideoDec
->hSrcInputThread
= NULL
;
1126 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1127 if (countValue
== 0)
1128 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
);
1129 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
, &countValue
);
1130 if (countValue
== 0)
1131 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
);
1132 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1133 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstInputThread
);
1134 pVideoDec
->hDstInputThread
= NULL
;
1136 pVideoDec
->exynos_codec_stop(pOMXComponent
, INPUT_PORT_INDEX
);
1137 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1138 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1139 Exynos_OSAL_ThreadTerminate(pVideoDec
->hSrcOutputThread
);
1140 pVideoDec
->hSrcOutputThread
= NULL
;
1142 pVideoDec
->exynos_codec_stop(pOMXComponent
, OUTPUT_PORT_INDEX
);
1143 pVideoDec
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1144 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1145 Exynos_OSAL_ThreadTerminate(pVideoDec
->hDstOutputThread
);
1146 pVideoDec
->hDstOutputThread
= NULL
;
1154 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent
)
1156 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1157 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1158 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1159 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1160 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1164 if (hComponent
== NULL
) {
1165 ret
= OMX_ErrorBadParameter
;
1168 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1169 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1170 if (ret
!= OMX_ErrorNone
) {
1171 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1175 ret
= Exynos_OMX_BaseComponent_Constructor(pOMXComponent
);
1176 if (ret
!= OMX_ErrorNone
) {
1177 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1181 ret
= Exynos_OMX_Port_Constructor(pOMXComponent
);
1182 if (ret
!= OMX_ErrorNone
) {
1183 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1184 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1188 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1190 pVideoDec
= Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1191 if (pVideoDec
== NULL
) {
1192 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1193 ret
= OMX_ErrorInsufficientResources
;
1194 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1198 Exynos_OSAL_Memset(pVideoDec
, 0, sizeof(EXYNOS_OMX_VIDEODEC_COMPONENT
));
1199 pVideoDec
->bReconfigDPB
= OMX_FALSE
;
1200 pVideoDec
->nSavedDPBCnt
= 0;
1201 pExynosComponent
->hComponentHandle
= (OMX_HANDLETYPE
)pVideoDec
;
1203 pExynosComponent
->bSaveFlagEOS
= OMX_FALSE
;
1204 pExynosComponent
->bMultiThreadProcess
= OMX_TRUE
;
1207 pExynosPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
1208 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_INPUTBUFFER_NUM
;
1209 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_INPUTBUFFER_NUM
;
1210 pExynosPort
->portDefinition
.nBufferSize
= 0;
1211 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1213 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1214 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1215 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1216 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1217 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1219 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1220 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1221 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1222 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1223 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1224 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1225 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1226 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1229 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1230 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1231 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1232 pExynosPort
->portDefinition
.nBufferSize
= DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE
;
1233 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1235 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1236 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1237 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1238 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1239 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1241 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1242 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1243 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1244 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1245 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1246 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1247 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1248 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1250 pExynosPort
->processData
.extInfo
= (OMX_PTR
)Exynos_OSAL_Malloc(sizeof(DECODE_CODEC_EXTRA_BUFFERINFO
));
1252 pOMXComponent
->UseBuffer
= &Exynos_OMX_UseBuffer
;
1253 pOMXComponent
->AllocateBuffer
= &Exynos_OMX_AllocateBuffer
;
1254 pOMXComponent
->FreeBuffer
= &Exynos_OMX_FreeBuffer
;
1255 pOMXComponent
->ComponentTunnelRequest
= &Exynos_OMX_ComponentTunnelRequest
;
1257 pExynosComponent
->exynos_AllocateTunnelBuffer
= &Exynos_OMX_AllocateTunnelBuffer
;
1258 pExynosComponent
->exynos_FreeTunnelBuffer
= &Exynos_OMX_FreeTunnelBuffer
;
1259 pExynosComponent
->exynos_BufferProcessCreate
= &Exynos_OMX_BufferProcess_Create
;
1260 pExynosComponent
->exynos_BufferProcessTerminate
= &Exynos_OMX_BufferProcess_Terminate
;
1261 pExynosComponent
->exynos_BufferFlush
= &Exynos_OMX_BufferFlush
;
1269 OMX_ERRORTYPE
Exynos_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent
)
1271 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1272 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1273 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1274 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1275 EXYNOS_OMX_VIDEODEC_COMPONENT
*pVideoDec
= NULL
;
1280 if (hComponent
== NULL
) {
1281 ret
= OMX_ErrorBadParameter
;
1284 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1285 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1286 if (ret
!= OMX_ErrorNone
) {
1290 if (pOMXComponent
->pComponentPrivate
== NULL
) {
1291 ret
= OMX_ErrorBadParameter
;
1294 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1296 pVideoDec
= (EXYNOS_OMX_VIDEODEC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1298 Exynos_OSAL_Free(pVideoDec
);
1299 pExynosComponent
->hComponentHandle
= pVideoDec
= NULL
;
1301 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1302 if (pExynosPort
->processData
.extInfo
!= NULL
) {
1303 Exynos_OSAL_Free(pExynosPort
->processData
.extInfo
);
1304 pExynosPort
->processData
.extInfo
= NULL
;
1307 for(i
= 0; i
< ALL_PORT_NUM
; i
++) {
1308 pExynosPort
= &pExynosComponent
->pExynosPort
[i
];
1309 Exynos_OSAL_Free(pExynosPort
->portDefinition
.format
.video
.cMIMEType
);
1310 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= NULL
;
1313 ret
= Exynos_OMX_Port_Destructor(pOMXComponent
);
1315 ret
= Exynos_OMX_BaseComponent_Destructor(hComponent
);