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