95689c6f053ab0874da130553787d2de0f4222ec
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / enc / Exynos_OMX_Venc.c
1 /*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17
18 /*
19 * @file Exynos_OMX_Venc.c
20 * @brief
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * Yunji Kim (yunji.kim@samsung.com)
23 * @version 2.0.0
24 * @history
25 * 2012.02.20 : Create
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
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"
41 #include "ExynosVideoApi.h"
42 #include "csc.h"
43
44 #ifdef USE_STOREMETADATA
45 #include "Exynos_OSAL_Android.h"
46 #endif
47
48 #undef EXYNOS_LOG_TAG
49 #define EXYNOS_LOG_TAG "EXYNOS_VIDEO_ENC"
50 #define EXYNOS_LOG_OFF
51 //#define EXYNOS_TRACE_ON
52 #include "Exynos_OSAL_Log.h"
53
54
55 inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
56 {
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];
60
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;
66
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;
75
76 if (width && height)
77 exynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
78 }
79
80 return;
81 }
82
83 void Exynos_Free_CodecBuffers(
84 OMX_COMPONENTTYPE *pOMXComponent,
85 OMX_U32 nPortIndex)
86 {
87 OMX_ERRORTYPE ret = OMX_ErrorNone;
88 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
89 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
90 CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
91
92 OMX_U32 nPlaneCnt = 0;
93 int i, j;
94
95 FunctionIn();
96
97 if (nPortIndex == INPUT_PORT_INDEX) {
98 ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
99 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
100 } else {
101 ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
102 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
103 }
104
105 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
106 if (ppCodecBuffer[i] != NULL) {
107 for (j = 0; j < nPlaneCnt; j++) {
108 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
109 Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
110 }
111
112 Exynos_OSAL_Free(ppCodecBuffer[i]);
113 ppCodecBuffer[i] = NULL;
114 }
115 }
116
117 FunctionOut();
118 }
119
120 OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
121 OMX_COMPONENTTYPE *pOMXComponent,
122 OMX_U32 nPortIndex,
123 OMX_U32 nBufferCnt,
124 OMX_U32 nPlaneSize[MFC_OUTPUT_BUFFER_PLANE])
125 {
126 OMX_ERRORTYPE ret = OMX_ErrorNone;
127 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
128 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
129 MEMORY_TYPE eMemoryType = SYSTEM_MEMORY;
130 CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
131
132 OMX_U32 nPlaneCnt = 0;
133 int i, j;
134
135 FunctionIn();
136
137 if (nPortIndex == INPUT_PORT_INDEX) {
138 ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
139 nPlaneCnt = MFC_INPUT_BUFFER_PLANE;
140 } else {
141 ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
142 nPlaneCnt = MFC_OUTPUT_BUFFER_PLANE;
143 #ifdef USE_CSC_HW
144 eMemoryType = NORMAL_MEMORY;
145 #endif
146 }
147
148 for (i = 0; i < nBufferCnt; i++) {
149 ppCodecBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
150 if (ppCodecBuffer[i] == NULL) {
151 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
152 ret = OMX_ErrorInsufficientResources;
153 goto EXIT;
154 }
155 Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_ENC_BUFFER));
156
157 for (j = 0; j < nPlaneCnt; j++) {
158 ppCodecBuffer[i]->pVirAddr[j] =
159 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nPlaneSize[j], eMemoryType);
160 if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
161 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc plane");
162 ret = OMX_ErrorInsufficientResources;
163 goto EXIT;
164 }
165
166 ppCodecBuffer[i]->fd[j] =
167 Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
168 ppCodecBuffer[i]->bufferSize[j] = nPlaneSize[j];
169 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[j]);
170 }
171
172 ppCodecBuffer[i]->dataSize = 0;
173 }
174
175 return OMX_ErrorNone;
176
177 EXIT:
178 Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
179
180 FunctionOut();
181
182 return ret;
183 }
184
185 OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
186 {
187 OMX_BOOL ret = OMX_FALSE;
188
189 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
190 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
191 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
192 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
193 ret = OMX_TRUE;
194 } else {
195 ret = OMX_FALSE;
196 }
197
198 return ret;
199 }
200
201 OMX_ERRORTYPE Exynos_Input_CodecBufferToData(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_PTR codecBuffer, EXYNOS_OMX_DATA *pData)
202 {
203 OMX_ERRORTYPE ret = OMX_ErrorNone;
204 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
205 CODEC_ENC_BUFFER *pInputCodecBuffer = (CODEC_ENC_BUFFER*)codecBuffer;
206
207 pData->buffer.multiPlaneBuffer.dataBuffer[0] = pInputCodecBuffer->pVirAddr[0];
208 pData->buffer.multiPlaneBuffer.dataBuffer[1] = pInputCodecBuffer->pVirAddr[1];
209 pData->buffer.multiPlaneBuffer.fd[0] = pInputCodecBuffer->fd[0];
210 pData->buffer.multiPlaneBuffer.fd[1] = pInputCodecBuffer->fd[1];
211 pData->allocSize = pInputCodecBuffer->bufferSize[0] + pInputCodecBuffer->bufferSize[1];
212 pData->dataLen = pInputCodecBuffer->dataSize;
213 pData->usedDataLen = 0;
214 pData->remainDataLen = pInputCodecBuffer->dataSize;
215
216 pData->nFlags = 0;
217 pData->timeStamp = 0;
218 pData->pPrivate = codecBuffer;
219 pData->bufferHeader = NULL;
220
221 return ret;
222 }
223
224 OMX_ERRORTYPE Exynos_Output_CodecBufferToData(
225 CODEC_ENC_BUFFER *pCodecBuffer,
226 EXYNOS_OMX_DATA *pData)
227 {
228 OMX_ERRORTYPE ret = OMX_ErrorNone;
229
230 pData->buffer.singlePlaneBuffer.dataBuffer = pCodecBuffer->pVirAddr[0];
231 pData->buffer.singlePlaneBuffer.fd = pCodecBuffer->fd[0];
232 pData->allocSize = pCodecBuffer->bufferSize[0];
233 pData->dataLen = 0;
234 pData->usedDataLen = 0;
235 pData->remainDataLen = 0;
236
237 pData->nFlags = 0;
238 pData->timeStamp = 0;
239 pData->pPrivate = pCodecBuffer;
240 pData->bufferHeader = NULL;
241
242 return ret;
243 }
244
245 void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
246 {
247 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
248 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
249 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
250
251 FunctionIn();
252
253 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
254
255 if (((pExynosComponent->currentState == OMX_StatePause) ||
256 (pExynosComponent->currentState == OMX_StateIdle) ||
257 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
258 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
259 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
260 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
261 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
262 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
263 }
264
265 FunctionOut();
266
267 return;
268 }
269
270 OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
271 {
272 OMX_BOOL ret = OMX_FALSE;
273 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
274 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
275 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
276 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
277 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
278 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
279 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
280 OMX_BYTE checkInputStream = NULL;
281 OMX_BOOL flagEOS = OMX_FALSE;
282
283 FunctionIn();
284
285 checkInputStream = inputUseBuffer->bufferHeader->pBuffer;
286
287 CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate;
288 codecInputBuffer->dataSize = ((nFrameWidth * nFrameHeight) * 3) / 2;
289
290 unsigned int csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
291 unsigned int csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
292 CSC_METHOD csc_method = CSC_METHOD_SW;
293 unsigned int srcCacheable = 1, dstCacheable = 1;
294
295 unsigned char *pSrcBuf[3] = {NULL, };
296 unsigned char *pDstBuf[3] = {NULL, };
297
298 CSC_ERRORCODE cscRet = CSC_ErrorNone;
299
300 pSrcBuf[0] = checkInputStream;
301 pSrcBuf[1] = checkInputStream + (nFrameWidth * nFrameHeight);
302 pSrcBuf[2] = checkInputStream + (((nFrameWidth * nFrameHeight) * 5) / 4);
303
304 pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
305 pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
306 pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.dataBuffer[2];
307
308 csc_get_method(pVideoEnc->csc_handle, &csc_method);
309 if (csc_method == CSC_METHOD_HW)
310 dstCacheable = 0;
311
312 #ifdef USE_METADATABUFFERTYPE
313 OMX_PTR ppBuf[MAX_BUFFER_PLANE];
314
315 /* kMetadataBufferTypeGrallocSource */
316 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
317 /* ARGB8888 converted to YUV420SemiPlanar */
318 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_Format32bitARGB8888);
319 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
320
321 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
322 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
323 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
324 OMX_U32 stride;
325 int imageSize;
326
327 ret = Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, planes);
328 if (ret != OMX_ErrorNone) {
329 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__);
330 ret = OMX_FALSE;
331 goto EXIT;
332 }
333
334 imageSize = nFrameWidth * nFrameHeight * 3; /* RGB888 */
335
336 #ifdef USE_GSC_RGB_ENCODER
337 if (pVideoEnc->csc_set_format == OMX_FALSE) {
338 cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
339 if (cscRet != CSC_ErrorNone) {
340 ret = OMX_FALSE;
341 goto EXIT;
342 }
343 }
344 #endif
345
346 #ifdef USE_DMA_BUF
347 if (csc_method == CSC_METHOD_HW)
348 pSrcBuf[0] = (unsigned char *)planes[0].fd;
349 else
350 #endif
351 pSrcBuf[0] = planes[0].addr;
352 pSrcBuf[1] = NULL;
353 pSrcBuf[2] = NULL;
354 }
355 } else
356 #endif
357 {
358 #ifdef USE_DMA_BUF
359 if (csc_method == CSC_METHOD_HW) {
360 pSrcBuf[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, checkInputStream);
361 pSrcBuf[1] = NULL;
362 pSrcBuf[2] = NULL;
363 }
364 #endif
365
366 switch (eColorFormat) {
367 case OMX_COLOR_FormatYUV420Planar:
368 /* YUV420Planar converted to YUV420Semiplanar (interleaved UV plane) as per MFC spec.*/
369 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420Planar);
370 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
371 break;
372 case OMX_COLOR_FormatYUV420SemiPlanar:
373 case OMX_SEC_COLOR_FormatNV12Tiled:
374 case OMX_SEC_COLOR_FormatNV21Linear:
375 /* Just copied to MFC input buffer */
376 csc_src_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
377 csc_dst_color_format = omx_2_hal_pixel_format((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar);
378 break;
379 default:
380 break;
381 }
382 }
383
384 #ifdef USE_DMA_BUF
385 if (csc_method == CSC_METHOD_HW) {
386 pDstBuf[0] = srcInputData->buffer.multiPlaneBuffer.fd[0];
387 pDstBuf[1] = srcInputData->buffer.multiPlaneBuffer.fd[1];
388 pDstBuf[2] = srcInputData->buffer.multiPlaneBuffer.fd[2];
389 }
390 #endif
391
392 csc_set_src_format(
393 pVideoEnc->csc_handle, /* handle */
394 nFrameWidth, /* width */
395 nFrameHeight, /* height */
396 0, /* crop_left */
397 0, /* crop_right */
398 nFrameWidth, /* crop_width */
399 nFrameHeight, /* crop_height */
400 csc_src_color_format, /* color_format */
401 srcCacheable); /* cacheable */
402 csc_set_dst_format(
403 pVideoEnc->csc_handle, /* handle */
404 nFrameWidth, /* width */
405 nFrameHeight, /* height */
406 0, /* crop_left */
407 0, /* crop_right */
408 nFrameWidth, /* crop_width */
409 nFrameHeight, /* crop_height */
410 csc_dst_color_format, /* color_format */
411 dstCacheable); /* cacheable */
412 csc_set_src_buffer(
413 pVideoEnc->csc_handle, /* handle */
414 pSrcBuf,
415 CSC_MEMORY_DMABUF); /* YUV Addr or FD */
416 csc_set_dst_buffer(
417 pVideoEnc->csc_handle, /* handle */
418 pDstBuf,
419 CSC_MEMORY_DMABUF); /* YUV Addr or FD */
420 cscRet = csc_convert(pVideoEnc->csc_handle);
421 if (cscRet != CSC_ErrorNone)
422 ret = OMX_FALSE;
423 else
424 ret = OMX_TRUE;
425
426 #ifdef USE_METADATABUFFERTYPE
427 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
428 Exynos_OSAL_UnlockANBHandle((OMX_U32)ppBuf[0]);
429 }
430 #endif
431
432 ret = OMX_TRUE;
433
434 EXIT:
435 FunctionOut();
436
437 return ret;
438 }
439
440 OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
441 {
442 OMX_BOOL ret = OMX_FALSE;
443 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
444 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
445 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
446 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
447 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
448 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
449 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
450 OMX_U32 copySize = 0;
451 OMX_BYTE checkInputStream = NULL;
452 OMX_U32 checkInputStreamLen = 0;
453 OMX_BOOL flagEOS = OMX_FALSE;
454
455 FunctionIn();
456
457 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
458 if ((srcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) ||
459 (srcInputData->pPrivate == NULL)) {
460 ret = OMX_FALSE;
461 goto EXIT;
462 }
463 }
464
465 if (inputUseBuffer->dataValid == OMX_TRUE) {
466 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
467 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
468 #ifdef USE_METADATABUFFERTYPE
469 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
470 OMX_PTR ppBuf[MAX_BUFFER_PLANE];
471 OMX_PTR allocSize[MAX_BUFFER_PLANE];
472 int plane = 0;
473
474 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
475 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
476 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
477
478 Exynos_OSAL_LockANBHandle((OMX_U32)ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatYUV420SemiPlanar, planes);
479
480 srcInputData->buffer.multiPlaneBuffer.fd[0] = planes[0].fd;
481 srcInputData->buffer.multiPlaneBuffer.fd[1] = planes[1].fd;
482 allocSize[0] = nFrameWidth * nFrameHeight;
483 allocSize[1] = nFrameWidth * nFrameHeight >> 1;
484
485 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
486 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] =
487 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]);
488 if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) {
489 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] =
490 Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]);
491 }
492 }
493 /* input buffers are 2 plane. */
494 srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL;
495 srcInputData->buffer.multiPlaneBuffer.fd[2] = -1;
496 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[0]);
497 } else {
498 /* kMetadataBufferTypeCameraSource */
499 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf);
500 #ifdef USE_DMA_BUF
501 srcInputData->buffer.multiPlaneBuffer.fd[0] = ppBuf[0];
502 srcInputData->buffer.multiPlaneBuffer.fd[1] = ppBuf[1];
503 allocSize[0] = nFrameWidth * nFrameHeight;
504 allocSize[1] = nFrameWidth * nFrameHeight >> 1;
505
506 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
507 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] =
508 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->buffer.multiPlaneBuffer.fd[plane]);
509 if(srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] == NULL) {
510 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] =
511 Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, allocSize[plane], srcInputData->buffer.multiPlaneBuffer.fd[plane]);
512 }
513 }
514 /* input buffers are 2 plane. */
515 srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL;
516 srcInputData->buffer.multiPlaneBuffer.fd[2] = -1;
517 #else
518 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
519 srcInputData->buffer.multiPlaneBuffer.dataBuffer[plane] = ppBuf[plane];
520 }
521 srcInputData->buffer.multiPlaneBuffer.dataBuffer[2] = NULL;
522 #endif
523 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%x CbCrAddr: 0x%x", __FUNCTION__, __LINE__, (unsigned int)ppBuf[0], (unsigned int)ppBuf[1]);
524 }
525 }
526 #endif
527 /* reset dataBuffer */
528 Exynos_ResetDataBuffer(inputUseBuffer);
529 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
530 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
531 checkInputStreamLen = inputUseBuffer->remainDataLen;
532
533 pExynosComponent->bUseFlagEOF = OMX_TRUE;
534
535 if (checkInputStreamLen == 0) {
536 inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
537 flagEOS = OMX_TRUE;
538 }
539
540 copySize = checkInputStreamLen;
541 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "exynos_checkInputFrame : OMX_TRUE");
542
543 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
544 ret = Exynos_CSC_InputData(pOMXComponent, srcInputData);
545 if (ret == OMX_FALSE)
546 goto EXIT;
547
548 inputUseBuffer->dataLen -= copySize;
549 inputUseBuffer->remainDataLen -= copySize;
550 inputUseBuffer->usedDataLen += copySize;
551
552 srcInputData->dataLen += copySize;
553 srcInputData->remainDataLen += copySize;
554
555 srcInputData->timeStamp = inputUseBuffer->timeStamp;
556 srcInputData->nFlags = inputUseBuffer->nFlags;
557 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
558 } else {
559 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
560 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
561 pExynosComponent->callbackData,
562 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
563 ret = OMX_FALSE;
564 }
565
566 if (((exynosInputPort->bStoreMetaData == OMX_TRUE) && (eColorFormat == OMX_COLOR_FormatAndroidOpaque)) ||
567 (exynosInputPort->bStoreMetaData == OMX_FALSE)) {
568 Exynos_InputBufferReturn(pOMXComponent);
569 } else {
570 inputUseBuffer->dataValid = OMX_TRUE;
571 }
572 }
573
574 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
575 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
576 srcInputData->dataLen = 0;
577 srcInputData->remainDataLen = 0;
578 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
579 }
580
581 if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
582 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
583 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
584 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
585 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
586 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
587 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
588 }
589
590 ret = OMX_TRUE;
591 }
592
593 EXIT:
594
595 FunctionOut();
596
597 return ret;
598 }
599
600 OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
601 {
602 OMX_BOOL ret = OMX_FALSE;
603 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
604 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
605 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
606 OMX_U32 copySize = 0;
607
608 FunctionIn();
609
610 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
611 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer, OMX_FALSE) == OMX_ErrorNone)
612 outputUseBuffer->dataValid = OMX_TRUE;
613 }
614
615 if (outputUseBuffer->dataValid == OMX_TRUE) {
616 if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
617 if (pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp){
618 pExynosComponent->checkTimeStamp.startTimeStamp = -19761123;
619 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
620 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
621 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
622 } else {
623 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "garbage frame drop after flush");
624 ret = OMX_TRUE;
625 goto EXIT;
626 }
627 } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
628 ret = OMX_TRUE;
629 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input buffer has not come after flush.");
630 goto EXIT;
631 }
632
633 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
634 if (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) {
635 copySize = dstOutputData->remainDataLen;
636 if (copySize > 0)
637 Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen),
638 (dstOutputData->buffer.singlePlaneBuffer.dataBuffer + dstOutputData->usedDataLen),
639 copySize);
640 outputUseBuffer->dataLen += copySize;
641 outputUseBuffer->remainDataLen += copySize;
642 outputUseBuffer->nFlags = dstOutputData->nFlags;
643 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
644
645 ret = OMX_TRUE;
646
647 if ((outputUseBuffer->remainDataLen > 0) ||
648 (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
649 Exynos_OutputBufferReturn(pOMXComponent);
650 }
651 } else {
652 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than encoded data size Out Length");
653 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
654 pExynosComponent->callbackData,
655 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
656 ret = OMX_FALSE;
657 }
658 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
659 if ((outputUseBuffer->remainDataLen > 0) ||
660 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
661 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)))
662 Exynos_OutputBufferReturn(pOMXComponent);
663 }
664 } else {
665 ret = OMX_FALSE;
666 }
667
668 EXIT:
669 FunctionOut();
670
671 return ret;
672 }
673
674 #ifdef USE_METADATABUFFERTYPE
675 OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent)
676 {
677 OMX_ERRORTYPE ret = OMX_ErrorNone;
678 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
679 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
680 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
681 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
682 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
683 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
684 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
685
686 int i = 0;
687 OMX_PTR ppBuf[MAX_BUFFER_PLANE];
688
689
690 /* kMetadataBufferTypeGrallocSource */
691 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
692 Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf);
693 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
694 pVideoEnc->ANBColorFormat = Exynos_OSAL_GetANBColorFormat(ppBuf[0]);
695 if ((pVideoEnc->ANBColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) ||
696 (pVideoEnc->ANBColorFormat == OMX_SEC_COLOR_FormatNV12Tiled)) {
697 exynosInputPort->bufferProcessType = BUFFER_SHARE;
698 } else {
699 exynosInputPort->bufferProcessType = BUFFER_COPY;
700 }
701
702 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
703 OMX_U32 nPlaneSize[MFC_INPUT_BUFFER_PLANE] = {0, };
704 nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE;
705 nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
706
707 Exynos_OSAL_SemaphoreCreate(&exynosInputPort->codecSemID);
708 Exynos_OSAL_QueueCreate(&exynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
709
710 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
711 if (ret != OMX_ErrorNone)
712 goto EXIT;
713
714 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
715 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
716 } else if (exynosInputPort->bufferProcessType == BUFFER_SHARE) {
717 /*************/
718 /* TBD */
719 /*************/
720 /* Does not require any actions. */
721 }
722 }
723 }
724
725 EXIT:
726
727 return ret;
728 }
729 #endif
730
731 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
732 {
733 OMX_ERRORTYPE ret = OMX_ErrorNone;
734 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
735 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
736 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
737 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
738 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
739 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
740 OMX_BOOL bCheckInputData = OMX_FALSE;
741 OMX_BOOL bValidCodecData = OMX_FALSE;
742
743 FunctionIn();
744
745 while (!pVideoEnc->bExitBufferProcessThread) {
746 Exynos_OSAL_SleepMillisec(0);
747 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
748
749 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
750 (!pVideoEnc->bExitBufferProcessThread)) {
751 Exynos_OSAL_SleepMillisec(0);
752
753 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
754 break;
755 if (exynosInputPort->portState != OMX_StateIdle)
756 break;
757
758 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
759 if (pVideoEnc->bFirstInput == OMX_FALSE) {
760 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
761 OMX_PTR codecBuffer;
762 if ((pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) {
763 Exynos_CodecBufferDequeue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
764 if (codecBuffer != NULL) {
765 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
766 }
767 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
768 break;
769 }
770 }
771
772 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
773 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
774 } else {
775 bCheckInputData = OMX_FALSE;
776 }
777 }
778 if ((bCheckInputData == OMX_FALSE) &&
779 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
780 ret = Exynos_InputBufferGetQueue(pExynosComponent);
781 #ifdef USE_METADATABUFFERTYPE
782 if ((pVideoEnc->bFirstInput == OMX_TRUE) &&
783 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
784 Exynos_OMX_ExtensionSetup(hComponent);
785 pVideoEnc->bFirstInput = OMX_FALSE;
786 }
787 #endif
788 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
789 break;
790 }
791
792 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
793 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
794 break;
795 }
796
797 ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
798 Exynos_ResetCodecData(pSrcInputData);
799 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
800 if (ret == OMX_ErrorCodecInit)
801 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
802 }
803 }
804
805 EXIT:
806
807 FunctionOut();
808
809 return ret;
810 }
811
812 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
813 {
814 OMX_ERRORTYPE ret = OMX_ErrorNone;
815 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
816 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
817 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
818 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
819 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
820 EXYNOS_OMX_DATA srcOutputData;
821
822 FunctionIn();
823
824 while (!pVideoEnc->bExitBufferProcessThread) {
825 Exynos_OSAL_SleepMillisec(0);
826
827 while (!pVideoEnc->bExitBufferProcessThread) {
828 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
829 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
830 break;
831 }
832 Exynos_OSAL_SleepMillisec(0);
833
834 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
835 break;
836
837 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
838 ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
839
840 if (ret == OMX_ErrorNone) {
841 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
842 OMX_PTR codecBuffer;
843 codecBuffer = srcOutputData.pPrivate;
844 if (codecBuffer != NULL)
845 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
846 }
847 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
848 OMX_BOOL bNeedUnlock = OMX_FALSE;
849 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
850 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque)
851 bNeedUnlock = OMX_TRUE;
852 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer, bNeedUnlock);
853 Exynos_InputBufferReturn(pOMXComponent);
854 }
855 Exynos_ResetCodecData(&srcOutputData);
856 }
857 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
858 }
859 }
860
861 EXIT:
862
863 FunctionOut();
864
865 return ret;
866 }
867
868 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
869 {
870 OMX_ERRORTYPE ret = OMX_ErrorNone;
871 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
872 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
873 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
874 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
875 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
876 EXYNOS_OMX_DATA dstInputData;
877
878 FunctionIn();
879
880 while (!pVideoEnc->bExitBufferProcessThread) {
881 Exynos_OSAL_SleepMillisec(0);
882
883 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
884 (!pVideoEnc->bExitBufferProcessThread)) {
885 Exynos_OSAL_SleepMillisec(0);
886
887 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
888 (!CHECK_PORT_POPULATED(exynosOutputPort)))
889 break;
890 if (exynosOutputPort->portState != OMX_StateIdle)
891 break;
892
893 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
894 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
895 CODEC_ENC_BUFFER *pCodecBuffer = NULL;
896 ret = Exynos_CodecBufferDequeue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
897 if (ret != OMX_ErrorNone) {
898 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
899 break;
900 }
901 Exynos_Output_CodecBufferToData(pCodecBuffer, &dstInputData);
902 }
903
904 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
905 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
906 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
907 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
908 if (ret != OMX_ErrorNone) {
909 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
910 break;
911 }
912 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE);
913 Exynos_ResetDataBuffer(dstInputUseBuffer);
914 }
915 }
916
917 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
918 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
919 break;
920 }
921 ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
922
923 Exynos_ResetCodecData(&dstInputData);
924 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
925 }
926 }
927
928 EXIT:
929
930 FunctionOut();
931
932 return ret;
933 }
934
935 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
936 {
937 OMX_ERRORTYPE ret = OMX_ErrorNone;
938 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
939 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
940 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
941 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
942 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
943 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
944
945 FunctionIn();
946
947 while (!pVideoEnc->bExitBufferProcessThread) {
948 Exynos_OSAL_SleepMillisec(0);
949 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
950
951 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
952 (!pVideoEnc->bExitBufferProcessThread)) {
953 Exynos_OSAL_SleepMillisec(0);
954
955 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
956 break;
957
958 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
959 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
960 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
961 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
962 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
963 if (ret != OMX_ErrorNone) {
964 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
965 break;
966 }
967 }
968 }
969
970 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
971 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
972 ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
973
974 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
975 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
976 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
977 }
978
979 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
980 if (pDstOutputData->pPrivate != NULL) {
981 Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
982 pDstOutputData->pPrivate = NULL;
983 }
984 }
985
986 /* reset outputData */
987 Exynos_ResetCodecData(pDstOutputData);
988 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
989 }
990 }
991
992 EXIT:
993
994 FunctionOut();
995
996 return ret;
997 }
998
999 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
1000 {
1001 OMX_ERRORTYPE ret = OMX_ErrorNone;
1002 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1003 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1004 EXYNOS_OMX_MESSAGE *message = NULL;
1005
1006 FunctionIn();
1007
1008 if (threadData == NULL) {
1009 ret = OMX_ErrorBadParameter;
1010 goto EXIT;
1011 }
1012 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1013 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1014 if (ret != OMX_ErrorNone) {
1015 goto EXIT;
1016 }
1017 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1018 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1019
1020 Exynos_OSAL_ThreadExit(NULL);
1021
1022 EXIT:
1023 FunctionOut();
1024
1025 return ret;
1026 }
1027
1028 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1029 {
1030 OMX_ERRORTYPE ret = OMX_ErrorNone;
1031 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1032 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1033 EXYNOS_OMX_MESSAGE *message = NULL;
1034
1035 FunctionIn();
1036
1037 if (threadData == NULL) {
1038 ret = OMX_ErrorBadParameter;
1039 goto EXIT;
1040 }
1041 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1042 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1043 if (ret != OMX_ErrorNone) {
1044 goto EXIT;
1045 }
1046 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1047 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1048
1049 Exynos_OSAL_ThreadExit(NULL);
1050
1051 EXIT:
1052 FunctionOut();
1053
1054 return ret;
1055 }
1056
1057 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1058 {
1059 OMX_ERRORTYPE ret = OMX_ErrorNone;
1060 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1061 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1062 EXYNOS_OMX_MESSAGE *message = NULL;
1063
1064 FunctionIn();
1065
1066 if (threadData == NULL) {
1067 ret = OMX_ErrorBadParameter;
1068 goto EXIT;
1069 }
1070 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1071 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1072 if (ret != OMX_ErrorNone) {
1073 goto EXIT;
1074 }
1075 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1076 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1077
1078 Exynos_OSAL_ThreadExit(NULL);
1079
1080 EXIT:
1081 FunctionOut();
1082
1083 return ret;
1084 }
1085
1086 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1087 {
1088 OMX_ERRORTYPE ret = OMX_ErrorNone;
1089 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1090 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1091 EXYNOS_OMX_MESSAGE *message = NULL;
1092
1093 FunctionIn();
1094
1095 if (threadData == NULL) {
1096 ret = OMX_ErrorBadParameter;
1097 goto EXIT;
1098 }
1099 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1100 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1101 if (ret != OMX_ErrorNone) {
1102 goto EXIT;
1103 }
1104 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1105 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1106
1107 Exynos_OSAL_ThreadExit(NULL);
1108
1109 EXIT:
1110 FunctionOut();
1111
1112 return ret;
1113 }
1114
1115 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1116 {
1117 OMX_ERRORTYPE ret = OMX_ErrorNone;
1118 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1119 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1120 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1121
1122 FunctionIn();
1123
1124 pVideoEnc->bExitBufferProcessThread = OMX_FALSE;
1125
1126 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread,
1127 Exynos_OMX_DstOutputProcessThread,
1128 pOMXComponent);
1129 if (ret == OMX_ErrorNone)
1130 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread,
1131 Exynos_OMX_SrcOutputProcessThread,
1132 pOMXComponent);
1133 if (ret == OMX_ErrorNone)
1134 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread,
1135 Exynos_OMX_DstInputProcessThread,
1136 pOMXComponent);
1137 if (ret == OMX_ErrorNone)
1138 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread,
1139 Exynos_OMX_SrcInputProcessThread,
1140 pOMXComponent);
1141
1142 EXIT:
1143 FunctionOut();
1144
1145 return ret;
1146 }
1147
1148 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1149 {
1150 OMX_ERRORTYPE ret = OMX_ErrorNone;
1151 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1152 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1153 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1154 OMX_S32 countValue = 0;
1155 unsigned int i = 0;
1156
1157 FunctionIn();
1158
1159 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
1160
1161 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1162 if (countValue == 0)
1163 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1164 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1165 if (countValue == 0)
1166 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1167 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1168 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread);
1169 pVideoEnc->hSrcInputThread = NULL;
1170
1171 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1172 if (countValue == 0)
1173 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1174 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1175 if (countValue == 0)
1176 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1177 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1178 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread);
1179 pVideoEnc->hDstInputThread = NULL;
1180
1181 pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1182 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1183 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1184 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread);
1185 pVideoEnc->hSrcOutputThread = NULL;
1186
1187 pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1188 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1189 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1190 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread);
1191 pVideoEnc->hDstOutputThread = NULL;
1192
1193 EXIT:
1194 FunctionOut();
1195
1196 return ret;
1197 }
1198
1199 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1200 {
1201 OMX_ERRORTYPE ret = OMX_ErrorNone;
1202 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1203 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1204 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1205 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1206
1207 FunctionIn();
1208
1209 if (hComponent == NULL) {
1210 ret = OMX_ErrorBadParameter;
1211 goto EXIT;
1212 }
1213 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1214 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1215 if (ret != OMX_ErrorNone) {
1216 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1217 goto EXIT;
1218 }
1219
1220 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1221 if (ret != OMX_ErrorNone) {
1222 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1223 goto EXIT;
1224 }
1225
1226 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1227 if (ret != OMX_ErrorNone) {
1228 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1229 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1230 goto EXIT;
1231 }
1232
1233 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1234
1235 pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1236 if (pVideoEnc == NULL) {
1237 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1238 ret = OMX_ErrorInsufficientResources;
1239 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1240 goto EXIT;
1241 }
1242
1243 Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1244 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
1245
1246 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1247
1248 pVideoEnc->bFirstInput = OMX_FALSE;
1249 pVideoEnc->bFirstOutput = OMX_FALSE;
1250 pVideoEnc->configChange = OMX_FALSE;
1251 pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter
1252 pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
1253 pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
1254
1255 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1256
1257 /* Input port */
1258 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1259 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1260 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1261 pExynosPort->portDefinition.nBufferSize = 0;
1262 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1263
1264 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1265 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1266 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1267 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1268 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1269
1270 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1271 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1272 pExynosPort->portDefinition.format.video.nStride = 0;
1273 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1274 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1275 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1276 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1277 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1278 pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable;
1279
1280 pExynosPort->bStoreMetaData = OMX_FALSE;
1281
1282 /* Output port */
1283 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1284 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1285 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1286 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1287 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1288
1289 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1290 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1291 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1292 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1293 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1294
1295 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1296 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1297 pExynosPort->portDefinition.format.video.nStride = 0;
1298 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1299 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1300 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1301 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1302 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1303 pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable;
1304
1305 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1306 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1307 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1308 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1309
1310 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1311 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1312 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1313 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1314 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1315
1316 EXIT:
1317 FunctionOut();
1318
1319 return ret;
1320 }
1321
1322 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1323 {
1324 OMX_ERRORTYPE ret = OMX_ErrorNone;
1325 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1326 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1327 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1328 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1329 int i = 0;
1330
1331 FunctionIn();
1332
1333 if (hComponent == NULL) {
1334 ret = OMX_ErrorBadParameter;
1335 goto EXIT;
1336 }
1337 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1338 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1339 if (ret != OMX_ErrorNone) {
1340 goto EXIT;
1341 }
1342
1343 if (pOMXComponent->pComponentPrivate == NULL) {
1344 ret = OMX_ErrorBadParameter;
1345 goto EXIT;
1346 }
1347 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1348
1349 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1350
1351 Exynos_OSAL_Free(pVideoEnc);
1352 pExynosComponent->hComponentHandle = pVideoEnc = NULL;
1353
1354 for(i = 0; i < ALL_PORT_NUM; i++) {
1355 pExynosPort = &pExynosComponent->pExynosPort[i];
1356 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1357 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1358 }
1359
1360 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1361
1362 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1363
1364 EXIT:
1365 FunctionOut();
1366
1367 return ret;
1368 }