OpenMax: Update from ODROID-XU 04212014 BSP
[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 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
828 OMX_U32 nPlaneSize[MAX_BUFFER_PLANE] = {0, 0, 0};
829
830 nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE;
831 nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
832
833 if (pVideoEnc->nInbufSpareSize > 0) {
834 nPlaneSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE + pVideoEnc->nInbufSpareSize;
835 nPlaneSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE + pVideoEnc->nInbufSpareSize;
836 }
837
838 Exynos_OSAL_SemaphoreCreate(&exynosInputPort->codecSemID);
839 Exynos_OSAL_QueueCreate(&exynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
840
841 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nPlaneSize);
842 if (ret != OMX_ErrorNone)
843 goto EXIT;
844
845 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
846 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
847 } else if (exynosInputPort->bufferProcessType == BUFFER_SHARE) {
848 /*************/
849 /* TBD */
850 /*************/
851 /* Does not require any actions. */
852 }
853 } else {
854 pExtBufferInfo->eColorFormat = eColorFormat;
855 }
856 }
857
858 EXIT:
859
860 return ret;
861 }
862 #endif
863
864 OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
865 {
866 OMX_ERRORTYPE ret = OMX_ErrorNone;
867 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
868 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
869 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
870 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
871 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
872 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
873 OMX_BOOL bCheckInputData = OMX_FALSE;
874 OMX_BOOL bValidCodecData = OMX_FALSE;
875
876 FunctionIn();
877
878 while (!pVideoEnc->bExitBufferProcessThread) {
879 Exynos_OSAL_SleepMillisec(0);
880 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
881
882 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
883 (!pVideoEnc->bExitBufferProcessThread)) {
884 Exynos_OSAL_SleepMillisec(0);
885
886 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
887 break;
888 if (exynosInputPort->portState != OMX_StateIdle)
889 break;
890
891 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
892 if (pVideoEnc->bFirstInput == OMX_FALSE) {
893 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
894 OMX_PTR codecBuffer;
895 if ((pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) {
896 Exynos_CodecBufferDequeue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
897 if (codecBuffer != NULL) {
898 Exynos_Input_CodecBufferToData(pExynosComponent, codecBuffer, pSrcInputData);
899 }
900 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
901 break;
902 }
903 }
904
905 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
906 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
907 } else {
908 bCheckInputData = OMX_FALSE;
909 }
910 }
911 if ((bCheckInputData == OMX_FALSE) &&
912 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
913 ret = Exynos_InputBufferGetQueue(pExynosComponent);
914 #ifdef USE_METADATABUFFERTYPE
915 if (ret != OMX_ErrorNone) {
916 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
917 break;
918 }
919
920 if ((pVideoEnc->bFirstInput == OMX_TRUE) &&
921 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
922 Exynos_OMX_ExtensionSetup(hComponent);
923 pVideoEnc->bFirstInput = OMX_FALSE;
924 }
925 #endif
926 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
927 break;
928 }
929
930 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
931 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
932 break;
933 }
934
935 ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
936 Exynos_ResetCodecData(pSrcInputData);
937 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
938 if (ret == OMX_ErrorCodecInit)
939 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
940 }
941 }
942
943 EXIT:
944
945 FunctionOut();
946
947 return ret;
948 }
949
950 OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
951 {
952 OMX_ERRORTYPE ret = OMX_ErrorNone;
953 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
954 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
955 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
956 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
957 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
958 EXYNOS_OMX_DATA srcOutputData;
959
960 FunctionIn();
961
962 while (!pVideoEnc->bExitBufferProcessThread) {
963 Exynos_OSAL_SleepMillisec(0);
964
965 while (!pVideoEnc->bExitBufferProcessThread) {
966 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
967 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
968 break;
969 }
970 Exynos_OSAL_SleepMillisec(0);
971
972 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
973 break;
974
975 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
976 ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
977
978 if (ret == OMX_ErrorNone) {
979 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
980 OMX_PTR codecBuffer;
981 codecBuffer = srcOutputData.pPrivate;
982 if (codecBuffer != NULL)
983 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
984 }
985 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
986 OMX_BOOL bNeedUnlock = OMX_FALSE;
987 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
988 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque)
989 bNeedUnlock = OMX_TRUE;
990 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer, bNeedUnlock);
991 Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
992 }
993 Exynos_ResetCodecData(&srcOutputData);
994 }
995 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
996 }
997 }
998
999 EXIT:
1000
1001 FunctionOut();
1002
1003 return ret;
1004 }
1005
1006 OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
1007 {
1008 OMX_ERRORTYPE ret = OMX_ErrorNone;
1009 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1010 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1011 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1012 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1013 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
1014 EXYNOS_OMX_DATA dstInputData;
1015
1016 FunctionIn();
1017
1018 while (!pVideoEnc->bExitBufferProcessThread) {
1019 Exynos_OSAL_SleepMillisec(0);
1020
1021 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1022 (!pVideoEnc->bExitBufferProcessThread)) {
1023 Exynos_OSAL_SleepMillisec(0);
1024
1025 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
1026 (!CHECK_PORT_POPULATED(exynosOutputPort)))
1027 break;
1028 if (exynosOutputPort->portState != OMX_StateIdle)
1029 break;
1030
1031 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
1032 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1033 CODEC_ENC_BUFFER *pCodecBuffer = NULL;
1034 ret = Exynos_CodecBufferDequeue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
1035 if (ret != OMX_ErrorNone) {
1036 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1037 break;
1038 }
1039 Exynos_Output_CodecBufferToData(pCodecBuffer, &dstInputData);
1040 }
1041
1042 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1043 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
1044 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1045 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1046 if (ret != OMX_ErrorNone) {
1047 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1048 break;
1049 }
1050 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE);
1051 if (pVideoEnc->bDRMPlayerMode == OMX_TRUE) {
1052 OMX_PTR dataBuffer = NULL;
1053 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory,
1054 dstInputData.buffer.singlePlaneBuffer.dataBuffer);
1055 if (dataBuffer == NULL) {
1056 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Secure buffer", __LINE__);
1057 ret = OMX_ErrorUndefined;
1058 break;
1059 }
1060 dstInputData.buffer.singlePlaneBuffer.fd =
1061 dstInputData.buffer.singlePlaneBuffer.dataBuffer;
1062 dstInputData.buffer.singlePlaneBuffer.dataBuffer = dataBuffer;
1063 } else {
1064 dstInputData.buffer.singlePlaneBuffer.fd =
1065 Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory,
1066 dstInputData.buffer.singlePlaneBuffer.dataBuffer);
1067 }
1068 Exynos_ResetDataBuffer(dstInputUseBuffer);
1069 }
1070 }
1071
1072 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
1073 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1074 break;
1075 }
1076 ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
1077
1078 Exynos_ResetCodecData(&dstInputData);
1079 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1080 }
1081 }
1082
1083 EXIT:
1084
1085 FunctionOut();
1086
1087 return ret;
1088 }
1089
1090 OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
1091 {
1092 OMX_ERRORTYPE ret = OMX_ErrorNone;
1093 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1094 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1095 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1096 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1097 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
1098 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
1099
1100 FunctionIn();
1101
1102 while (!pVideoEnc->bExitBufferProcessThread) {
1103 Exynos_OSAL_SleepMillisec(0);
1104 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
1105
1106 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1107 (!pVideoEnc->bExitBufferProcessThread)) {
1108 Exynos_OSAL_SleepMillisec(0);
1109
1110 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
1111 break;
1112
1113 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
1114 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1115 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
1116 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1117 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1118 if (ret != OMX_ErrorNone) {
1119 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1120 break;
1121 }
1122 }
1123 }
1124
1125 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
1126 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
1127 ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
1128
1129 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
1130 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
1131 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
1132 }
1133
1134 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1135 if (pDstOutputData->pPrivate != NULL) {
1136 Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
1137 pDstOutputData->pPrivate = NULL;
1138 }
1139 }
1140
1141 /* reset outputData */
1142 Exynos_ResetCodecData(pDstOutputData);
1143 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1144 }
1145 }
1146
1147 EXIT:
1148
1149 FunctionOut();
1150
1151 return ret;
1152 }
1153
1154 static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
1155 {
1156 OMX_ERRORTYPE ret = OMX_ErrorNone;
1157 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1158 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1159 EXYNOS_OMX_MESSAGE *message = NULL;
1160
1161 FunctionIn();
1162
1163 if (threadData == NULL) {
1164 ret = OMX_ErrorBadParameter;
1165 goto EXIT;
1166 }
1167 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1168 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1169 if (ret != OMX_ErrorNone) {
1170 goto EXIT;
1171 }
1172 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1173 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1174
1175 Exynos_OSAL_ThreadExit(NULL);
1176
1177 EXIT:
1178 FunctionOut();
1179
1180 return ret;
1181 }
1182
1183 static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1184 {
1185 OMX_ERRORTYPE ret = OMX_ErrorNone;
1186 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1187 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1188 EXYNOS_OMX_MESSAGE *message = NULL;
1189
1190 FunctionIn();
1191
1192 if (threadData == NULL) {
1193 ret = OMX_ErrorBadParameter;
1194 goto EXIT;
1195 }
1196 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1197 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1198 if (ret != OMX_ErrorNone) {
1199 goto EXIT;
1200 }
1201 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1202 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1203
1204 Exynos_OSAL_ThreadExit(NULL);
1205
1206 EXIT:
1207 FunctionOut();
1208
1209 return ret;
1210 }
1211
1212 static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1213 {
1214 OMX_ERRORTYPE ret = OMX_ErrorNone;
1215 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1216 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1217 EXYNOS_OMX_MESSAGE *message = NULL;
1218
1219 FunctionIn();
1220
1221 if (threadData == NULL) {
1222 ret = OMX_ErrorBadParameter;
1223 goto EXIT;
1224 }
1225 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1226 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1227 if (ret != OMX_ErrorNone) {
1228 goto EXIT;
1229 }
1230 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1231 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1232
1233 Exynos_OSAL_ThreadExit(NULL);
1234
1235 EXIT:
1236 FunctionOut();
1237
1238 return ret;
1239 }
1240
1241 static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1242 {
1243 OMX_ERRORTYPE ret = OMX_ErrorNone;
1244 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1245 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1246 EXYNOS_OMX_MESSAGE *message = NULL;
1247
1248 FunctionIn();
1249
1250 if (threadData == NULL) {
1251 ret = OMX_ErrorBadParameter;
1252 goto EXIT;
1253 }
1254 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1255 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1256 if (ret != OMX_ErrorNone) {
1257 goto EXIT;
1258 }
1259 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1260 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1261
1262 Exynos_OSAL_ThreadExit(NULL);
1263
1264 EXIT:
1265 FunctionOut();
1266
1267 return ret;
1268 }
1269
1270 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1271 {
1272 OMX_ERRORTYPE ret = OMX_ErrorNone;
1273 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1274 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1275 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1276
1277 FunctionIn();
1278
1279 pVideoEnc->bExitBufferProcessThread = OMX_FALSE;
1280
1281 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread,
1282 Exynos_OMX_DstOutputProcessThread,
1283 pOMXComponent);
1284 if (ret == OMX_ErrorNone)
1285 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread,
1286 Exynos_OMX_SrcOutputProcessThread,
1287 pOMXComponent);
1288 if (ret == OMX_ErrorNone)
1289 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread,
1290 Exynos_OMX_DstInputProcessThread,
1291 pOMXComponent);
1292 if (ret == OMX_ErrorNone)
1293 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread,
1294 Exynos_OMX_SrcInputProcessThread,
1295 pOMXComponent);
1296
1297 EXIT:
1298 FunctionOut();
1299
1300 return ret;
1301 }
1302
1303 OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1304 {
1305 OMX_ERRORTYPE ret = OMX_ErrorNone;
1306 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1307 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1308 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1309 OMX_S32 countValue = 0;
1310 unsigned int i = 0;
1311
1312 FunctionIn();
1313
1314 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
1315
1316 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1317 if (countValue == 0)
1318 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1319 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1320 if (countValue == 0)
1321 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1322 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1323 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread);
1324 pVideoEnc->hSrcInputThread = NULL;
1325
1326 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1327 if (countValue == 0)
1328 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1329 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1330 if (countValue == 0)
1331 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1332 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1333 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread);
1334 pVideoEnc->hDstInputThread = NULL;
1335
1336 pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1337 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1338 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1339 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread);
1340 pVideoEnc->hSrcOutputThread = NULL;
1341
1342 pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1343 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1344 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1345 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread);
1346 pVideoEnc->hDstOutputThread = NULL;
1347
1348 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
1349 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
1350
1351 EXIT:
1352 FunctionOut();
1353
1354 return ret;
1355 }
1356
1357 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1358 {
1359 OMX_ERRORTYPE ret = OMX_ErrorNone;
1360 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1361 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1362 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1363 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1364
1365 FunctionIn();
1366
1367 if (hComponent == NULL) {
1368 ret = OMX_ErrorBadParameter;
1369 goto EXIT;
1370 }
1371 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1372 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1373 if (ret != OMX_ErrorNone) {
1374 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1375 goto EXIT;
1376 }
1377
1378 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1379 if (ret != OMX_ErrorNone) {
1380 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1381 goto EXIT;
1382 }
1383
1384 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1385 if (ret != OMX_ErrorNone) {
1386 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1387 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1388 goto EXIT;
1389 }
1390
1391 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1392
1393 pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1394 if (pVideoEnc == NULL) {
1395 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1396 ret = OMX_ErrorInsufficientResources;
1397 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1398 goto EXIT;
1399 }
1400
1401 Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1402 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
1403
1404 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1405 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1406
1407 pVideoEnc->bFirstInput = OMX_FALSE;
1408 pVideoEnc->bFirstOutput = OMX_FALSE;
1409 pVideoEnc->configChange = OMX_FALSE;
1410 pVideoEnc->bQosChanged = OMX_FALSE;
1411 pVideoEnc->nQosRatio = 0;
1412 pVideoEnc->nInbufSpareSize = 0;
1413 pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter
1414 pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
1415 pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
1416 pVideoEnc->bRGBSupport = OMX_FALSE;
1417
1418 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1419
1420 /* Input port */
1421 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1422 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1423 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1424 pExynosPort->portDefinition.nBufferSize = 0;
1425 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1426
1427 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1428 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1429 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1430 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1431 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1432
1433 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1434 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1435 pExynosPort->portDefinition.format.video.nStride = 0;
1436 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1437 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1438 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1439 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1440 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1441 pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateDisable;
1442
1443 pExynosPort->bStoreMetaData = OMX_FALSE;
1444 pExynosPort->processData.extInfo = (OMX_PTR)Exynos_OSAL_Malloc(sizeof(ENCODE_CODEC_EXTRA_BUFFERINFO));
1445 ((ENCODE_CODEC_EXTRA_BUFFERINFO *)(pExynosPort->processData.extInfo))->eColorFormat = OMX_COLOR_FormatUnused;
1446
1447 /* Output port */
1448 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1449 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1450 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1451 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1452 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1453
1454 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1455 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1456 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1457 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1458 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1459
1460 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1461 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1462 pExynosPort->portDefinition.format.video.nStride = 0;
1463 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1464 pExynosPort->portDefinition.format.video.nBitrate = 64000;
1465 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1466 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1467 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1468 pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateDisable;
1469
1470 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1471 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1472 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1473 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1474
1475 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1476 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1477 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1478 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1479 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1480
1481 EXIT:
1482 FunctionOut();
1483
1484 return ret;
1485 }
1486
1487 OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1488 {
1489 OMX_ERRORTYPE ret = OMX_ErrorNone;
1490 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1491 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1492 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1493 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1494 int i = 0;
1495
1496 FunctionIn();
1497
1498 if (hComponent == NULL) {
1499 ret = OMX_ErrorBadParameter;
1500 goto EXIT;
1501 }
1502 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1503 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1504 if (ret != OMX_ErrorNone) {
1505 goto EXIT;
1506 }
1507
1508 if (pOMXComponent->pComponentPrivate == NULL) {
1509 ret = OMX_ErrorBadParameter;
1510 goto EXIT;
1511 }
1512 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1513
1514 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1515
1516 Exynos_OSAL_Free(pVideoEnc);
1517 pExynosComponent->hComponentHandle = pVideoEnc = NULL;
1518
1519 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1520 if (pExynosPort->processData.extInfo != NULL) {
1521 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
1522 pExynosPort->processData.extInfo = NULL;
1523 }
1524
1525 for(i = 0; i < ALL_PORT_NUM; i++) {
1526 pExynosPort = &pExynosComponent->pExynosPort[i];
1527 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
1528 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
1529 }
1530
1531 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
1532
1533 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
1534
1535 EXIT:
1536 FunctionOut();
1537
1538 return ret;
1539 }