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