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_Venc.c
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * Yunji Kim (yunji.kim@samsung.com)
31 #include "Exynos_OMX_Macros.h"
32 #include "Exynos_OSAL_Event.h"
33 #include "Exynos_OMX_Venc.h"
34 #include "Exynos_OMX_VencControl.h"
35 #include "Exynos_OMX_Basecomponent.h"
36 #include "Exynos_OSAL_Thread.h"
37 #include "Exynos_OSAL_Semaphore.h"
38 #include "Exynos_OSAL_SharedMemory.h"
39 #include "Exynos_OSAL_Mutex.h"
40 #include "Exynos_OSAL_ETC.h"
43 #ifdef USE_STOREMETADATA
44 #include <system/window.h>
45 #include "Exynos_OSAL_Android.h"
49 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENC"
50 #define EXYNOS_LOG_OFF
51 //#define EXYNOS_TRACE_ON
52 #include "Exynos_OSAL_Log.h"
55 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE
*pOMXComponent
)
57 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
58 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
59 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
61 if ((exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
!=
62 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
) ||
63 (exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
!=
64 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
)) {
65 OMX_U32 width
= 0, height
= 0;
67 exynosOutputPort
->portDefinition
.format
.video
.nFrameWidth
=
68 exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
;
69 exynosOutputPort
->portDefinition
.format
.video
.nFrameHeight
=
70 exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
;
71 width
= exynosOutputPort
->portDefinition
.format
.video
.nStride
=
72 exynosInputPort
->portDefinition
.format
.video
.nStride
;
73 height
= exynosOutputPort
->portDefinition
.format
.video
.nSliceHeight
=
74 exynosInputPort
->portDefinition
.format
.video
.nSliceHeight
;
77 exynosOutputPort
->portDefinition
.nBufferSize
= (width
* height
* 3) / 2;
83 OMX_BOOL
Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
85 OMX_BOOL ret
= OMX_FALSE
;
87 if ((pExynosComponent
->currentState
== OMX_StateExecuting
) &&
88 (pExynosComponent
->pExynosPort
[nPortIndex
].portState
== OMX_StateIdle
) &&
89 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateExecutingToIdle
) &&
90 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToExecuting
)) {
99 OMX_ERRORTYPE
Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_PTR codecBuffer
, EXYNOS_OMX_DATA
*pData
)
101 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
102 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
103 CODEC_ENC_BUFFER
*pInputCodecBuffer
= (CODEC_ENC_BUFFER
*)codecBuffer
;
105 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] = pInputCodecBuffer
->pVirAddr
[0];
106 pData
->buffer
.multiPlaneBuffer
.dataBuffer
[1] = pInputCodecBuffer
->pVirAddr
[1];
107 pData
->buffer
.multiPlaneBuffer
.fd
[0] = pInputCodecBuffer
->fd
[0];
108 pData
->buffer
.multiPlaneBuffer
.fd
[1] = pInputCodecBuffer
->fd
[1];
109 pData
->allocSize
= pInputCodecBuffer
->bufferSize
[0] + pInputCodecBuffer
->bufferSize
[1];
110 pData
->dataLen
= pInputCodecBuffer
->dataSize
;
111 pData
->usedDataLen
= 0;
112 pData
->remainDataLen
= pInputCodecBuffer
->dataSize
;
115 pData
->timeStamp
= 0;
116 pData
->pPrivate
= codecBuffer
;
117 pData
->bufferHeader
= NULL
;
122 OMX_ERRORTYPE
Exynos_Output_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_PTR codecBuffer
, EXYNOS_OMX_DATA
*pData
)
124 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
125 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
129 pVideoEnc
->exynos_codec_getCodecOutputPrivateData(codecBuffer
, &pSrcBuf
, &allocSize
);
130 pData
->buffer
.singlePlaneBuffer
.dataBuffer
= pSrcBuf
;
131 pData
->allocSize
= allocSize
;
133 pData
->usedDataLen
= 0;
134 pData
->remainDataLen
= 0;
137 pData
->timeStamp
= 0;
138 pData
->pPrivate
= codecBuffer
;
139 pData
->bufferHeader
= NULL
;
144 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
, OMX_U32 nPortIndex
)
146 EXYNOS_OMX_BASEPORT
*exynosOMXInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
147 EXYNOS_OMX_BASEPORT
*exynosOMXOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
148 EXYNOS_OMX_BASEPORT
*exynosOMXPort
= NULL
;
152 exynosOMXPort
= &pExynosComponent
->pExynosPort
[nPortIndex
];
154 if (((pExynosComponent
->currentState
== OMX_StatePause
) ||
155 (pExynosComponent
->currentState
== OMX_StateIdle
) ||
156 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateLoadedToIdle
) ||
157 (pExynosComponent
->transientState
== EXYNOS_OMX_TransStateExecutingToIdle
)) &&
158 (pExynosComponent
->transientState
!= EXYNOS_OMX_TransStateIdleToLoaded
) &&
159 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort
))) {
160 Exynos_OSAL_SignalWait(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
, DEF_MAX_WAIT_TIME
);
161 Exynos_OSAL_SignalReset(pExynosComponent
->pExynosPort
[nPortIndex
].pauseEvent
);
169 OMX_BOOL
Exynos_CSC_InputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*srcInputData
)
171 OMX_BOOL ret
= OMX_FALSE
;
172 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
173 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
174 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
175 EXYNOS_OMX_DATABUFFER
*inputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
176 OMX_U32 nFrameWidth
= exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
;
177 OMX_U32 nFrameHeight
= exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
;
178 OMX_COLOR_FORMATTYPE eColorFormat
= exynosInputPort
->portDefinition
.format
.video
.eColorFormat
;
179 OMX_BYTE checkInputStream
= NULL
;
180 OMX_BOOL flagEOS
= OMX_FALSE
;
184 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
;
186 CODEC_ENC_BUFFER
*codecInputBuffer
= (CODEC_ENC_BUFFER
*)srcInputData
->pPrivate
;
187 codecInputBuffer
->dataSize
= ((nFrameWidth
* nFrameHeight
) * 3) / 2;
189 unsigned int csc_src_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
190 unsigned int csc_dst_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
191 CSC_METHOD csc_method
= CSC_METHOD_SW
;
192 unsigned int cacheable
= 1;
194 void *pSrcBuf
[3] = {NULL
, };
195 void *pSrcFd
[3] = {NULL
, };
196 void *pDstBuf
[3] = {NULL
, };
197 void *pDstFd
[3] = {NULL
, };
199 CSC_ERRORCODE cscRet
= CSC_ErrorNone
;
201 pSrcBuf
[0] = checkInputStream
;
202 pSrcBuf
[1] = checkInputStream
+ (nFrameWidth
* nFrameHeight
);
203 pSrcBuf
[2] = checkInputStream
+ (((nFrameWidth
* nFrameHeight
) * 5) / 4);
205 pDstBuf
[0] = srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[0];
206 pDstBuf
[1] = srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[1];
207 pDstBuf
[2] = srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[2];
209 #ifdef USE_METADATABUFFERTYPE
210 OMX_PTR ppBuf
[MAX_BUFFER_PLANE
];
212 /* kMetadataBufferTypeGrallocSource */
213 if (exynosInputPort
->bStoreMetaData
== OMX_TRUE
) {
214 /* ARGB8888 converted to YUV420SemiPlanar */
215 csc_src_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888
);
216 csc_dst_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
218 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE
)inputUseBuffer
->bufferHeader
->pBuffer
, ppBuf
);
219 if (eColorFormat
== OMX_COLOR_FormatAndroidOpaque
) {
220 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
223 Exynos_OSAL_LockANBHandle((OMX_U32
)ppBuf
[0], nFrameWidth
, nFrameHeight
, OMX_COLOR_FormatAndroidOpaque
, planes
);
225 #ifdef USE_CSC_GSCALER
226 csc_method
= CSC_METHOD_HW
;
228 pSrcBuf
[0] = planes
[0].addr
;
229 pSrcFd
[0] = (void *)planes
[0].fd
;
230 for (i
= 0; i
< 3; i
++)
231 pDstFd
[i
] = (void *)srcInputData
->buffer
.multiPlaneBuffer
.fd
[i
];
236 switch (eColorFormat
) {
237 case OMX_COLOR_FormatYUV420Planar
:
238 /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/
239 csc_src_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar
);
240 csc_dst_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
242 case OMX_COLOR_FormatYUV420SemiPlanar
:
243 case OMX_SEC_COLOR_FormatNV12Tiled
:
244 case OMX_SEC_COLOR_FormatNV21Linear
:
245 /* Just copied to MFC input buffer */
246 csc_src_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
247 csc_dst_color_format
= omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar
);
255 pVideoEnc
->csc_handle
,
258 pVideoEnc
->csc_handle
, /* handle */
259 nFrameWidth
, /* width */
260 nFrameHeight
, /* height */
263 nFrameWidth
, /* crop_width */
264 nFrameHeight
, /* crop_height */
265 csc_src_color_format
, /* color_format */
266 cacheable
); /* cacheable */
268 pVideoEnc
->csc_handle
, /* handle */
269 nFrameWidth
, /* width */
270 nFrameHeight
, /* height */
273 nFrameWidth
, /* crop_width */
274 nFrameHeight
, /* crop_height */
275 csc_dst_color_format
, /* color_format */
276 cacheable
); /* cacheable */
277 if (csc_method
== CSC_METHOD_SW
) {
279 pVideoEnc
->csc_handle
, /* handle */
282 pVideoEnc
->csc_handle
, /* handle */
286 pVideoEnc
->csc_handle
, /* handle */
289 pVideoEnc
->csc_handle
, /* handle */
292 cscRet
= csc_convert(pVideoEnc
->csc_handle
);
293 if (cscRet
!= CSC_ErrorNone
)
298 #ifdef USE_METADATABUFFERTYPE
299 if (exynosInputPort
->bStoreMetaData
== OMX_TRUE
) {
300 Exynos_OSAL_UnlockANBHandle((OMX_U32
)ppBuf
[0]);
310 OMX_BOOL
Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*srcInputData
)
312 OMX_BOOL ret
= OMX_FALSE
;
313 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
314 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
315 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
316 EXYNOS_OMX_DATABUFFER
*inputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
317 OMX_U32 nFrameWidth
= exynosInputPort
->portDefinition
.format
.video
.nFrameWidth
;
318 OMX_U32 nFrameHeight
= exynosInputPort
->portDefinition
.format
.video
.nFrameHeight
;
319 OMX_COLOR_FORMATTYPE eColorFormat
= exynosInputPort
->portDefinition
.format
.video
.eColorFormat
;
320 OMX_U32 copySize
= 0;
321 OMX_BYTE checkInputStream
= NULL
;
322 OMX_U32 checkInputStreamLen
= 0;
323 OMX_BOOL flagEOS
= OMX_FALSE
;
327 if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
328 if ((srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] == NULL
) ||
329 (srcInputData
->pPrivate
== NULL
)) {
335 if (inputUseBuffer
->dataValid
== OMX_TRUE
) {
336 if (exynosInputPort
->bufferProcessType
== BUFFER_SHARE
) {
337 Exynos_Shared_BufferToData(inputUseBuffer
, srcInputData
, ONE_PLANE
);
338 #ifdef USE_METADATABUFFERTYPE
339 if (exynosInputPort
->bStoreMetaData
== OMX_TRUE
) {
340 OMX_PTR ppBuf
[MAX_BUFFER_PLANE
];
341 OMX_PTR allocSize
[MAX_BUFFER_PLANE
];
343 if (eColorFormat
== OMX_COLOR_FormatAndroidOpaque
) {
344 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE
)inputUseBuffer
->bufferHeader
->pBuffer
, ppBuf
);
345 ExynosVideoPlane planes
[MAX_BUFFER_PLANE
];
347 Exynos_OSAL_LockANBHandle((OMX_U32
)ppBuf
[0], nFrameWidth
, nFrameHeight
, OMX_COLOR_FormatYUV420SemiPlanar
, planes
);
349 srcInputData
->buffer
.multiPlaneBuffer
.fd
[0] = planes
[0].fd
;
350 srcInputData
->buffer
.multiPlaneBuffer
.fd
[1] = planes
[1].fd
;
351 allocSize
[0] = nFrameWidth
* nFrameHeight
;
352 allocSize
[1] = nFrameWidth
* nFrameHeight
>> 1;
354 for (plane
= 0; plane
< MFC_INPUT_BUFFER_PLANE
; plane
++) {
355 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] =
356 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc
->hSharedMemory
, srcInputData
->buffer
.multiPlaneBuffer
.fd
[plane
]);
357 if(srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] == NULL
) {
358 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] =
359 Exynos_OSAL_SharedMemory_Map(pVideoEnc
->hSharedMemory
, allocSize
[plane
], srcInputData
->buffer
.multiPlaneBuffer
.fd
[plane
]);
362 /* input buffers are 2 plane. */
363 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[2] = NULL
;
364 srcInputData
->buffer
.multiPlaneBuffer
.fd
[2] = -1;
365 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__
, __LINE__
, (unsigned int)ppBuf
[0], (unsigned int)ppBuf
[0]);
367 /* kMetadataBufferTypeCameraSource */
368 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE
)inputUseBuffer
->bufferHeader
->pBuffer
, ppBuf
);
369 srcInputData
->buffer
.multiPlaneBuffer
.fd
[0] = ppBuf
[0];
370 srcInputData
->buffer
.multiPlaneBuffer
.fd
[1] = ppBuf
[1];
371 allocSize
[0] = nFrameWidth
* nFrameHeight
;
372 allocSize
[1] = nFrameWidth
* nFrameHeight
>> 1;
374 for (plane
= 0; plane
< MFC_INPUT_BUFFER_PLANE
; plane
++) {
375 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] =
376 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc
->hSharedMemory
, srcInputData
->buffer
.multiPlaneBuffer
.fd
[plane
]);
377 if(srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] == NULL
) {
378 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[plane
] =
379 Exynos_OSAL_SharedMemory_Map(pVideoEnc
->hSharedMemory
, allocSize
[plane
], srcInputData
->buffer
.multiPlaneBuffer
.fd
[plane
]);
382 /* input buffers are 2 plane. */
383 srcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[2] = NULL
;
384 srcInputData
->buffer
.multiPlaneBuffer
.fd
[2] = -1;
385 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__
, __LINE__
, (unsigned int)ppBuf
[0], (unsigned int)ppBuf
[0]);
389 /* reset dataBuffer */
390 Exynos_ResetDataBuffer(inputUseBuffer
);
391 } else if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
392 checkInputStream
= inputUseBuffer
->bufferHeader
->pBuffer
+ inputUseBuffer
->usedDataLen
;
393 checkInputStreamLen
= inputUseBuffer
->remainDataLen
;
395 pExynosComponent
->bUseFlagEOF
= OMX_TRUE
;
397 if (checkInputStreamLen
== 0) {
398 inputUseBuffer
->nFlags
|= OMX_BUFFERFLAG_EOS
;
402 copySize
= checkInputStreamLen
;
403 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "exynos_checkInputFrame : OMX_TRUE");
405 if (((srcInputData
->allocSize
) - (srcInputData
->dataLen
)) >= copySize
) {
406 ret
= Exynos_CSC_InputData(pOMXComponent
, srcInputData
);
408 inputUseBuffer
->dataLen
-= copySize
;
409 inputUseBuffer
->remainDataLen
-= copySize
;
410 inputUseBuffer
->usedDataLen
+= copySize
;
412 srcInputData
->dataLen
+= copySize
;
413 srcInputData
->remainDataLen
+= copySize
;
415 srcInputData
->timeStamp
= inputUseBuffer
->timeStamp
;
416 srcInputData
->nFlags
= inputUseBuffer
->nFlags
;
417 srcInputData
->bufferHeader
= inputUseBuffer
->bufferHeader
;
419 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Exynos_CSC_InputData() failure");
420 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
421 pExynosComponent
->callbackData
, OMX_EventError
,
422 OMX_ErrorUndefined
, 0, NULL
);
425 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "input codec buffer is smaller than decoded input data size Out Length");
426 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
427 pExynosComponent
->callbackData
,
428 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
432 if (((exynosInputPort
->bStoreMetaData
== OMX_TRUE
) && (eColorFormat
== OMX_COLOR_FormatAndroidOpaque
)) ||
433 (exynosInputPort
->bStoreMetaData
== OMX_FALSE
)) {
434 Exynos_InputBufferReturn(pOMXComponent
);
436 inputUseBuffer
->dataValid
= OMX_TRUE
;
440 if ((srcInputData
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) {
441 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "bSaveFlagEOS : OMX_TRUE");
442 srcInputData
->dataLen
= 0;
443 srcInputData
->remainDataLen
= 0;
444 pExynosComponent
->bSaveFlagEOS
= OMX_TRUE
;
447 if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
448 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_TRUE
;
449 pExynosComponent
->checkTimeStamp
.startTimeStamp
= srcInputData
->timeStamp
;
450 pExynosComponent
->checkTimeStamp
.nStartFlags
= srcInputData
->nFlags
;
451 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
452 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "first frame timestamp after seeking %lld us (%.2f secs)",
453 srcInputData
->timeStamp
, srcInputData
->timeStamp
/ 1E6
);
466 OMX_BOOL
Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE
*pOMXComponent
, EXYNOS_OMX_DATA
*dstOutputData
)
468 OMX_BOOL ret
= OMX_FALSE
;
469 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
470 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
471 EXYNOS_OMX_DATABUFFER
*outputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
472 OMX_U32 copySize
= 0;
476 if (exynosOutputPort
->bufferProcessType
== BUFFER_SHARE
) {
477 if (Exynos_Shared_DataToBuffer(dstOutputData
, outputUseBuffer
) == OMX_ErrorNone
)
478 outputUseBuffer
->dataValid
= OMX_TRUE
;
481 if (outputUseBuffer
->dataValid
== OMX_TRUE
) {
482 if (pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
== OMX_TRUE
) {
483 if (pExynosComponent
->checkTimeStamp
.startTimeStamp
== dstOutputData
->timeStamp
){
484 pExynosComponent
->checkTimeStamp
.startTimeStamp
= -19761123;
485 pExynosComponent
->checkTimeStamp
.nStartFlags
= 0x0;
486 pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
= OMX_FALSE
;
487 pExynosComponent
->checkTimeStamp
.needCheckStartTimeStamp
= OMX_FALSE
;
489 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "garbage frame drop after flush");
493 } else if (pExynosComponent
->checkTimeStamp
.needSetStartTimeStamp
== OMX_TRUE
) {
495 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "input buffer has not come after flush.");
499 if ((exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
500 if (dstOutputData
->remainDataLen
<= (outputUseBuffer
->allocSize
- outputUseBuffer
->dataLen
)) {
501 copySize
= dstOutputData
->remainDataLen
;
503 Exynos_OSAL_Memcpy((outputUseBuffer
->bufferHeader
->pBuffer
+ outputUseBuffer
->dataLen
),
504 (dstOutputData
->buffer
.singlePlaneBuffer
.dataBuffer
+ dstOutputData
->usedDataLen
),
506 outputUseBuffer
->dataLen
+= copySize
;
507 outputUseBuffer
->remainDataLen
+= copySize
;
508 outputUseBuffer
->nFlags
= dstOutputData
->nFlags
;
509 outputUseBuffer
->timeStamp
= dstOutputData
->timeStamp
;
513 if ((outputUseBuffer
->remainDataLen
> 0) ||
514 (outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
)) {
515 Exynos_OutputBufferReturn(pOMXComponent
);
518 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "output buffer is smaller than encoded data size Out Length");
519 pExynosComponent
->pCallbacks
->EventHandler((OMX_HANDLETYPE
)pOMXComponent
,
520 pExynosComponent
->callbackData
,
521 OMX_EventError
, OMX_ErrorUndefined
, 0, NULL
);
524 } else if (exynosOutputPort
->bufferProcessType
== BUFFER_SHARE
) {
525 if ((outputUseBuffer
->remainDataLen
> 0) ||
526 ((outputUseBuffer
->nFlags
& OMX_BUFFERFLAG_EOS
) == OMX_BUFFERFLAG_EOS
) ||
527 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)))
528 Exynos_OutputBufferReturn(pOMXComponent
);
540 #ifdef USE_METADATABUFFERTYPE
541 OMX_ERRORTYPE
Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent
)
543 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
544 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
545 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
546 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
547 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
548 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
549 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
550 OMX_COLOR_FORMATTYPE eColorFormat
= exynosInputPort
->portDefinition
.format
.video
.eColorFormat
;
553 OMX_PTR ppBuf
[MAX_BUFFER_PLANE
];
556 /* kMetadataBufferTypeGrallocSource */
557 if (exynosInputPort
->bStoreMetaData
== OMX_TRUE
) {
558 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE
)srcInputUseBuffer
->bufferHeader
->pBuffer
, ppBuf
);
559 if (eColorFormat
== OMX_COLOR_FormatAndroidOpaque
) {
560 pVideoEnc
->ANBColorFormat
= Exynos_OSAL_GetANBColorFormat(ppBuf
[0]);
561 if ((pVideoEnc
->ANBColorFormat
== OMX_COLOR_FormatYUV420SemiPlanar
) ||
562 (pVideoEnc
->ANBColorFormat
== OMX_SEC_COLOR_FormatNV12Tiled
)) {
563 exynosInputPort
->bufferProcessType
= BUFFER_SHARE
;
565 exynosInputPort
->bufferProcessType
= BUFFER_COPY
;
568 if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
569 Exynos_OSAL_SemaphoreCreate(&exynosInputPort
->codecSemID
);
570 Exynos_OSAL_QueueCreate(&exynosInputPort
->codecBufferQ
, MAX_QUEUE_ELEMENTS
);
572 for (i
= 0; i
< MFC_INPUT_BUFFER_NUM_MAX
; i
++) {
573 pVideoEnc
->pMFCEncInputBuffer
[i
] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER
));
574 /* Use ION Allocator */
576 pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc
->hSharedMemory
, DEFAULT_MFC_INPUT_YBUFFER_SIZE
, NORMAL_MEMORY
);
577 pVideoEnc
->pMFCEncInputBuffer
[i
]->fd
[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc
->hSharedMemory
, pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[0]);
578 pVideoEnc
->pMFCEncInputBuffer
[i
]->bufferSize
[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE
;
580 pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc
->hSharedMemory
, DEFAULT_MFC_INPUT_CBUFFER_SIZE
, NORMAL_MEMORY
);
581 pVideoEnc
->pMFCEncInputBuffer
[i
]->fd
[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc
->hSharedMemory
, pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[1]);
582 pVideoEnc
->pMFCEncInputBuffer
[i
]->bufferSize
[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE
;
584 pVideoEnc
->pMFCEncInputBuffer
[i
]->dataSize
= 0;
586 if ((pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[0] == NULL
) ||
587 (pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[1] == NULL
)) {
588 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "Fail input buffer");
589 ret
= OMX_ErrorInsufficientResources
;
593 /* MFC input buffers are 1 plane. */
594 pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[2] = NULL
;
595 pVideoEnc
->pMFCEncInputBuffer
[i
]->fd
[2] = -1;
596 pVideoEnc
->pMFCEncInputBuffer
[i
]->bufferSize
[2] = 0;
598 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i
, pVideoEnc
->pMFCEncInputBuffer
[i
]);
599 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i
, pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[0]);
600 Exynos_OSAL_Log(EXYNOS_LOG_TRACE
, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i
, pVideoEnc
->pMFCEncInputBuffer
[i
]->pVirAddr
[1]);
602 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, pVideoEnc
->pMFCEncInputBuffer
[i
]);
604 } else if (exynosInputPort
->bufferProcessType
== BUFFER_SHARE
) {
608 /* Does not require any actions. */
620 OMX_ERRORTYPE
Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent
)
622 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
623 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
624 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
625 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
626 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
627 EXYNOS_OMX_DATABUFFER
*srcInputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
628 EXYNOS_OMX_DATA
*pSrcInputData
= &exynosInputPort
->processData
;
629 OMX_BOOL bCheckInputData
= OMX_FALSE
;
630 OMX_BOOL bValidCodecData
= OMX_FALSE
;
634 while (!pVideoEnc
->bExitBufferProcessThread
) {
635 Exynos_OSAL_SleepMillisec(0);
636 Exynos_Wait_ProcessPause(pExynosComponent
, INPUT_PORT_INDEX
);
638 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
)) &&
639 (!pVideoEnc
->bExitBufferProcessThread
)) {
640 Exynos_OSAL_SleepMillisec(0);
642 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
644 if (exynosInputPort
->portState
!= OMX_StateIdle
)
647 Exynos_OSAL_MutexLock(srcInputUseBuffer
->bufferMutex
);
648 if (pVideoEnc
->bFirstInput
== OMX_FALSE
) {
649 if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
651 if ((pSrcInputData
->buffer
.multiPlaneBuffer
.dataBuffer
[0] == NULL
) || (pSrcInputData
->pPrivate
== NULL
)) {
652 Exynos_CodecBufferDeQueue(pExynosComponent
, INPUT_PORT_INDEX
, &codecBuffer
);
653 if (codecBuffer
!= NULL
) {
654 Exynos_Input_CodecBufferToData(pExynosComponent
, codecBuffer
, pSrcInputData
);
656 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
661 if (srcInputUseBuffer
->dataValid
== OMX_TRUE
) {
662 bCheckInputData
= Exynos_Preprocessor_InputData(pOMXComponent
, pSrcInputData
);
664 bCheckInputData
= OMX_FALSE
;
667 if ((bCheckInputData
== OMX_FALSE
) &&
668 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
669 ret
= Exynos_InputBufferGetQueue(pExynosComponent
);
670 #ifdef USE_METADATABUFFERTYPE
671 if ((pVideoEnc
->bFirstInput
== OMX_TRUE
) &&
672 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort
))) {
673 Exynos_OMX_ExtensionSetup(hComponent
);
674 pVideoEnc
->bFirstInput
= OMX_FALSE
;
677 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
681 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
)) {
682 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
686 ret
= pVideoEnc
->exynos_codec_srcInputProcess(pOMXComponent
, pSrcInputData
);
687 Exynos_ResetCodecData(pSrcInputData
);
688 Exynos_OSAL_MutexUnlock(srcInputUseBuffer
->bufferMutex
);
689 if (ret
== OMX_ErrorCodecInit
)
690 pVideoEnc
->bExitBufferProcessThread
= OMX_TRUE
;
701 OMX_ERRORTYPE
Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent
)
703 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
704 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
705 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
706 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
707 EXYNOS_OMX_BASEPORT
*exynosInputPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
708 EXYNOS_OMX_DATABUFFER
*srcOutputUseBuffer
= &exynosInputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
709 EXYNOS_OMX_DATA srcOutputData
;
713 while (!pVideoEnc
->bExitBufferProcessThread
) {
714 Exynos_OSAL_SleepMillisec(0);
716 while (!pVideoEnc
->bExitBufferProcessThread
) {
717 if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
718 if (Exynos_Check_BufferProcess_State(pExynosComponent
, INPUT_PORT_INDEX
) == OMX_FALSE
)
721 Exynos_OSAL_SleepMillisec(0);
723 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort
))
726 Exynos_OSAL_MutexLock(srcOutputUseBuffer
->bufferMutex
);
727 ret
= pVideoEnc
->exynos_codec_srcOutputProcess(pOMXComponent
, &srcOutputData
);
729 if (ret
== OMX_ErrorNone
) {
730 if ((exynosInputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
732 codecBuffer
= srcOutputData
.pPrivate
;
733 if (codecBuffer
!= NULL
)
734 Exynos_CodecBufferEnQueue(pExynosComponent
, INPUT_PORT_INDEX
, codecBuffer
);
736 if (exynosInputPort
->bufferProcessType
== BUFFER_SHARE
) {
737 Exynos_Shared_DataToBuffer(&srcOutputData
, srcOutputUseBuffer
);
738 Exynos_InputBufferReturn(pOMXComponent
);
740 Exynos_ResetCodecData(&srcOutputData
);
742 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer
->bufferMutex
);
753 OMX_ERRORTYPE
Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent
)
755 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
756 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
757 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
758 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
759 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
760 EXYNOS_OMX_DATABUFFER
*dstInputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.inputDataBuffer
;
761 EXYNOS_OMX_DATA dstInputData
;
765 while (!pVideoEnc
->bExitBufferProcessThread
) {
766 Exynos_OSAL_SleepMillisec(0);
768 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
769 (!pVideoEnc
->bExitBufferProcessThread
)) {
770 Exynos_OSAL_SleepMillisec(0);
772 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) ||
773 (!CHECK_PORT_POPULATED(exynosOutputPort
)))
775 if (exynosOutputPort
->portState
!= OMX_StateIdle
)
778 Exynos_OSAL_MutexLock(dstInputUseBuffer
->bufferMutex
);
779 if ((exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
781 ret
= Exynos_CodecBufferDeQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, &codecBuffer
);
782 if (ret
!= OMX_ErrorNone
) {
783 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
786 Exynos_Output_CodecBufferToData(pExynosComponent
, codecBuffer
, &dstInputData
);
789 if (exynosOutputPort
->bufferProcessType
== BUFFER_SHARE
) {
790 if ((dstInputUseBuffer
->dataValid
!= OMX_TRUE
) &&
791 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
792 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
793 if (ret
!= OMX_ErrorNone
) {
794 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
797 Exynos_Shared_BufferToData(dstInputUseBuffer
, &dstInputData
, ONE_PLANE
);
798 Exynos_ResetDataBuffer(dstInputUseBuffer
);
802 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
)) {
803 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
806 ret
= pVideoEnc
->exynos_codec_dstInputProcess(pOMXComponent
, &dstInputData
);
808 Exynos_ResetCodecData(&dstInputData
);
809 Exynos_OSAL_MutexUnlock(dstInputUseBuffer
->bufferMutex
);
820 OMX_ERRORTYPE
Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent
)
822 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
823 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
824 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
825 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
826 EXYNOS_OMX_BASEPORT
*exynosOutputPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
827 EXYNOS_OMX_DATABUFFER
*dstOutputUseBuffer
= &exynosOutputPort
->way
.port2WayDataBuffer
.outputDataBuffer
;
828 EXYNOS_OMX_DATA
*pDstOutputData
= &exynosOutputPort
->processData
;
832 while (!pVideoEnc
->bExitBufferProcessThread
) {
833 Exynos_OSAL_SleepMillisec(0);
834 Exynos_Wait_ProcessPause(pExynosComponent
, OUTPUT_PORT_INDEX
);
836 while ((Exynos_Check_BufferProcess_State(pExynosComponent
, OUTPUT_PORT_INDEX
)) &&
837 (!pVideoEnc
->bExitBufferProcessThread
)) {
838 Exynos_OSAL_SleepMillisec(0);
840 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))
843 Exynos_OSAL_MutexLock(dstOutputUseBuffer
->bufferMutex
);
844 if ((exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
845 if ((dstOutputUseBuffer
->dataValid
!= OMX_TRUE
) &&
846 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort
))) {
847 ret
= Exynos_OutputBufferGetQueue(pExynosComponent
);
848 if (ret
!= OMX_ErrorNone
) {
849 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
855 if ((dstOutputUseBuffer
->dataValid
== OMX_TRUE
) ||
856 (exynosOutputPort
->bufferProcessType
== BUFFER_SHARE
))
857 ret
= pVideoEnc
->exynos_codec_dstOutputProcess(pOMXComponent
, pDstOutputData
);
859 if (((ret
== OMX_ErrorNone
) && (dstOutputUseBuffer
->dataValid
== OMX_TRUE
)) ||
860 (exynosOutputPort
->bufferProcessType
== BUFFER_SHARE
)) {
861 Exynos_Postprocess_OutputData(pOMXComponent
, pDstOutputData
);
864 if ((exynosOutputPort
->bufferProcessType
& BUFFER_COPY
) == BUFFER_COPY
) {
866 codecBuffer
= pDstOutputData
->pPrivate
;
867 if (codecBuffer
!= NULL
) {
868 Exynos_CodecBufferEnQueue(pExynosComponent
, OUTPUT_PORT_INDEX
, codecBuffer
);
869 pDstOutputData
->pPrivate
= NULL
;
873 /* reset outputData */
874 Exynos_ResetCodecData(pDstOutputData
);
875 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer
->bufferMutex
);
886 static OMX_ERRORTYPE
Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData
)
888 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
889 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
890 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
891 EXYNOS_OMX_MESSAGE
*message
= NULL
;
895 if (threadData
== NULL
) {
896 ret
= OMX_ErrorBadParameter
;
899 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
900 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
901 if (ret
!= OMX_ErrorNone
) {
904 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
905 Exynos_OMX_SrcInputBufferProcess(pOMXComponent
);
907 Exynos_OSAL_ThreadExit(NULL
);
915 static OMX_ERRORTYPE
Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData
)
917 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
918 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
919 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
920 EXYNOS_OMX_MESSAGE
*message
= NULL
;
924 if (threadData
== NULL
) {
925 ret
= OMX_ErrorBadParameter
;
928 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
929 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
930 if (ret
!= OMX_ErrorNone
) {
933 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
934 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent
);
936 Exynos_OSAL_ThreadExit(NULL
);
944 static OMX_ERRORTYPE
Exynos_OMX_DstInputProcessThread(OMX_PTR threadData
)
946 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
947 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
948 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
949 EXYNOS_OMX_MESSAGE
*message
= NULL
;
953 if (threadData
== NULL
) {
954 ret
= OMX_ErrorBadParameter
;
957 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
958 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
959 if (ret
!= OMX_ErrorNone
) {
962 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
963 Exynos_OMX_DstInputBufferProcess(pOMXComponent
);
965 Exynos_OSAL_ThreadExit(NULL
);
973 static OMX_ERRORTYPE
Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData
)
975 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
976 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
977 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
978 EXYNOS_OMX_MESSAGE
*message
= NULL
;
982 if (threadData
== NULL
) {
983 ret
= OMX_ErrorBadParameter
;
986 pOMXComponent
= (OMX_COMPONENTTYPE
*)threadData
;
987 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
988 if (ret
!= OMX_ErrorNone
) {
991 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
992 Exynos_OMX_DstOutputBufferProcess(pOMXComponent
);
994 Exynos_OSAL_ThreadExit(NULL
);
1002 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent
)
1004 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1005 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1006 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1007 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1011 pVideoEnc
->bExitBufferProcessThread
= OMX_FALSE
;
1013 ret
= Exynos_OSAL_ThreadCreate(&pVideoEnc
->hDstOutputThread
,
1014 Exynos_OMX_DstOutputProcessThread
,
1016 if (ret
== OMX_ErrorNone
)
1017 ret
= Exynos_OSAL_ThreadCreate(&pVideoEnc
->hSrcOutputThread
,
1018 Exynos_OMX_SrcOutputProcessThread
,
1020 if (ret
== OMX_ErrorNone
)
1021 ret
= Exynos_OSAL_ThreadCreate(&pVideoEnc
->hDstInputThread
,
1022 Exynos_OMX_DstInputProcessThread
,
1024 if (ret
== OMX_ErrorNone
)
1025 ret
= Exynos_OSAL_ThreadCreate(&pVideoEnc
->hSrcInputThread
,
1026 Exynos_OMX_SrcInputProcessThread
,
1035 OMX_ERRORTYPE
Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent
)
1037 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1038 OMX_COMPONENTTYPE
*pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1039 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1040 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1041 OMX_S32 countValue
= 0;
1046 pVideoEnc
->bExitBufferProcessThread
= OMX_TRUE
;
1048 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1049 if (countValue
== 0)
1050 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].bufferSemID
);
1051 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
, &countValue
);
1052 if (countValue
== 0)
1053 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].codecSemID
);
1054 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1055 Exynos_OSAL_ThreadTerminate(pVideoEnc
->hSrcInputThread
);
1056 pVideoEnc
->hSrcInputThread
= NULL
;
1058 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
, &countValue
);
1059 if (countValue
== 0)
1060 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].bufferSemID
);
1061 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
, &countValue
);
1062 if (countValue
== 0)
1063 Exynos_OSAL_SemaphorePost(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].codecSemID
);
1064 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1065 Exynos_OSAL_ThreadTerminate(pVideoEnc
->hDstInputThread
);
1066 pVideoEnc
->hDstInputThread
= NULL
;
1068 pVideoEnc
->exynos_codec_stop(pOMXComponent
, INPUT_PORT_INDEX
);
1069 pVideoEnc
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1070 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
].pauseEvent
);
1071 Exynos_OSAL_ThreadTerminate(pVideoEnc
->hSrcOutputThread
);
1072 pVideoEnc
->hSrcOutputThread
= NULL
;
1074 pVideoEnc
->exynos_codec_stop(pOMXComponent
, OUTPUT_PORT_INDEX
);
1075 pVideoEnc
->exynos_codec_bufferProcessRun(pOMXComponent
, INPUT_PORT_INDEX
);
1076 Exynos_OSAL_SignalSet(pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
].pauseEvent
);
1077 Exynos_OSAL_ThreadTerminate(pVideoEnc
->hDstOutputThread
);
1078 pVideoEnc
->hDstOutputThread
= NULL
;
1086 OMX_ERRORTYPE
Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent
)
1088 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1089 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1090 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1091 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1092 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= NULL
;
1094 CSC_METHOD csc_method
= CSC_METHOD_SW
;
1098 if (hComponent
== NULL
) {
1099 ret
= OMX_ErrorBadParameter
;
1102 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1103 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1104 if (ret
!= OMX_ErrorNone
) {
1105 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1109 ret
= Exynos_OMX_BaseComponent_Constructor(pOMXComponent
);
1110 if (ret
!= OMX_ErrorNone
) {
1111 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1115 ret
= Exynos_OMX_Port_Constructor(pOMXComponent
);
1116 if (ret
!= OMX_ErrorNone
) {
1117 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1118 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_Error, Line:%d", __LINE__
);
1122 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1124 pVideoEnc
= Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT
));
1125 if (pVideoEnc
== NULL
) {
1126 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1127 ret
= OMX_ErrorInsufficientResources
;
1128 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1132 Exynos_OSAL_Memset(pVideoEnc
, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT
));
1133 pExynosComponent
->hComponentHandle
= (OMX_HANDLETYPE
)pVideoEnc
;
1135 pExynosComponent
->bSaveFlagEOS
= OMX_FALSE
;
1137 pVideoEnc
->bFirstInput
= OMX_FALSE
;
1138 pVideoEnc
->bFirstOutput
= OMX_FALSE
;
1139 pVideoEnc
->configChange
= OMX_FALSE
;
1140 pVideoEnc
->quantization
.nQpI
= 4; // I frame quantization parameter
1141 pVideoEnc
->quantization
.nQpP
= 5; // P frame quantization parameter
1142 pVideoEnc
->quantization
.nQpB
= 5; // B frame quantization parameter
1144 pVideoEnc
->csc_handle
= csc_init(csc_method
);
1145 if (pVideoEnc
->csc_handle
== NULL
) {
1146 Exynos_OSAL_Free(pVideoEnc
);
1147 Exynos_OMX_BaseComponent_Destructor(pOMXComponent
);
1148 ret
= OMX_ErrorInsufficientResources
;
1149 Exynos_OSAL_Log(EXYNOS_LOG_ERROR
, "OMX_ErrorInsufficientResources, Line:%d", __LINE__
);
1152 pVideoEnc
->csc_set_format
= OMX_FALSE
;
1153 #if defined(USE_CSC_GSCALER)
1154 csc_set_hw_property(pVideoEnc
->csc_handle
, CSC_HW_PROPERTY_FIXED_NODE
, CSC_GSCALER_IDX
);
1157 pExynosComponent
->bMultiThreadProcess
= OMX_TRUE
;
1160 pExynosPort
= &pExynosComponent
->pExynosPort
[INPUT_PORT_INDEX
];
1161 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_INPUTBUFFER_NUM
;
1162 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_INPUTBUFFER_NUM
;
1163 pExynosPort
->portDefinition
.nBufferSize
= 0;
1164 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1166 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1167 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1168 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1169 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1170 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1172 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1173 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1174 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1175 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1176 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1177 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1178 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1179 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1180 pVideoEnc
->eControlRate
[INPUT_PORT_INDEX
] = OMX_Video_ControlRateDisable
;
1182 pExynosPort
->bStoreMetaData
= OMX_FALSE
;
1185 pExynosPort
= &pExynosComponent
->pExynosPort
[OUTPUT_PORT_INDEX
];
1186 pExynosPort
->portDefinition
.nBufferCountActual
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1187 pExynosPort
->portDefinition
.nBufferCountMin
= MAX_VIDEO_OUTPUTBUFFER_NUM
;
1188 pExynosPort
->portDefinition
.nBufferSize
= DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE
;
1189 pExynosPort
->portDefinition
.eDomain
= OMX_PortDomainVideo
;
1191 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE
);
1192 Exynos_OSAL_Strcpy(pExynosPort
->portDefinition
.format
.video
.cMIMEType
, "raw/video");
1193 pExynosPort
->portDefinition
.format
.video
.pNativeRender
= 0;
1194 pExynosPort
->portDefinition
.format
.video
.bFlagErrorConcealment
= OMX_FALSE
;
1195 pExynosPort
->portDefinition
.format
.video
.eCompressionFormat
= OMX_VIDEO_CodingUnused
;
1197 pExynosPort
->portDefinition
.format
.video
.nFrameWidth
= 0;
1198 pExynosPort
->portDefinition
.format
.video
.nFrameHeight
= 0;
1199 pExynosPort
->portDefinition
.format
.video
.nStride
= 0;
1200 pExynosPort
->portDefinition
.format
.video
.nSliceHeight
= 0;
1201 pExynosPort
->portDefinition
.format
.video
.nBitrate
= 64000;
1202 pExynosPort
->portDefinition
.format
.video
.xFramerate
= (15 << 16);
1203 pExynosPort
->portDefinition
.format
.video
.eColorFormat
= OMX_COLOR_FormatUnused
;
1204 pExynosPort
->portDefinition
.format
.video
.pNativeWindow
= NULL
;
1205 pVideoEnc
->eControlRate
[OUTPUT_PORT_INDEX
] = OMX_Video_ControlRateDisable
;
1207 pOMXComponent
->UseBuffer
= &Exynos_OMX_UseBuffer
;
1208 pOMXComponent
->AllocateBuffer
= &Exynos_OMX_AllocateBuffer
;
1209 pOMXComponent
->FreeBuffer
= &Exynos_OMX_FreeBuffer
;
1210 pOMXComponent
->ComponentTunnelRequest
= &Exynos_OMX_ComponentTunnelRequest
;
1212 pExynosComponent
->exynos_AllocateTunnelBuffer
= &Exynos_OMX_AllocateTunnelBuffer
;
1213 pExynosComponent
->exynos_FreeTunnelBuffer
= &Exynos_OMX_FreeTunnelBuffer
;
1214 pExynosComponent
->exynos_BufferProcessCreate
= &Exynos_OMX_BufferProcess_Create
;
1215 pExynosComponent
->exynos_BufferProcessTerminate
= &Exynos_OMX_BufferProcess_Terminate
;
1216 pExynosComponent
->exynos_BufferFlush
= &Exynos_OMX_BufferFlush
;
1224 OMX_ERRORTYPE
Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent
)
1226 OMX_ERRORTYPE ret
= OMX_ErrorNone
;
1227 OMX_COMPONENTTYPE
*pOMXComponent
= NULL
;
1228 EXYNOS_OMX_BASECOMPONENT
*pExynosComponent
= NULL
;
1229 EXYNOS_OMX_BASEPORT
*pExynosPort
= NULL
;
1230 EXYNOS_OMX_VIDEOENC_COMPONENT
*pVideoEnc
= NULL
;
1235 if (hComponent
== NULL
) {
1236 ret
= OMX_ErrorBadParameter
;
1239 pOMXComponent
= (OMX_COMPONENTTYPE
*)hComponent
;
1240 ret
= Exynos_OMX_Check_SizeVersion(pOMXComponent
, sizeof(OMX_COMPONENTTYPE
));
1241 if (ret
!= OMX_ErrorNone
) {
1245 if (pOMXComponent
->pComponentPrivate
== NULL
) {
1246 ret
= OMX_ErrorBadParameter
;
1249 pExynosComponent
= (EXYNOS_OMX_BASECOMPONENT
*)pOMXComponent
->pComponentPrivate
;
1251 pVideoEnc
= (EXYNOS_OMX_VIDEOENC_COMPONENT
*)pExynosComponent
->hComponentHandle
;
1253 if (pVideoEnc
->csc_handle
!= NULL
) {
1254 csc_deinit(pVideoEnc
->csc_handle
);
1255 pVideoEnc
->csc_handle
= NULL
;
1258 Exynos_OSAL_Free(pVideoEnc
);
1259 pExynosComponent
->hComponentHandle
= pVideoEnc
= NULL
;
1261 for(i
= 0; i
< ALL_PORT_NUM
; i
++) {
1262 pExynosPort
= &pExynosComponent
->pExynosPort
[i
];
1263 Exynos_OSAL_Free(pExynosPort
->portDefinition
.format
.video
.cMIMEType
);
1264 pExynosPort
->portDefinition
.format
.video
.cMIMEType
= NULL
;
1267 ret
= Exynos_OMX_Port_Destructor(pOMXComponent
);
1269 ret
= Exynos_OMX_BaseComponent_Destructor(hComponent
);