import exynos 7570 bsp
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / enc / Exynos_OMX_Venc.c
CommitLineData
a9bdc01e
T
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_METADATABUFFERTYPE
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#include "Exynos_OSAL_Log.h"
52
53inline void Exynos_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent)
54{
55 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
56 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
57 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
58
59 exynosInputPort->portDefinition.nBufferSize = ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16) *
60 ALIGN(exynosInputPort->portDefinition.format.video.nFrameHeight, 16) * 3 / 2;
61
62 if ((exynosOutputPort->portDefinition.format.video.nFrameWidth !=
63 exynosInputPort->portDefinition.format.video.nFrameWidth) ||
64 (exynosOutputPort->portDefinition.format.video.nFrameHeight !=
65 exynosInputPort->portDefinition.format.video.nFrameHeight)) {
66 OMX_U32 width = 0, height = 0;
67
68 exynosOutputPort->portDefinition.format.video.nFrameWidth =
69 exynosInputPort->portDefinition.format.video.nFrameWidth;
70 exynosOutputPort->portDefinition.format.video.nFrameHeight =
71 exynosInputPort->portDefinition.format.video.nFrameHeight;
72 width = exynosOutputPort->portDefinition.format.video.nStride =
73 exynosInputPort->portDefinition.format.video.nStride;
74 height = exynosOutputPort->portDefinition.format.video.nSliceHeight =
75 exynosInputPort->portDefinition.format.video.nSliceHeight;
76
77 if (width && height)
78 exynosOutputPort->portDefinition.nBufferSize = ALIGN((ALIGN(width, 16) * ALIGN(height, 16) * 3) / 2, 512);
79 }
80
81 return;
82}
83
84void Exynos_Input_SetSupportFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
85{
86 OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
87 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
88 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
89
90 if ((pVideoEnc == NULL) || (pInputPort == NULL))
91 return ;
92
93 if (pInputPort->supportFormat != NULL) {
94 OMX_BOOL ret = OMX_FALSE;
95 int nLastIndex = INPUT_PORT_SUPPORTFORMAT_DEFAULT_NUM;
96 int i;
97
98 /* default supported formats */
99 pInputPort->supportFormat[0] = OMX_COLOR_FormatYUV420Planar;
100 pInputPort->supportFormat[1] = OMX_COLOR_FormatYUV420SemiPlanar;
101 pInputPort->supportFormat[2] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV21Linear;
102 pInputPort->supportFormat[3] = OMX_COLOR_Format32bitARGB8888;
103 pInputPort->supportFormat[4] = (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888;
104#ifdef USE_ANDROIDOPAQUE
105 pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_FormatAndroidOpaque;
106#endif
107
108 /* add extra formats, if It is supported by H/W. (CSC doesn't exist) */
109 /* OMX_SEC_COLOR_FormatNV12Tiled */
110 ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
111 (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled);
112 if (ret == OMX_TRUE)
113 pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled;
114
115 /* OMX_SEC_COLOR_FormatYVU420Planar */
116 ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent,
117 (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar);
118 if (ret == OMX_TRUE)
119 pInputPort->supportFormat[nLastIndex++] = (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatYVU420Planar;
120
121 /* OMX_COLOR_Format32bitBGRA8888 */
122 ret = pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, OMX_COLOR_Format32bitBGRA8888);
123 if (ret == OMX_TRUE)
124 pInputPort->supportFormat[nLastIndex++] = OMX_COLOR_Format32bitBGRA8888;
125
126 for (i = 0; i < nLastIndex; i++)
127 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Support Format[%d] : 0x%x", i, pInputPort->supportFormat[i]);
128
129 pInputPort->supportFormat[nLastIndex] = OMX_COLOR_FormatUnused;
130 }
131
132 return ;
133}
134
135OMX_COLOR_FORMATTYPE Exynos_Input_GetActualColorFormat(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
136{
137 OMX_COLOR_FORMATTYPE ret = OMX_COLOR_FormatUnused;
138 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
139 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
140 OMX_COLOR_FORMATTYPE eColorFormat = pInputPort->portDefinition.format.video.eColorFormat;
141
142#ifdef USE_ANDROIDOPAQUE
143 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
144 eColorFormat = pVideoEnc->ANBColorFormat;
145#endif
146
147 if (pVideoEnc->exynos_codec_checkFormatSupport(pExynosComponent, eColorFormat) == OMX_TRUE) {
148 ret = eColorFormat;
149 goto EXIT;
150 }
151
152 switch ((int)eColorFormat) {
153 case OMX_COLOR_FormatYUV420SemiPlanar:
154 case OMX_COLOR_FormatYUV420Planar: /* converted to NV12 using CSC */
155 case OMX_COLOR_Format32bitARGB8888: /* converted to NV12 using CSC */
156 case OMX_COLOR_Format32BitRGBA8888: /* converted to NV12 using CSC */
157 ret = OMX_COLOR_FormatYUV420SemiPlanar;
158 break;
159 case OMX_SEC_COLOR_FormatNV21Linear:
160 case OMX_SEC_COLOR_FormatNV12Tiled:
161 ret = eColorFormat;
162 break;
163 default:
164 ret = OMX_COLOR_FormatUnused;
165 break;
166 }
167
168EXIT:
169 return ret;
170}
171
172void Exynos_Free_CodecBuffers(
173 OMX_COMPONENTTYPE *pOMXComponent,
174 OMX_U32 nPortIndex)
175{
176 OMX_ERRORTYPE ret = OMX_ErrorNone;
177 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
178 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
179 CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
180
181 int nBufferCnt = 0, nPlaneCnt = 0;
182 int i, j;
183
184 FunctionIn();
185
186 if (nPortIndex == INPUT_PORT_INDEX) {
187 ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
188 nBufferCnt = MFC_INPUT_BUFFER_NUM_MAX;
189 } else {
190 ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
191 nBufferCnt = MFC_OUTPUT_BUFFER_NUM_MAX;
192 }
193
194 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
195 for (i = 0; i < nBufferCnt; i++) {
196 if (ppCodecBuffer[i] != NULL) {
197 for (j = 0; j < nPlaneCnt; j++) {
198 if (ppCodecBuffer[i]->pVirAddr[j] != NULL)
199 Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
200 }
201
202 Exynos_OSAL_Free(ppCodecBuffer[i]);
203 ppCodecBuffer[i] = NULL;
204 }
205 }
206
207 FunctionOut();
208}
209
210OMX_ERRORTYPE Exynos_Allocate_CodecBuffers(
211 OMX_COMPONENTTYPE *pOMXComponent,
212 OMX_U32 nPortIndex,
213 int nBufferCnt,
214 unsigned int nAllocLen[MAX_BUFFER_PLANE])
215{
216 OMX_ERRORTYPE ret = OMX_ErrorNone;
217 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
218 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
219 MEMORY_TYPE eMemoryType = CACHED_MEMORY;
220 CODEC_ENC_BUFFER **ppCodecBuffer = NULL;
221
222 int nPlaneCnt = 0;
223 int i, j;
224
225 FunctionIn();
226
227 if (nPortIndex == INPUT_PORT_INDEX) {
228 ppCodecBuffer = &(pVideoEnc->pMFCEncInputBuffer[0]);
229 } else {
230 ppCodecBuffer = &(pVideoEnc->pMFCEncOutputBuffer[0]);
231#ifdef USE_CSC_HW
232 eMemoryType = NORMAL_MEMORY;
233#endif
234 }
235
236 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
237
238 if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC)
239 eMemoryType = SECURE_MEMORY;
240
241 for (i = 0; i < nBufferCnt; i++) {
242 ppCodecBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
243 if (ppCodecBuffer[i] == NULL) {
244 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
245 ret = OMX_ErrorInsufficientResources;
246 goto EXIT;
247 }
248 Exynos_OSAL_Memset(ppCodecBuffer[i], 0, sizeof(CODEC_ENC_BUFFER));
249
250 for (j = 0; j < nPlaneCnt; j++) {
251 ppCodecBuffer[i]->pVirAddr[j] =
252 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nAllocLen[j], eMemoryType);
253 if (ppCodecBuffer[i]->pVirAddr[j] == NULL) {
254 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc plane");
255 ret = OMX_ErrorInsufficientResources;
256 goto EXIT;
257 }
258
259 ppCodecBuffer[i]->fd[j] =
260 Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, ppCodecBuffer[i]->pVirAddr[j]);
261 ppCodecBuffer[i]->bufferSize[j] = nAllocLen[j];
262 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PORT[%d]: pMFCCodecBuffer[%d]->pVirAddr[%d]: 0x%x", nPortIndex, i, j, ppCodecBuffer[i]->pVirAddr[j]);
263 }
264
265 ppCodecBuffer[i]->dataSize = 0;
266 }
267
268 return OMX_ErrorNone;
269
270EXIT:
271 Exynos_Free_CodecBuffers(pOMXComponent, nPortIndex);
272
273 FunctionOut();
274
275 return ret;
276}
277
278OMX_BOOL Exynos_Check_BufferProcess_State(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
279{
280 OMX_BOOL ret = OMX_FALSE;
281
282 if ((pExynosComponent->currentState == OMX_StateExecuting) &&
283 (pExynosComponent->pExynosPort[nPortIndex].portState == OMX_StateIdle) &&
284 (pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
285 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToExecuting)) {
286 ret = OMX_TRUE;
287 } else {
288 ret = OMX_FALSE;
289 }
290
291 return ret;
292}
293
294OMX_ERRORTYPE Exynos_ResetAllPortConfig(OMX_COMPONENTTYPE *pOMXComponent)
295{
296 OMX_ERRORTYPE ret = OMX_ErrorNone;
297 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
298 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
299 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
300
301 /* Input port */
302 pInputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
303 pInputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
304 pInputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
305 pInputPort->portDefinition.format.video.nSliceHeight = 0;
306 pInputPort->portDefinition.format.video.pNativeRender = 0;
307 pInputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
308 pInputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
309
310 pInputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
311 pInputPort->portDefinition.bEnabled = OMX_TRUE;
312
313 pInputPort->bufferProcessType = BUFFER_COPY;
314 pInputPort->portWayType = WAY2_PORT;
315 Exynos_SetPlaneToPort(pInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
316
317 /* Output port */
318 pOutputPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
319 pOutputPort->portDefinition.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
320 pOutputPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
321 pOutputPort->portDefinition.format.video.nSliceHeight = 0;
322 pOutputPort->portDefinition.format.video.pNativeRender = 0;
323 pOutputPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
324 pOutputPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
325
326 pOutputPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
327 pOutputPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
328 pOutputPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
329 pOutputPort->portDefinition.bEnabled = OMX_TRUE;
330
331 pOutputPort->bufferProcessType = BUFFER_SHARE;
332 pOutputPort->portWayType = WAY2_PORT;
333 pOutputPort->latestTimeStamp = DEFAULT_TIMESTAMP_VAL;
334 Exynos_SetPlaneToPort(pOutputPort, Exynos_OSAL_GetPlaneCount(OMX_COLOR_FormatYUV420Planar, pOutputPort->ePlaneType));
335
336 /* remove a configuration command that is in piled up */
337 while (Exynos_OSAL_GetElemNum(&pExynosComponent->dynamicConfigQ) > 0) {
338 OMX_PTR pDynamicConfigCMD = NULL;
339 pDynamicConfigCMD = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosComponent->dynamicConfigQ);
340 Exynos_OSAL_Free(pDynamicConfigCMD);
341 }
342
343 return ret;
344}
345
346OMX_ERRORTYPE Exynos_CodecBufferToData(
347 CODEC_ENC_BUFFER *pCodecBuffer,
348 EXYNOS_OMX_DATA *pData,
349 OMX_U32 nPortIndex)
350{
351 OMX_ERRORTYPE ret = OMX_ErrorNone;
352 int i;
353
354 if (nPortIndex > OUTPUT_PORT_INDEX) {
355 ret = OMX_ErrorBadPortIndex;
356 goto EXIT;
357 }
358
359 pData->allocSize = 0;
360 pData->usedDataLen = 0;
361 pData->nFlags = 0;
362 pData->timeStamp = 0;
363 pData->pPrivate = pCodecBuffer;
364 pData->bufferHeader = NULL;
365
366 for (i = 0; i < MAX_BUFFER_PLANE; i++) {
367 pData->multiPlaneBuffer.dataBuffer[i] = pCodecBuffer->pVirAddr[i];
368 pData->multiPlaneBuffer.fd[i] = pCodecBuffer->fd[i];
369 pData->allocSize += pCodecBuffer->bufferSize[i];
370 }
371
372 if (nPortIndex == INPUT_PORT_INDEX) {
373 pData->dataLen = pCodecBuffer->dataSize;
374 pData->remainDataLen = pCodecBuffer->dataSize;
375 } else {
376 pData->dataLen = 0;
377 pData->remainDataLen = 0;
378 }
379
380EXIT:
381 return ret;
382}
383
384void Exynos_Wait_ProcessPause(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 nPortIndex)
385{
386 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
387 EXYNOS_OMX_BASEPORT *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
388 EXYNOS_OMX_BASEPORT *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
389 EXYNOS_OMX_BASEPORT *exynosOMXPort = NULL;
390
391 FunctionIn();
392
393 exynosOMXPort = &pExynosComponent->pExynosPort[nPortIndex];
394
395 if (((pExynosComponent->currentState == OMX_StatePause) ||
396 (pExynosComponent->currentState == OMX_StateIdle) ||
397 (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) ||
398 (pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle)) &&
399 (pExynosComponent->transientState != EXYNOS_OMX_TransStateIdleToLoaded) &&
400 (!CHECK_PORT_BEING_FLUSHED(exynosOMXPort))) {
401 Exynos_OSAL_SignalWait(pExynosComponent->pExynosPort[nPortIndex].pauseEvent, DEF_MAX_WAIT_TIME);
402 if (pVideoEnc->bExitBufferProcessThread)
403 goto EXIT;
404
405 Exynos_OSAL_SignalReset(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
406 }
407
408EXIT:
409 FunctionOut();
410
411 return;
412}
413
414OMX_BOOL Exynos_CSC_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
415{
416 OMX_BOOL ret = OMX_FALSE;
417 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
418 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
419 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
420 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
421 CODEC_ENC_BUFFER *codecInputBuffer = (CODEC_ENC_BUFFER *)srcInputData->pPrivate;
422 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
423 OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
424
425 FunctionIn();
426
427 void *pInputBuf = (void *)inputUseBuffer->bufferHeader->pBuffer;
428 void *pSrcBuf[MAX_BUFFER_PLANE] = {NULL, };
429 void *pDstBuf[MAX_BUFFER_PLANE] = {NULL, };
430
431 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
432 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
433 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
434 OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
435
436 OMX_U32 nSrcFrameWidth = 0, nSrcFrameHeight = 0;
437 OMX_U32 nSrcImageWidth = 0, nSrcImageHeight = 0, stride = 0;
438
439 OMX_U32 nDstFrameWidth = 0, nDstFrameHeight = 0;
440 OMX_U32 nDstImageWidth = 0, nDstImageHeight = 0;
441 int i, nPlaneCnt;
442
443 CSC_ERRORCODE cscRet = CSC_ErrorNone;
444 CSC_METHOD csc_method = CSC_METHOD_SW;
445 CSC_MEMTYPE csc_memType = CSC_MEMORY_USERPTR;
446 unsigned int srcCacheable = 1, dstCacheable = 1;
447 unsigned int csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar, PLANE_SINGLE_USER);
448 unsigned int csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)OMX_COLOR_FormatYUV420SemiPlanar, exynosInputPort->ePlaneType);
449
450 nDstFrameWidth = nSrcFrameWidth = ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16);
451 nDstImageWidth = nSrcImageWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
452 nDstFrameHeight = nDstImageHeight = nSrcFrameHeight = nSrcImageHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
453
454 if ((pVideoEnc->eRotationType == ROTATE_90) ||
455 (pVideoEnc->eRotationType == ROTATE_270)) {
456 nDstFrameWidth = ALIGN(exynosInputPort->portDefinition.format.video.nFrameHeight, 16);
457 nDstImageWidth = exynosInputPort->portDefinition.format.video.nFrameHeight;
458 nDstFrameHeight = nDstImageHeight = exynosInputPort->portDefinition.format.video.nFrameWidth;
459 }
460
461 csc_get_method(pVideoEnc->csc_handle, &csc_method);
462
463 /* blur filtering and rotation are supported by H/W */
464 if (((pVideoEnc->bUseBlurFilter == OMX_TRUE) ||
465 (pVideoEnc->eRotationType != ROTATE_0)) &&
466 (csc_method == CSC_METHOD_SW)) {
467 cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
468 if (cscRet != CSC_ErrorNone) {
469 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_HW) is failed", __FUNCTION__);
470 ret = OMX_FALSE;
471 goto EXIT;
472 }
473
474 csc_method = CSC_METHOD_HW;
475 }
476
477 /* setup dst buffer */
478 pDstBuf[0] = srcInputData->multiPlaneBuffer.dataBuffer[0];
479 pDstBuf[1] = srcInputData->multiPlaneBuffer.dataBuffer[1];
480 pDstBuf[2] = srcInputData->multiPlaneBuffer.dataBuffer[2];
481
482 inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
483 Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nDstImageWidth, nDstImageHeight, nDataLen, nAllocLen);
484 codecInputBuffer->dataSize = 0;
485 nPlaneCnt = Exynos_GetPlaneFromPort(exynosInputPort);
486 for (i = 0; i < nPlaneCnt; i++)
487 codecInputBuffer->dataSize += nDataLen[i];
488
489 if (exynosInputPort->ePlaneType == PLANE_SINGLE) { /* for H/W. only Y addr is valid */
490 /* get a count of color plane */
491 int nPlaneCnt = Exynos_OSAL_GetPlaneCount(inputColorFormat, PLANE_MULTIPLE);
492
493 if (nPlaneCnt == 2) { /* Semi-Planar : interleaved */
494 pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_UV_OFFSET(nDstImageWidth, nDstImageHeight));
495 } else if (nPlaneCnt == 3) { /* Planar */
496 pDstBuf[1] = (void *)(((char *)pDstBuf[0]) + GET_CB_OFFSET(nDstImageWidth, nDstImageHeight));
497 pDstBuf[2] = (void *)(((char *)pDstBuf[0]) + GET_CR_OFFSET(nDstImageWidth, nDstImageHeight));
498 }
499 }
500
501 /* setup src buffer */
502#ifdef USE_METADATABUFFERTYPE
503 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
504 /* 1. meta data is enabled
505 *
506 * 1) gralloc source
507 * 2) camera source
508 */
509 if (OMX_ErrorNone != Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf)) {
510 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
511 ret = OMX_FALSE;
512 goto EXIT;
513 }
514
515#ifdef USE_ANDROIDOPAQUE
516 /* 1-1) gralloc source
517 * -> kMetadataBufferTypeGrallocSource
518 * -> when format is not supported at H/W codec
519 */
520 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
521 OMX_COLOR_FORMATTYPE eDestFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
522
523 csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType);
524 csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eDestFormat, exynosInputPort->ePlaneType);
525
526 if (OMX_ErrorNone != Exynos_OSAL_LockANBHandle(ppBuf[0], nSrcImageWidth, nSrcImageHeight, OMX_COLOR_FormatAndroidOpaque, &stride, planes)) {
527 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_LockANBHandle() failed", __FUNCTION__);
528 ret = OMX_FALSE;
529 goto EXIT;
530 }
531
532#ifdef USE_HW_CSC_GRALLOC_SOURCE
533#ifdef USE_FIMC_CSC
534 if ((csc_method != CSC_METHOD_HW) &&
535 (pVideoEnc->ANBColorFormat != (OMX_COLOR_FORMATTYPE)OMX_COLOR_Format32BitRGBA8888))
536#else
537 if (csc_method != CSC_METHOD_HW)
538#endif // USE_FIMC_CSC
539 {
540 cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_HW);
541 if (cscRet != CSC_ErrorNone) {
542 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_HW) is failed", __FUNCTION__);
543 ret = OMX_FALSE;
544 goto EXIT;
545 }
546 csc_method = CSC_METHOD_HW;
547 }
548#endif // USE_HW_CSC_GRALLOC_SOURCE
549
550 pSrcBuf[0] = (void *)planes[0].addr;
551 pSrcBuf[1] = (void *)planes[1].addr;
552 pSrcBuf[2] = (void *)planes[2].addr;
553
554#ifdef USE_DMA_BUF
555 if (csc_method == CSC_METHOD_HW) {
556 srcCacheable = 0;
557 csc_memType = CSC_MEMORY_DMABUF;
558 pSrcBuf[0] = INT_TO_PTR(planes[0].fd);
559 pSrcBuf[1] = INT_TO_PTR(planes[1].fd);
560 pSrcBuf[2] = INT_TO_PTR(planes[2].fd);
561 }
562#endif // USE_DMA_BUF
563 } else
564#endif // USE_ANDROIDOPAQUE
565 {
566 /* 1-2) camera source
567 * -> kMetadataBufferTypeCameraSource
568 * -> when blur filter or rotation mode is enabled
569 */
570 csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, exynosInputPort->ePlaneType);
571 csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, exynosInputPort->ePlaneType);
572
573#ifdef USE_DMA_BUF
574 if (csc_method == CSC_METHOD_HW) {
575 srcCacheable = 0;
576 csc_memType = CSC_MEMORY_DMABUF;
577 pSrcBuf[0] = INT_TO_PTR(ppBuf[0]);
578 pSrcBuf[1] = INT_TO_PTR(ppBuf[1]);
579 pSrcBuf[2] = INT_TO_PTR(ppBuf[2]);
580 } else
581#endif // USE_DMA_BUF
582 { /* CSC_METHOD_SW */
583 Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nSrcImageWidth, nSrcImageHeight, nDataLen, nAllocLen);
584 for (i = 0; i < nPlaneCnt; i++) {
585 if (PTR_TO_INT(ppBuf[i]) != -1) {
586 pSrcBuf[i] = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, PTR_TO_INT(ppBuf[i]));
587 if(pSrcBuf[i] == NULL)
588 pSrcBuf[i] = Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[i], PTR_TO_INT(ppBuf[i]));
589
590 if (pSrcBuf[i] == NULL) {
591 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Exynos_OSAL_SharedMemory_Map(%d) is failed", __FUNCTION__, PTR_TO_INT(ppBuf[i]));
592 ret = OMX_FALSE;
593 goto EXIT;
594 }
595 }
596 }
597 }
598 }
599 } else
600#endif // USE_USE_METADATABUFFERTYPE
601 {
602 /* 2. meta data is not enabled
603 *
604 * 1) format is supported at HW codec
605 * uses SW CSC for satisfying HW constraints except for blur, rotation mode and USE_CSC_HW.
606 * * blur, rotation is supported by HW.
607 * 2) format is not supported at HW codec
608 * needs CSC(Color-Space-Conversion).
609 */
610 /* calculate each plane info from the application */
611 Exynos_OSAL_GetPlaneSize(eColorFormat, PLANE_SINGLE_USER, nSrcImageWidth, nSrcImageHeight, nDataLen, nAllocLen);
612 pSrcBuf[0] = (void *)((char *)pInputBuf);
613 pSrcBuf[1] = (void *)((char *)pInputBuf + nDataLen[0]);
614 pSrcBuf[2] = (void *)((char *)pInputBuf + nDataLen[0] + nDataLen[1]);
615
616#ifdef USE_CSC_HW
617 if ((pVideoEnc->bUseBlurFilter != OMX_TRUE) &&
618 (pVideoEnc->eRotationType == ROTATE_0) &&
619 (csc_method != CSC_METHOD_HW) &&
620 (eColorFormat == inputColorFormat)) {
621#else
622 if ((pVideoEnc->bUseBlurFilter != OMX_TRUE) &&
623 (pVideoEnc->eRotationType == ROTATE_0) &&
624 (eColorFormat == inputColorFormat)) {
625#endif
626 csc_memType = CSC_MEMORY_MFC; /* to remove stride value */
627 csc_method = CSC_METHOD_SW;
628
629 cscRet = csc_set_method(pVideoEnc->csc_handle, CSC_METHOD_SW);
630 if (cscRet != CSC_ErrorNone) {
631 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: csc_set_method(CSC_METHOD_SW) for CSC_MEMORY_MFC is failed", __FUNCTION__);
632 ret = OMX_FALSE;
633 goto EXIT;
634 }
635 }
636
637 if (pVideoEnc->csc_set_format == OMX_FALSE) {
638 csc_src_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)eColorFormat, PLANE_SINGLE_USER);
639 csc_dst_color_format = Exynos_OSAL_OMX2HALPixelFormat((unsigned int)inputColorFormat, exynosInputPort->ePlaneType);
640 }
641
642#ifdef USE_DMA_BUF
643 if (csc_method == CSC_METHOD_HW) {
644 srcCacheable = 0;
645 csc_memType = CSC_MEMORY_DMABUF;
646 pSrcBuf[0] = INT_TO_PTR(Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, (char *)pInputBuf));
647 pSrcBuf[1] = NULL;
648 pSrcBuf[2] = NULL;
649 }
650#endif
651 }
652
653 /* re-check a csc_method and setup dst buffer */
654#ifdef USE_DMA_BUF
655 if (csc_method == CSC_METHOD_HW) {
656 dstCacheable = 0;
657 csc_memType = CSC_MEMORY_DMABUF;
658 pDstBuf[0] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[0]);
659 pDstBuf[1] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[1]);
660 pDstBuf[2] = INT_TO_PTR(srcInputData->multiPlaneBuffer.fd[2]);
661 }
662#endif
663
664 /* set info to libcsc */
665 if (pVideoEnc->csc_set_format == OMX_FALSE) {
666 csc_set_src_format(
667 pVideoEnc->csc_handle, /* handle */
668 nSrcFrameWidth, /* width */
669 nSrcFrameHeight , /* height */
670 0, /* crop_left */
671 0, /* crop_right */
672 nSrcImageWidth, /* crop_width */
673 nSrcImageHeight, /* crop_height */
674 csc_src_color_format, /* color_format */
675 srcCacheable); /* cacheable */
676
677 csc_set_dst_format(
678 pVideoEnc->csc_handle, /* handle */
679 nDstFrameWidth, /* width */
680 nDstFrameHeight, /* height */
681 0, /* crop_left */
682 0, /* crop_right */
683 nDstImageWidth, /* crop_width */
684 nDstImageHeight, /* crop_height */
685 csc_dst_color_format, /* color_format */
686 dstCacheable); /* cacheable */
687
688 csc_set_eq_property(
689 pVideoEnc->csc_handle, /* handle */
690 CSC_EQ_MODE_USER, /* user select */
691 CSC_EQ_RANGE_NARROW, /* narrow */
692 CSC_EQ_COLORSPACE_SMPTE170M); /* bt.601 */
693
694 pVideoEnc->csc_set_format = OMX_TRUE;
695 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] %s CSC(%x) %s/ [SRC] width(%d/%d),height(%d/%d),format(0x%x) -> [DST] width(%d/%d),height(%d/%d),format(0x%x)",
696 pExynosComponent, __FUNCTION__,
697 (csc_method == CSC_METHOD_SW)? "SW":"HW", csc_memType,
698 (pVideoEnc->eRotationType != ROTATE_0)? "with rotation":"",
699 nSrcFrameWidth, nSrcImageWidth, nSrcFrameHeight, nSrcImageHeight, csc_src_color_format,
700 nDstFrameWidth, nDstImageWidth, nDstFrameHeight, nDstImageHeight, csc_dst_color_format);
701 }
702
703 /* blur filter */
704 if (pVideoEnc->bUseBlurFilter == OMX_TRUE) {
705 CSC_HW_FILTER filterType = CSC_FT_NONE;
706
707 if (pVideoEnc->eBlurMode & BLUR_MODE_DOWNUP) {
708 switch (pVideoEnc->eBlurResol) {
709 case BLUR_RESOL_240:
710 filterType = CSC_FT_240;
711 break;
712 case BLUR_RESOL_480:
713 filterType = CSC_FT_480;
714 break;
715 case BLUR_RESOL_720:
716 filterType = CSC_FT_720;
717 break;
718 case BLUR_RESOL_1080:
719 filterType = CSC_FT_1080;
720 break;
721 default:
722 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invliad eBlurResol(%d)", __FUNCTION__, pVideoEnc->eBlurResol);
723 ret = OMX_FALSE;
724 goto EXIT;
725 }
726 }
727
728 if (pVideoEnc->eBlurMode & BLUR_MODE_COEFFICIENT)
729 filterType = CSC_FT_BLUR;
730
731 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] blur filter is enabled : type(%x)", pExynosComponent, __FUNCTION__, filterType);
732
733 csc_set_filter_property(
734 pVideoEnc->csc_handle,
735 filterType);
736 }
737
738 csc_set_src_buffer(
739 pVideoEnc->csc_handle, /* handle */
740 pSrcBuf,
741 csc_memType); /* YUV Addr or FD */
742
743 csc_set_dst_buffer(
744 pVideoEnc->csc_handle, /* handle */
745 pDstBuf,
746 csc_memType); /* YUV Addr or FD */
747
748 if (pVideoEnc->eRotationType != ROTATE_0)
749 cscRet = csc_convert_with_rotation(pVideoEnc->csc_handle, (int)pVideoEnc->eRotationType, 0, 0);
750 else
751 cscRet = csc_convert(pVideoEnc->csc_handle);
752
753 if (cscRet != CSC_ErrorNone)
754 ret = OMX_FALSE;
755 else
756 ret = OMX_TRUE;
757
758#ifdef USE_METADATABUFFERTYPE
759 if ((exynosInputPort->bStoreMetaData == OMX_TRUE) &&
760 (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)) {
761#ifdef USE_ANDROIDOPAQUE
762 Exynos_OSAL_UnlockANBHandle(ppBuf[0]);
763#endif
764 }
765#endif
766
767EXIT:
768 FunctionOut();
769
770 return ret;
771}
772
773OMX_BOOL Exynos_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *srcInputData)
774{
775 OMX_BOOL ret = OMX_FALSE;
776 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
777 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
778 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
779 EXYNOS_OMX_DATABUFFER *inputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
780 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
781 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
782 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
783
784 OMX_U32 copySize = 0;
785 OMX_BYTE checkInputStream = NULL;
786 OMX_U32 checkInputStreamLen = 0;
787 OMX_BOOL flagEOS = OMX_FALSE;
788
789 FunctionIn();
790
791 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
792 if ((srcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) ||
793 (srcInputData->pPrivate == NULL)) {
794 ret = OMX_FALSE;
795 goto EXIT;
796 }
797 }
798
799 if (inputUseBuffer->dataValid == OMX_TRUE) {
800 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
801 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Input port is BUFFER_SHARE", pExynosComponent, __FUNCTION__);
802
803 Exynos_Shared_BufferToData(inputUseBuffer, srcInputData, ONE_PLANE);
804#ifdef USE_METADATABUFFERTYPE
805 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
806 OMX_COLOR_FORMATTYPE inputColorFormat = OMX_COLOR_FormatUnused;
807
808 OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
809 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
810 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
811 int plane = 0, nPlaneCnt = 0;
812
813 inputColorFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
814 Exynos_OSAL_GetPlaneSize(inputColorFormat, exynosInputPort->ePlaneType, nFrameWidth, nFrameHeight, nDataLen, nAllocLen);
815 nPlaneCnt = Exynos_GetPlaneFromPort(exynosInputPort);
816 if (pVideoEnc->nInbufSpareSize > 0) {
817 for (plane = 0; plane < nPlaneCnt; plane++)
818 nAllocLen[plane] += pVideoEnc->nInbufSpareSize;
819 }
820
821 for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) {
822 srcInputData->multiPlaneBuffer.fd[plane] = -1;
823 srcInputData->multiPlaneBuffer.dataBuffer[plane] = NULL;
824 }
825
826 if (inputUseBuffer->dataLen <= 0) {
827 /* input data is not valid */
828 if (!(inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
829 /* w/o EOS flag */
830 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] dataLen is zero w/o EOS flag(0x%x). this buffer(%p) will be discarded",
831 pExynosComponent, __FUNCTION__,
832 inputUseBuffer->nFlags, inputUseBuffer);
833 Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
834 Exynos_ResetDataBuffer(inputUseBuffer); /* reset dataBuffer */
835 } else {
836 /* with EOS flag
837 * makes a buffer for EOS handling needed at MFC Processing scheme.
838 */
839 for (plane = 0; plane < nPlaneCnt; plane++) {
840 srcInputData->multiPlaneBuffer.dataBuffer[plane] =
841 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY);
842 srcInputData->multiPlaneBuffer.fd[plane] =
843 Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, srcInputData->multiPlaneBuffer.dataBuffer[plane]);
844 }
845 }
846 } else {
847 if (OMX_ErrorNone != Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)inputUseBuffer->bufferHeader->pBuffer, ppBuf)) {
848 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
849 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
850 pExynosComponent->callbackData,
851 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
852 ret = OMX_FALSE;
853 goto EXIT;
854 }
855#ifdef USE_DMA_BUF
856#ifdef USE_ANDROIDOPAQUE
857 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
858 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
859 OMX_U32 stride = 0;
860
861 Exynos_OSAL_LockANBHandle(ppBuf[0], nFrameWidth, nFrameHeight, OMX_COLOR_FormatAndroidOpaque, &stride, planes);
862
863 if (stride == ALIGN(exynosInputPort->portDefinition.format.video.nFrameWidth, 16))
864 exynosInputPort->portDefinition.format.video.nStride = stride;
865
866 for (plane = 0; plane < nPlaneCnt; plane++) {
867 srcInputData->multiPlaneBuffer.fd[plane] = planes[plane].fd;
868 srcInputData->multiPlaneBuffer.dataBuffer[plane] = planes[plane].addr;
869 }
870 } else
871#endif
872 {
873 /* kMetadataBufferTypeCameraSource */
874 for (plane = 0; plane < nPlaneCnt; plane++) {
875 srcInputData->multiPlaneBuffer.fd[plane] = PTR_TO_INT(ppBuf[plane]);
876 }
877 }
878
879 for (plane = 0; plane < nPlaneCnt; plane++) {
880 if ((srcInputData->multiPlaneBuffer.fd[plane] != -1) &&
881 (srcInputData->multiPlaneBuffer.dataBuffer[plane] == NULL)) {
882 srcInputData->multiPlaneBuffer.dataBuffer[plane] =
883 Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, srcInputData->multiPlaneBuffer.fd[plane]);
884 if(srcInputData->multiPlaneBuffer.dataBuffer[plane] == NULL) {
885 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Initial mapping is now in progress. fd[%d]",srcInputData->multiPlaneBuffer.fd[plane]);
886 srcInputData->multiPlaneBuffer.dataBuffer[plane] =
887 Exynos_OSAL_SharedMemory_Map(pVideoEnc->hSharedMemory, nAllocLen[plane], srcInputData->multiPlaneBuffer.fd[plane]);
888 }
889 }
890 }
891#else
892#ifdef USE_ANDROIDOPAQUE
893 if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
894 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_COLOR_FormatAndroidOpaque share don't implemented in UserPtr mode.");
895 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
896 pExynosComponent->callbackData,
897 OMX_EventError, OMX_ErrorNotImplemented, 0, NULL);
898 ret = OMX_FALSE;
899 goto EXIT;
900 } else
901#endif
902 {
903 /* kMetadataBufferTypeCameraSource */
904 for (plane = 0; plane < MAX_BUFFER_PLANE; plane++) {
905 srcInputData->multiPlaneBuffer.dataBuffer[plane] = (int)ppBuf[plane];
906 }
907 }
908#endif
909 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s:%d YAddr: 0x%p CbCrAddr: 0x%p", __FUNCTION__, __LINE__, ppBuf[0], ppBuf[1]);
910 }
911 }
912#endif
913 /* reset dataBuffer */
914 Exynos_ResetDataBuffer(inputUseBuffer);
915 } else if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
916 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Input port is BUFFER_COPY", pExynosComponent, __FUNCTION__);
917
918 checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen;
919 checkInputStreamLen = inputUseBuffer->remainDataLen;
920
921 pExynosComponent->bUseFlagEOF = OMX_TRUE;
922
923 if (checkInputStreamLen == 0) {
924 inputUseBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
925 flagEOS = OMX_TRUE;
926 }
927
928 copySize = checkInputStreamLen;
929
930 if (((srcInputData->allocSize) - (srcInputData->dataLen)) >= copySize) {
931 if ((copySize > 0) || (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
932 ret = OMX_TRUE;
933 if (copySize > 0)
934 ret = Exynos_CSC_InputData(pOMXComponent, srcInputData);
935 if (ret) {
936 inputUseBuffer->dataLen -= copySize;
937 inputUseBuffer->remainDataLen -= copySize;
938 inputUseBuffer->usedDataLen += copySize;
939
940 srcInputData->dataLen += copySize;
941 srcInputData->remainDataLen += copySize;
942
943 srcInputData->timeStamp = inputUseBuffer->timeStamp;
944 srcInputData->nFlags = inputUseBuffer->nFlags;
945 srcInputData->bufferHeader = inputUseBuffer->bufferHeader;
946 } else {
947 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Exynos_CSC_InputData() failure");
948 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
949 pExynosComponent->callbackData,
950 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
951 ret = OMX_FALSE;
952 }
953 } else {
954 ret = OMX_FALSE;
955 }
956 } else {
957 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input codec buffer is smaller than decoded input data size Out Length");
958 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
959 pExynosComponent->callbackData,
960 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
961 ret = OMX_FALSE;
962 }
963
964 Exynos_InputBufferReturn(pOMXComponent, inputUseBuffer);
965
966 /* reset dataBuffer */
967 Exynos_ResetDataBuffer(inputUseBuffer);
968 }
969
970 if ((srcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
971 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "bSaveFlagEOS : OMX_TRUE");
972 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
973 if (srcInputData->dataLen != 0)
974 pExynosComponent->bBehaviorEOS = OMX_TRUE;
975 }
976
977 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) &&
978 ((srcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != OMX_BUFFERFLAG_CODECCONFIG)) {
979 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE;
980 pExynosComponent->checkTimeStamp.startTimeStamp = srcInputData->timeStamp;
981 pExynosComponent->checkTimeStamp.nStartFlags = srcInputData->nFlags;
982 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
983 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "first frame timestamp after seeking %lld us (%.2f secs)",
984 srcInputData->timeStamp, srcInputData->timeStamp / 1E6);
985 }
986
987 ret = OMX_TRUE;
988 }
989
990EXIT:
991
992 FunctionOut();
993
994 return ret;
995}
996
997OMX_BOOL Exynos_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *dstOutputData)
998{
999 OMX_BOOL ret = OMX_FALSE;
1000 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1001 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1002 EXYNOS_OMX_DATABUFFER *outputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
1003 OMX_U32 copySize = 0;
1004
1005 FunctionIn();
1006
1007 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1008 if (Exynos_Shared_DataToBuffer(dstOutputData, outputUseBuffer, OMX_FALSE) == OMX_ErrorNone)
1009 outputUseBuffer->dataValid = OMX_TRUE;
1010 }
1011
1012 if (outputUseBuffer->dataValid == OMX_TRUE) {
1013 if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
1014 if (pExynosComponent->checkTimeStamp.startTimeStamp == dstOutputData->timeStamp){
1015 pExynosComponent->checkTimeStamp.startTimeStamp = RESET_TIMESTAMP_VAL;
1016 pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
1017 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
1018 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
1019 } else {
1020 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "garbage frame drop after flush");
1021 ret = OMX_TRUE;
1022 goto EXIT;
1023 }
1024 } else if (pExynosComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) {
1025 ret = OMX_TRUE;
1026 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input buffer has not come after flush.");
1027 goto EXIT;
1028 }
1029
1030 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1031 if (dstOutputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) {
1032 copySize = dstOutputData->remainDataLen;
1033 if (copySize > 0)
1034 Exynos_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen),
1035 ((char *)dstOutputData->multiPlaneBuffer.dataBuffer[0] + dstOutputData->usedDataLen),
1036 copySize);
1037 outputUseBuffer->dataLen += copySize;
1038 outputUseBuffer->remainDataLen += copySize;
1039 outputUseBuffer->nFlags = dstOutputData->nFlags;
1040 outputUseBuffer->timeStamp = dstOutputData->timeStamp;
1041
1042 ret = OMX_TRUE;
1043
1044 if ((outputUseBuffer->remainDataLen > 0) ||
1045 (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
1046 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
1047 }
1048 } else {
1049 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "output buffer is smaller than encoded data size Out Length");
1050 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1051 pExynosComponent->callbackData,
1052 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1053 ret = OMX_FALSE;
1054 }
1055 } else if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1056 if ((outputUseBuffer->remainDataLen > 0) ||
1057 ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) ||
1058 (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1059 if (exynosOutputPort->bStoreMetaData == OMX_TRUE)
1060 Exynos_OSAL_SetDataLengthToMetaData(outputUseBuffer->bufferHeader->pBuffer, outputUseBuffer->remainDataLen);
1061 Exynos_OutputBufferReturn(pOMXComponent, outputUseBuffer);
1062 } else {
1063 Exynos_OMX_FillThisBufferAgain(pOMXComponent, outputUseBuffer->bufferHeader);
1064 Exynos_ResetDataBuffer(outputUseBuffer);
1065 }
1066 }
1067 } else {
1068 ret = OMX_FALSE;
1069 }
1070
1071EXIT:
1072 FunctionOut();
1073
1074 return ret;
1075}
1076
1077#ifdef USE_METADATABUFFERTYPE
1078OMX_ERRORTYPE Exynos_OMX_ExtensionSetup(OMX_HANDLETYPE hComponent)
1079{
1080 OMX_ERRORTYPE ret = OMX_ErrorNone;
1081 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1082 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1083 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1084 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1085 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
1086 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
1087 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
1088 OMX_COLOR_FORMATTYPE eActualFormat = OMX_COLOR_FormatUnused;
1089
1090 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1091 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1092 OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
1093 int i = 0;
1094
1095#ifdef USE_METADATABUFFERTYPE
1096 if (exynosInputPort->bStoreMetaData == OMX_TRUE) {
1097 if ((srcInputUseBuffer->dataLen == 0) &&
1098 (srcInputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) {
1099 /* In this case, the metadata is not valid.
1100 * sets dummy info in order to return EOS flag at output port through FBD.
1101 * IL client should do stop sequence.
1102 */
1103 Exynos_OSAL_Log(EXYNOS_LOG_INFO, "[%p][%s] dataLen is zero with EOS flag(0x%x) at first input",
1104 pExynosComponent, __FUNCTION__, srcInputUseBuffer->nFlags);
1105#ifdef USE_ANDROIDOPAQUE
1106 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
1107 pVideoEnc->ANBColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1108 exynosInputPort->bufferProcessType = BUFFER_SHARE;
1109 Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType));
1110 } else
1111#endif
1112 {
1113 Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
1114 }
1115
1116 goto EXIT;
1117 } else {
1118 ret = Exynos_OSAL_GetInfoFromMetaData((OMX_BYTE)srcInputUseBuffer->bufferHeader->pBuffer, ppBuf);
1119 if (ret != OMX_ErrorNone) {
1120 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: GetInfoFromMetadata() is failed", __FUNCTION__);
1121 goto EXIT;
1122 }
1123
1124#ifdef USE_ANDROIDOPAQUE
1125 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque) {
1126 /* kMetadataBufferTypeGrallocSource */
1127 pVideoEnc->ANBColorFormat = Exynos_OSAL_GetANBColorFormat(ppBuf[0]);
1128 eActualFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
1129 if (eActualFormat == OMX_COLOR_FormatUnused) {
1130 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format : ANB color is 0x%x", __FUNCTION__, pVideoEnc->ANBColorFormat);
1131 ret = OMX_ErrorNotImplemented;
1132 goto EXIT;
1133 }
1134
1135 if (pVideoEnc->ANBColorFormat == eActualFormat) {
1136 exynosInputPort->bufferProcessType = BUFFER_SHARE;
1137 Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(pVideoEnc->ANBColorFormat, exynosInputPort->ePlaneType));
1138 } else {
1139 exynosInputPort->bufferProcessType = BUFFER_COPY;
1140 }
1141 } else
1142#endif
1143 {
1144 Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eColorFormat, exynosInputPort->ePlaneType));
1145 }
1146 }
1147
1148 }
1149#endif
1150
1151 /* forcefully have to use BUFFER_COPY mode, if blur filter is used or rotation is needed */
1152 if ((pVideoEnc->bUseBlurFilter == OMX_TRUE) ||
1153 (pVideoEnc->eRotationType != ROTATE_0)) {
1154 exynosInputPort->bufferProcessType = BUFFER_COPY;
1155 }
1156
1157 if ((exynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1158 OMX_U32 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameWidth;
1159 OMX_U32 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameHeight;
1160
1161 if ((pVideoEnc->eRotationType == ROTATE_90) ||
1162 (pVideoEnc->eRotationType == ROTATE_270)) {
1163 nFrameWidth = exynosInputPort->portDefinition.format.video.nFrameHeight;
1164 nFrameHeight = exynosInputPort->portDefinition.format.video.nFrameWidth;
1165 }
1166
1167 if (pVideoEnc->bEncDRC == OMX_TRUE) {
1168 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
1169 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
1170 pVideoEnc->bEncDRC = OMX_FALSE;
1171 }
1172
1173 eActualFormat = Exynos_Input_GetActualColorFormat(pExynosComponent);
1174 if (eActualFormat == OMX_COLOR_FormatUnused) {
1175 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] unsupported color format : 0x%x", __func__, eActualFormat);
1176 ret = OMX_ErrorNotImplemented;
1177 goto EXIT;
1178 }
1179
1180 Exynos_SetPlaneToPort(exynosInputPort, Exynos_OSAL_GetPlaneCount(eActualFormat, exynosInputPort->ePlaneType));
1181 Exynos_OSAL_GetPlaneSize(eActualFormat, exynosInputPort->ePlaneType, nFrameWidth, nFrameHeight, nDataLen, nAllocLen);
1182
1183 if (pVideoEnc->nInbufSpareSize > 0) {
1184 for (i = 0; i < Exynos_GetPlaneFromPort(exynosInputPort); i++)
1185 nAllocLen[i] += pVideoEnc->nInbufSpareSize;
1186 }
1187
1188 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
1189 if (ret != OMX_ErrorNone)
1190 goto EXIT;
1191
1192 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
1193 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
1194 } else if (exynosInputPort->bufferProcessType == BUFFER_SHARE) {
1195 /*************/
1196 /* TBD */
1197 /*************/
1198 /* Does not require any actions. */
1199 }
1200
1201EXIT:
1202 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] eActualFormat: 0x%x eColorFormat: 0x%x ANBColorFormat: 0x%x bufferProcessType: 0x%x", pExynosComponent, __FUNCTION__, eActualFormat, eColorFormat, pVideoEnc->ANBColorFormat, exynosInputPort->bufferProcessType);
1203
1204 return ret;
1205}
1206#endif
1207
1208OMX_ERRORTYPE Exynos_OMX_SrcInputBufferProcess(OMX_HANDLETYPE hComponent)
1209{
1210 OMX_ERRORTYPE ret = OMX_ErrorNone;
1211 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1212 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1213 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1214 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1215 EXYNOS_OMX_DATABUFFER *srcInputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.inputDataBuffer;
1216 EXYNOS_OMX_DATA *pSrcInputData = &exynosInputPort->processData;
1217 OMX_BOOL bCheckInputData = OMX_FALSE;
1218 OMX_BOOL bValidCodecData = OMX_FALSE;
1219
1220 FunctionIn();
1221
1222 while (!pVideoEnc->bExitBufferProcessThread) {
1223 Exynos_OSAL_SleepMillisec(0);
1224 Exynos_Wait_ProcessPause(pExynosComponent, INPUT_PORT_INDEX);
1225 if ((exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
1226 (!CHECK_PORT_ENABLED(exynosInputPort))) {
1227 /* sema will be posted at PortEnable */
1228 Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
1229 continue;
1230 }
1231
1232 while ((Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) &&
1233 (!pVideoEnc->bExitBufferProcessThread)) {
1234 Exynos_OSAL_SleepMillisec(0);
1235
1236 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
1237 break;
1238 if (exynosInputPort->portState != OMX_StateIdle)
1239 break;
1240
1241 Exynos_OSAL_MutexLock(srcInputUseBuffer->bufferMutex);
1242 if (pVideoEnc->bFirstInput == OMX_FALSE) {
1243 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1244 OMX_PTR codecBuffer;
1245 if ((pSrcInputData->multiPlaneBuffer.dataBuffer[0] == NULL) || (pSrcInputData->pPrivate == NULL)) {
1246 Exynos_CodecBufferDequeue(pExynosComponent, INPUT_PORT_INDEX, &codecBuffer);
1247 if (pVideoEnc->bExitBufferProcessThread) {
1248 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1249 goto EXIT;
1250 }
1251
1252 if (codecBuffer != NULL) {
1253 Exynos_CodecBufferToData(codecBuffer, pSrcInputData, INPUT_PORT_INDEX);
1254 }
1255 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1256 break;
1257 }
1258 }
1259
1260 if (srcInputUseBuffer->dataValid == OMX_TRUE) {
1261 bCheckInputData = Exynos_Preprocessor_InputData(pOMXComponent, pSrcInputData);
1262 } else {
1263 bCheckInputData = OMX_FALSE;
1264 }
1265 }
1266 if ((bCheckInputData == OMX_FALSE) &&
1267 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
1268 ret = Exynos_InputBufferGetQueue(pExynosComponent);
1269 if (pVideoEnc->bExitBufferProcessThread) {
1270 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1271 goto EXIT;
1272 }
1273
1274 if (ret != OMX_ErrorNone) {
1275 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1276 break;
1277 }
1278
1279 if ((pVideoEnc->bFirstInput == OMX_TRUE) &&
1280 (!CHECK_PORT_BEING_FLUSHED(exynosInputPort))) {
1281 ret = Exynos_OMX_ExtensionSetup(hComponent);
1282 if (ret != OMX_ErrorNone) {
1283 (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
1284 pExynosComponent->callbackData,
1285 (OMX_U32)OMX_EventError,
1286 (OMX_U32)OMX_ErrorNotImplemented,
1287 INPUT_PORT_INDEX, NULL);
1288 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1289 break;
1290 }
1291
1292 pVideoEnc->bFirstInput = OMX_FALSE;
1293 }
1294
1295 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1296 break;
1297 }
1298
1299 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort)) {
1300 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1301 break;
1302 }
1303
1304 ret = pVideoEnc->exynos_codec_srcInputProcess(pOMXComponent, pSrcInputData);
1305 Exynos_ResetCodecData(pSrcInputData);
1306 Exynos_OSAL_MutexUnlock(srcInputUseBuffer->bufferMutex);
1307 if ((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCodecInit)
1308 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
1309 }
1310 }
1311
1312EXIT:
1313
1314 FunctionOut();
1315
1316 return ret;
1317}
1318
1319OMX_ERRORTYPE Exynos_OMX_SrcOutputBufferProcess(OMX_HANDLETYPE hComponent)
1320{
1321 OMX_ERRORTYPE ret = OMX_ErrorNone;
1322 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1323 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1324 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1325 EXYNOS_OMX_BASEPORT *exynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1326 EXYNOS_OMX_DATABUFFER *srcOutputUseBuffer = &exynosInputPort->way.port2WayDataBuffer.outputDataBuffer;
1327 EXYNOS_OMX_DATA srcOutputData;
1328
1329 FunctionIn();
1330
1331 Exynos_ResetCodecData(&srcOutputData);
1332
1333 while (!pVideoEnc->bExitBufferProcessThread) {
1334 Exynos_OSAL_SleepMillisec(0);
1335 if ((exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
1336 (!CHECK_PORT_ENABLED(exynosInputPort))) {
1337 /* sema will be posted at PortEnable */
1338 Exynos_OSAL_SemaphoreWait(exynosInputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
1339 continue;
1340 }
1341
1342 while (!pVideoEnc->bExitBufferProcessThread) {
1343 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1344 if (Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX) == OMX_FALSE)
1345 break;
1346 }
1347 Exynos_OSAL_SleepMillisec(0);
1348
1349 if (CHECK_PORT_BEING_FLUSHED(exynosInputPort))
1350 break;
1351
1352 Exynos_OSAL_MutexLock(srcOutputUseBuffer->bufferMutex);
1353 Exynos_OSAL_Memset(&srcOutputData, 0, sizeof(EXYNOS_OMX_DATA));
1354
1355 ret = pVideoEnc->exynos_codec_srcOutputProcess(pOMXComponent, &srcOutputData);
1356
1357 if (ret == OMX_ErrorNone) {
1358 if (exynosInputPort->bufferProcessType & BUFFER_COPY) {
1359 OMX_PTR codecBuffer;
1360 codecBuffer = srcOutputData.pPrivate;
1361 if (codecBuffer != NULL)
1362 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, codecBuffer);
1363 }
1364 if (exynosInputPort->bufferProcessType & BUFFER_SHARE) {
1365 OMX_BOOL bNeedUnlock = OMX_FALSE;
1366 OMX_COLOR_FORMATTYPE eColorFormat = exynosInputPort->portDefinition.format.video.eColorFormat;
1367#ifdef USE_ANDROIDOPAQUE
1368 if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_COLOR_FormatAndroidOpaque)
1369 bNeedUnlock = OMX_TRUE;
1370#endif
1371 Exynos_Shared_DataToBuffer(&srcOutputData, srcOutputUseBuffer, bNeedUnlock);
1372 Exynos_InputBufferReturn(pOMXComponent, srcOutputUseBuffer);
1373 }
1374 Exynos_ResetCodecData(&srcOutputData);
1375 }
1376 Exynos_OSAL_MutexUnlock(srcOutputUseBuffer->bufferMutex);
1377 }
1378 }
1379
1380EXIT:
1381
1382 FunctionOut();
1383
1384 return ret;
1385}
1386
1387OMX_ERRORTYPE Exynos_OMX_DstInputBufferProcess(OMX_HANDLETYPE hComponent)
1388{
1389 OMX_ERRORTYPE ret = OMX_ErrorNone;
1390 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1391 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1392 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1393 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1394 EXYNOS_OMX_DATABUFFER *dstInputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.inputDataBuffer;
1395 EXYNOS_OMX_DATA dstInputData;
1396
1397 FunctionIn();
1398
1399 Exynos_ResetCodecData(&dstInputData);
1400
1401 while (!pVideoEnc->bExitBufferProcessThread) {
1402 Exynos_OSAL_SleepMillisec(0);
1403 if ((exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX] != NULL) &&
1404 (!CHECK_PORT_ENABLED(exynosOutputPort))) {
1405 /* sema will be posted at PortEnable */
1406 Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[INPUT_WAY_INDEX]);
1407 continue;
1408 }
1409
1410 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1411 (!pVideoEnc->bExitBufferProcessThread)) {
1412 Exynos_OSAL_SleepMillisec(0);
1413
1414 if ((CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) ||
1415 (!CHECK_PORT_POPULATED(exynosOutputPort)))
1416 break;
1417 if (exynosOutputPort->portState != OMX_StateIdle)
1418 break;
1419
1420 Exynos_OSAL_MutexLock(dstInputUseBuffer->bufferMutex);
1421 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1422 CODEC_ENC_BUFFER *pCodecBuffer = NULL;
1423 ret = Exynos_CodecBufferDequeue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR *)&pCodecBuffer);
1424 if (pVideoEnc->bExitBufferProcessThread) {
1425 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1426 goto EXIT;
1427 }
1428
1429 if (ret != OMX_ErrorNone) {
1430 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1431 break;
1432 }
1433 Exynos_CodecBufferToData(pCodecBuffer, &dstInputData, OUTPUT_PORT_INDEX);
1434 }
1435
1436 if (exynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1437 if ((dstInputUseBuffer->dataValid != OMX_TRUE) &&
1438 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1439 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1440 if (pVideoEnc->bExitBufferProcessThread) {
1441 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1442 goto EXIT;
1443 }
1444
1445 if (ret != OMX_ErrorNone) {
1446 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1447 break;
1448 }
1449 Exynos_Shared_BufferToData(dstInputUseBuffer, &dstInputData, ONE_PLANE);
1450 if (exynosOutputPort->bStoreMetaData == OMX_TRUE) {
1451 int ionFD = -1;
1452 OMX_PTR dataBuffer = NULL;
1453 OMX_PTR ppBuf[MAX_BUFFER_PLANE] = {NULL, NULL, NULL};
1454
1455 ret = Exynos_OSAL_GetBufferFdFromMetaData((OMX_BYTE)dstInputUseBuffer->bufferHeader->pBuffer, ppBuf);
1456 if (ret != OMX_ErrorNone) {
1457 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: Exynos_OSAL_GetBufferFdFromMetaData() is failed", __FUNCTION__);
1458 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1459 pExynosComponent->callbackData,
1460 OMX_EventError, OMX_ErrorUndefined, 0, NULL);
1461 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1462 break;
1463 }
1464
1465 /* caution : data loss */
1466 ionFD = PTR_TO_INT(ppBuf[0]);
1467
1468 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
1469 if (dataBuffer == NULL) {
1470 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Metadata buffer", __LINE__);
1471 ret = OMX_ErrorUndefined;
1472 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1473 break;
1474 }
1475 dstInputData.multiPlaneBuffer.fd[0] = ionFD;
1476 dstInputData.multiPlaneBuffer.dataBuffer[0] = dataBuffer;
1477 } else {
1478 if (pExynosComponent->codecType == HW_VIDEO_ENC_SECURE_CODEC) {
1479 /* caution : data loss */
1480 int ionFD = PTR_TO_INT(dstInputData.multiPlaneBuffer.dataBuffer[0]);
1481
1482 OMX_PTR dataBuffer = NULL;
1483 dataBuffer = Exynos_OSAL_SharedMemory_IONToVirt(pVideoEnc->hSharedMemory, ionFD);
1484 if (dataBuffer == NULL) {
1485 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Wrong dst-input Secure buffer", __LINE__);
1486 ret = OMX_ErrorUndefined;
1487 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1488 break;
1489 }
1490 dstInputData.multiPlaneBuffer.fd[0] = ionFD;
1491 dstInputData.multiPlaneBuffer.dataBuffer[0] = dataBuffer;
1492 } else {
1493 dstInputData.multiPlaneBuffer.fd[0] =
1494 Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory,
1495 dstInputData.multiPlaneBuffer.dataBuffer[0]);
1496 }
1497 }
1498 Exynos_ResetDataBuffer(dstInputUseBuffer);
1499 }
1500 }
1501
1502 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort)) {
1503 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1504 break;
1505 }
1506 ret = pVideoEnc->exynos_codec_dstInputProcess(pOMXComponent, &dstInputData);
1507
1508 Exynos_ResetCodecData(&dstInputData);
1509 Exynos_OSAL_MutexUnlock(dstInputUseBuffer->bufferMutex);
1510 }
1511 }
1512
1513EXIT:
1514
1515 FunctionOut();
1516
1517 return ret;
1518}
1519
1520OMX_ERRORTYPE Exynos_OMX_DstOutputBufferProcess(OMX_HANDLETYPE hComponent)
1521{
1522 OMX_ERRORTYPE ret = OMX_ErrorNone;
1523 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1524 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1525 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1526 EXYNOS_OMX_BASEPORT *exynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1527 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &exynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
1528 EXYNOS_OMX_DATA *pDstOutputData = &exynosOutputPort->processData;
1529
1530 FunctionIn();
1531
1532 while (!pVideoEnc->bExitBufferProcessThread) {
1533 Exynos_OSAL_SleepMillisec(0);
1534 Exynos_Wait_ProcessPause(pExynosComponent, OUTPUT_PORT_INDEX);
1535 if ((exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX] != NULL) &&
1536 (!CHECK_PORT_ENABLED(exynosOutputPort))) {
1537 /* sema will be posted at PortEnable */
1538 Exynos_OSAL_SemaphoreWait(exynosOutputPort->semWaitPortEnable[OUTPUT_WAY_INDEX]);
1539 continue;
1540 }
1541
1542 while ((Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) &&
1543 (!pVideoEnc->bExitBufferProcessThread)) {
1544 Exynos_OSAL_SleepMillisec(0);
1545
1546 if (CHECK_PORT_BEING_FLUSHED(exynosOutputPort))
1547 break;
1548
1549 Exynos_OSAL_MutexLock(dstOutputUseBuffer->bufferMutex);
1550 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1551 if ((dstOutputUseBuffer->dataValid != OMX_TRUE) &&
1552 (!CHECK_PORT_BEING_FLUSHED(exynosOutputPort))) {
1553 ret = Exynos_OutputBufferGetQueue(pExynosComponent);
1554 if (pVideoEnc->bExitBufferProcessThread) {
1555 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1556 goto EXIT;
1557 }
1558
1559 if (ret != OMX_ErrorNone) {
1560 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1561 break;
1562 }
1563 }
1564 }
1565
1566 if ((dstOutputUseBuffer->dataValid == OMX_TRUE) ||
1567 (exynosOutputPort->bufferProcessType & BUFFER_SHARE))
1568 ret = pVideoEnc->exynos_codec_dstOutputProcess(pOMXComponent, pDstOutputData);
1569
1570 if (((ret == OMX_ErrorNone) && (dstOutputUseBuffer->dataValid == OMX_TRUE)) ||
1571 (exynosOutputPort->bufferProcessType & BUFFER_SHARE)) {
1572 Exynos_Postprocess_OutputData(pOMXComponent, pDstOutputData);
1573 }
1574
1575 if (exynosOutputPort->bufferProcessType & BUFFER_COPY) {
1576 if (pDstOutputData->pPrivate != NULL) {
1577 Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, pDstOutputData->pPrivate);
1578 pDstOutputData->pPrivate = NULL;
1579 }
1580 }
1581
1582 /* reset outputData */
1583 Exynos_ResetCodecData(pDstOutputData);
1584 Exynos_OSAL_MutexUnlock(dstOutputUseBuffer->bufferMutex);
1585 }
1586 }
1587
1588EXIT:
1589
1590 FunctionOut();
1591
1592 return ret;
1593}
1594
1595static OMX_ERRORTYPE Exynos_OMX_SrcInputProcessThread(OMX_PTR threadData)
1596{
1597 OMX_ERRORTYPE ret = OMX_ErrorNone;
1598 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1599 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1600 EXYNOS_OMX_MESSAGE *message = NULL;
1601
1602 FunctionIn();
1603
1604 if (threadData == NULL) {
1605 ret = OMX_ErrorBadParameter;
1606 goto EXIT;
1607 }
1608 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1609 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1610 if (ret != OMX_ErrorNone) {
1611 goto EXIT;
1612 }
1613 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1614 Exynos_OMX_SrcInputBufferProcess(pOMXComponent);
1615
1616 Exynos_OSAL_ThreadExit(NULL);
1617
1618EXIT:
1619 FunctionOut();
1620
1621 return ret;
1622}
1623
1624static OMX_ERRORTYPE Exynos_OMX_SrcOutputProcessThread(OMX_PTR threadData)
1625{
1626 OMX_ERRORTYPE ret = OMX_ErrorNone;
1627 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1628 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1629 EXYNOS_OMX_MESSAGE *message = NULL;
1630
1631 FunctionIn();
1632
1633 if (threadData == NULL) {
1634 ret = OMX_ErrorBadParameter;
1635 goto EXIT;
1636 }
1637 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1638 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1639 if (ret != OMX_ErrorNone) {
1640 goto EXIT;
1641 }
1642 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1643 Exynos_OMX_SrcOutputBufferProcess(pOMXComponent);
1644
1645 Exynos_OSAL_ThreadExit(NULL);
1646
1647EXIT:
1648 FunctionOut();
1649
1650 return ret;
1651}
1652
1653static OMX_ERRORTYPE Exynos_OMX_DstInputProcessThread(OMX_PTR threadData)
1654{
1655 OMX_ERRORTYPE ret = OMX_ErrorNone;
1656 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1657 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1658 EXYNOS_OMX_MESSAGE *message = NULL;
1659
1660 FunctionIn();
1661
1662 if (threadData == NULL) {
1663 ret = OMX_ErrorBadParameter;
1664 goto EXIT;
1665 }
1666 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1667 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1668 if (ret != OMX_ErrorNone) {
1669 goto EXIT;
1670 }
1671 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1672 Exynos_OMX_DstInputBufferProcess(pOMXComponent);
1673
1674 Exynos_OSAL_ThreadExit(NULL);
1675
1676EXIT:
1677 FunctionOut();
1678
1679 return ret;
1680}
1681
1682static OMX_ERRORTYPE Exynos_OMX_DstOutputProcessThread(OMX_PTR threadData)
1683{
1684 OMX_ERRORTYPE ret = OMX_ErrorNone;
1685 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1686 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1687 EXYNOS_OMX_MESSAGE *message = NULL;
1688
1689 FunctionIn();
1690
1691 if (threadData == NULL) {
1692 ret = OMX_ErrorBadParameter;
1693 goto EXIT;
1694 }
1695 pOMXComponent = (OMX_COMPONENTTYPE *)threadData;
1696 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1697 if (ret != OMX_ErrorNone) {
1698 goto EXIT;
1699 }
1700 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1701 Exynos_OMX_DstOutputBufferProcess(pOMXComponent);
1702
1703 Exynos_OSAL_ThreadExit(NULL);
1704
1705EXIT:
1706 FunctionOut();
1707
1708 return ret;
1709}
1710
1711OMX_ERRORTYPE Exynos_OMX_BufferProcess_Create(OMX_HANDLETYPE hComponent)
1712{
1713 OMX_ERRORTYPE ret = OMX_ErrorNone;
1714 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1715 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1716 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1717
1718 FunctionIn();
1719
1720 pVideoEnc->bExitBufferProcessThread = OMX_FALSE;
1721
1722 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstOutputThread,
1723 Exynos_OMX_DstOutputProcessThread,
1724 pOMXComponent);
1725 if (ret == OMX_ErrorNone)
1726 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcOutputThread,
1727 Exynos_OMX_SrcOutputProcessThread,
1728 pOMXComponent);
1729 if (ret == OMX_ErrorNone)
1730 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hDstInputThread,
1731 Exynos_OMX_DstInputProcessThread,
1732 pOMXComponent);
1733 if (ret == OMX_ErrorNone)
1734 ret = Exynos_OSAL_ThreadCreate(&pVideoEnc->hSrcInputThread,
1735 Exynos_OMX_SrcInputProcessThread,
1736 pOMXComponent);
1737
1738EXIT:
1739 FunctionOut();
1740
1741 return ret;
1742}
1743
1744OMX_ERRORTYPE Exynos_OMX_BufferProcess_Terminate(OMX_HANDLETYPE hComponent)
1745{
1746 OMX_ERRORTYPE ret = OMX_ErrorNone;
1747 OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1748 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1749 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1750 OMX_S32 countValue = 0;
1751 unsigned int i = 0;
1752
1753 FunctionIn();
1754
1755 pVideoEnc->bExitBufferProcessThread = OMX_TRUE;
1756
1757 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID, &countValue);
1758 if (countValue == 0)
1759 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].bufferSemID);
1760 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID, &countValue);
1761 if (countValue == 0)
1762 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].codecSemID);
1763 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
1764
1765 /* srcInput */
1766 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1767 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
1768 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcInputThread);
1769 pVideoEnc->hSrcInputThread = NULL;
1770 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
1771
1772 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID, &countValue);
1773 if (countValue == 0)
1774 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bufferSemID);
1775 Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID, &countValue);
1776 if (countValue == 0)
1777 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].codecSemID);
1778
1779 /* dstInput */
1780 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1781 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX]);
1782 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstInputThread);
1783 pVideoEnc->hDstInputThread = NULL;
1784 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[INPUT_WAY_INDEX], 0);
1785
1786 pVideoEnc->exynos_codec_stop(pOMXComponent, INPUT_PORT_INDEX);
1787 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, INPUT_PORT_INDEX);
1788
1789 /* srcOutput */
1790 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].pauseEvent);
1791 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
1792 Exynos_OSAL_ThreadTerminate(pVideoEnc->hSrcOutputThread);
1793 pVideoEnc->hSrcOutputThread = NULL;
1794 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[INPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
1795
1796 pVideoEnc->exynos_codec_stop(pOMXComponent, OUTPUT_PORT_INDEX);
1797 pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, OUTPUT_PORT_INDEX);
1798
1799 /* dstOutput */
1800 Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].pauseEvent);
1801 Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX]);
1802 Exynos_OSAL_ThreadTerminate(pVideoEnc->hDstOutputThread);
1803 pVideoEnc->hDstOutputThread = NULL;
1804 Exynos_OSAL_Set_SemaphoreCount(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].semWaitPortEnable[OUTPUT_WAY_INDEX], 0);
1805
1806 pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
1807 pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
1808
1809EXIT:
1810 FunctionOut();
1811
1812 return ret;
1813}
1814
1815OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent)
1816{
1817 OMX_ERRORTYPE ret = OMX_ErrorNone;
1818 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1819 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1820 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1821 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1822
1823 FunctionIn();
1824
1825 if (hComponent == NULL) {
1826 ret = OMX_ErrorBadParameter;
1827 goto EXIT;
1828 }
1829 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1830 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1831 if (ret != OMX_ErrorNone) {
1832 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1833 goto EXIT;
1834 }
1835
1836 ret = Exynos_OMX_BaseComponent_Constructor(pOMXComponent);
1837 if (ret != OMX_ErrorNone) {
1838 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1839 goto EXIT;
1840 }
1841
1842 ret = Exynos_OMX_Port_Constructor(pOMXComponent);
1843 if (ret != OMX_ErrorNone) {
1844 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1845 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1846 goto EXIT;
1847 }
1848
1849 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1850
1851 pVideoEnc = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1852 if (pVideoEnc == NULL) {
1853 Exynos_OMX_Port_Destructor(pOMXComponent);
1854 Exynos_OMX_BaseComponent_Destructor(pOMXComponent);
1855 ret = OMX_ErrorInsufficientResources;
1856 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1857 goto EXIT;
1858 }
1859
1860 Exynos_OSAL_Memset(pVideoEnc, 0, sizeof(EXYNOS_OMX_VIDEOENC_COMPONENT));
1861 pExynosComponent->hComponentHandle = (OMX_HANDLETYPE)pVideoEnc;
1862
1863 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1864 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1865
1866 pVideoEnc->bFirstInput = OMX_TRUE;
1867 pVideoEnc->bFirstOutput = OMX_FALSE;
1868 pVideoEnc->bQosChanged = OMX_FALSE;
1869 pVideoEnc->nQosRatio = 0;
1870 pVideoEnc->nInbufSpareSize = 0;
1871 pVideoEnc->quantization.nQpI = 4; // I frame quantization parameter
1872 pVideoEnc->quantization.nQpP = 5; // P frame quantization parameter
1873 pVideoEnc->quantization.nQpB = 5; // B frame quantization parameter
1874
1875 pVideoEnc->bUseBlurFilter = OMX_FALSE;
1876 pVideoEnc->eBlurMode = BLUR_MODE_NONE;
1877 pVideoEnc->eBlurResol = BLUR_RESOL_240;
1878
1879 pVideoEnc->eRotationType = ROTATE_0;
1880
1881 pExynosComponent->bMultiThreadProcess = OMX_TRUE;
1882
1883 /* Input port */
1884 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1885 pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX);
1886 if (pExynosPort->supportFormat == NULL) {
1887 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
1888 ret = OMX_ErrorInsufficientResources;
1889 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1890 goto EXIT;
1891 }
1892 Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * INPUT_PORT_SUPPORTFORMAT_NUM_MAX));
1893
1894 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM;
1895 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM;
1896 pExynosPort->portDefinition.nBufferSize = 0;
1897 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1898
1899 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1900 if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
1901 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
1902 ret = OMX_ErrorInsufficientResources;
1903 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1904 goto EXIT;
1905 }
1906 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1907 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1908 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1909 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1910
1911 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1912 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1913 pExynosPort->portDefinition.format.video.nStride = 0;
1914 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1915 pExynosPort->portDefinition.format.video.nBitrate = 1000000;
1916 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1917 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1918 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1919 pVideoEnc->eControlRate[INPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
1920
1921#ifdef USE_METADATABUFFERTYPE
1922 pExynosPort->bStoreMetaData = OMX_FALSE;
1923#endif
1924
1925 /* Output port */
1926 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1927 pExynosPort->supportFormat = Exynos_OSAL_Malloc(sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX);
1928 if (pExynosPort->supportFormat == NULL) {
1929 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
1930 ret = OMX_ErrorInsufficientResources;
1931 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1932 goto EXIT;
1933 }
1934 Exynos_OSAL_Memset(pExynosPort->supportFormat, 0, (sizeof(OMX_COLOR_FORMATTYPE) * OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX));
1935
1936 pExynosPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM;
1937 pExynosPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM;
1938 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
1939 pExynosPort->portDefinition.eDomain = OMX_PortDomainVideo;
1940
1941 pExynosPort->portDefinition.format.video.cMIMEType = Exynos_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE);
1942 if (pExynosPort->portDefinition.format.video.cMIMEType == NULL) {
1943 Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
1944 ret = OMX_ErrorInsufficientResources;
1945 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1946 goto EXIT;
1947 }
1948 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
1949 pExynosPort->portDefinition.format.video.pNativeRender = 0;
1950 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
1951 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
1952
1953 pExynosPort->portDefinition.format.video.nFrameWidth = 0;
1954 pExynosPort->portDefinition.format.video.nFrameHeight= 0;
1955 pExynosPort->portDefinition.format.video.nStride = 0;
1956 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
1957 pExynosPort->portDefinition.format.video.nBitrate = 1000000;
1958 pExynosPort->portDefinition.format.video.xFramerate = (15 << 16);
1959 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
1960 pExynosPort->portDefinition.format.video.pNativeWindow = NULL;
1961 pVideoEnc->eControlRate[OUTPUT_PORT_INDEX] = OMX_Video_ControlRateVariable;
1962
1963 pOMXComponent->UseBuffer = &Exynos_OMX_UseBuffer;
1964 pOMXComponent->AllocateBuffer = &Exynos_OMX_AllocateBuffer;
1965 pOMXComponent->FreeBuffer = &Exynos_OMX_FreeBuffer;
1966
1967#ifdef TUNNELING_SUPPORT
1968 pOMXComponent->ComponentTunnelRequest = &Exynos_OMX_ComponentTunnelRequest;
1969 pExynosComponent->exynos_AllocateTunnelBuffer = &Exynos_OMX_AllocateTunnelBuffer;
1970 pExynosComponent->exynos_FreeTunnelBuffer = &Exynos_OMX_FreeTunnelBuffer;
1971#endif
1972
1973 pExynosComponent->exynos_BufferProcessCreate = &Exynos_OMX_BufferProcess_Create;
1974 pExynosComponent->exynos_BufferProcessTerminate = &Exynos_OMX_BufferProcess_Terminate;
1975 pExynosComponent->exynos_BufferFlush = &Exynos_OMX_BufferFlush;
1976
1977EXIT:
1978 FunctionOut();
1979
1980 return ret;
1981}
1982
1983OMX_ERRORTYPE Exynos_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent)
1984{
1985 OMX_ERRORTYPE ret = OMX_ErrorNone;
1986 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1987 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1988 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
1989 EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1990 int i = 0;
1991
1992 FunctionIn();
1993
1994 if (hComponent == NULL) {
1995 ret = OMX_ErrorBadParameter;
1996 goto EXIT;
1997 }
1998 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1999 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
2000 if (ret != OMX_ErrorNone) {
2001 goto EXIT;
2002 }
2003
2004 if (pOMXComponent->pComponentPrivate == NULL) {
2005 ret = OMX_ErrorBadParameter;
2006 goto EXIT;
2007 }
2008 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2009
2010 pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2011
2012 Exynos_OSAL_Free(pVideoEnc);
2013 pExynosComponent->hComponentHandle = pVideoEnc = NULL;
2014
2015 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2016 if (pExynosPort->processData.extInfo != NULL) {
2017 Exynos_OSAL_Free(pExynosPort->processData.extInfo);
2018 pExynosPort->processData.extInfo = NULL;
2019 }
2020
2021 for(i = 0; i < ALL_PORT_NUM; i++) {
2022 pExynosPort = &pExynosComponent->pExynosPort[i];
2023 Exynos_OSAL_Free(pExynosPort->portDefinition.format.video.cMIMEType);
2024 pExynosPort->portDefinition.format.video.cMIMEType = NULL;
2025
2026 Exynos_OSAL_Free(pExynosPort->supportFormat);
2027 pExynosPort->supportFormat = NULL;
2028 }
2029
2030 ret = Exynos_OMX_Port_Destructor(pOMXComponent);
2031
2032 ret = Exynos_OMX_BaseComponent_Destructor(hComponent);
2033
2034EXIT:
2035 FunctionOut();
2036
2037 return ret;
2038}