c46dde3d6f0ba76b26f729b168d82b2b4bccd121
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / enc / Exynos_OMX_VencControl.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_VencControl.c
20  * @brief
21  * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
22  * @version     2.0.0
23  * @history
24  *   2012.02.20 : Create
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <mm_types.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_Mutex.h"
39 #include "Exynos_OSAL_ETC.h"
40 #include "Exynos_OSAL_SharedMemory.h"
41
42 #ifdef USE_PB
43 #include "Exynos_OSAL_Platform_Specific.h"
44 #endif
45
46 #undef  EXYNOS_LOG_TAG
47 #define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_ENCCONTROL"
48 #define EXYNOS_LOG_OFF
49 //#define EXYNOS_TRACE_ON
50 #include "Exynos_OSAL_Log.h"
51
52
53 OMX_ERRORTYPE Exynos_OMX_UseBuffer(
54     OMX_IN OMX_HANDLETYPE            hComponent,
55     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
56     OMX_IN OMX_U32                   nPortIndex,
57     OMX_IN OMX_PTR                   pAppPrivate,
58     OMX_IN OMX_U32                   nSizeBytes,
59     OMX_IN OMX_U8                   *pBuffer)
60 {
61     OMX_ERRORTYPE                    ret               = OMX_ErrorNone;
62     OMX_COMPONENTTYPE               *pOMXComponent     = NULL;
63     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent  = NULL;
64     EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc         = NULL;
65     EXYNOS_OMX_BASEPORT             *pExynosPort       = NULL;
66     OMX_BUFFERHEADERTYPE            *pTempBufferHdr    = NULL;
67     OMX_U32 i = 0;
68
69     FunctionIn();
70
71     if (hComponent == NULL) {
72         ret = OMX_ErrorBadParameter;
73         goto EXIT;
74     }
75     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
76
77     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
78     if (ret != OMX_ErrorNone) {
79         goto EXIT;
80     }
81
82     if (pOMXComponent->pComponentPrivate == NULL) {
83         ret = OMX_ErrorBadParameter;
84         goto EXIT;
85     }
86     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
87
88     if (pExynosComponent->hComponentHandle == NULL) {
89         ret = OMX_ErrorBadParameter;
90         goto EXIT;
91     }
92     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
93
94     if ((nPortIndex < 0) ||
95         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
96         ret = OMX_ErrorBadPortIndex;
97         goto EXIT;
98     }
99     pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
100
101     if (pExynosPort->portState != OMX_StateIdle) {
102         ret = OMX_ErrorIncorrectStateOperation;
103         goto EXIT;
104     }
105
106     if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
107         ret = OMX_ErrorBadPortIndex;
108         goto EXIT;
109     }
110
111     pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
112     if (pTempBufferHdr == NULL) {
113         ret = OMX_ErrorInsufficientResources;
114         goto EXIT;
115     }
116     Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
117
118     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
119         if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
120             pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
121             pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
122             INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
123             pTempBufferHdr->pBuffer        = pBuffer;
124             pTempBufferHdr->nAllocLen      = nSizeBytes;
125             pTempBufferHdr->pAppPrivate    = pAppPrivate;
126             if (nPortIndex == INPUT_PORT_INDEX)
127                 pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
128             else
129                 pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
130 #ifdef SLP_PLATFORM
131             if (nPortIndex == OUTPUT_PORT_INDEX && pVideoEnc->bSharedOutputFD == OMX_TRUE)
132                 pExynosPort->extendBufferHeader[i].buf_fd[0] = (int)(pBuffer); /*IL Client provides only FD value*/
133
134             MMVideoBuffer * pSlpOutBuf = (MMVideoBuffer *)pBuffer;
135
136             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "fd[0] =%d, fd[1] =%d, vaddr[0] =%p, vaddr[1] = %p, y_size=%d, uv_size=%d\n",
137                 pSlpOutBuf->handle.dmabuf_fd[0], pSlpOutBuf->handle.dmabuf_fd[1], pSlpOutBuf->data[0], pSlpOutBuf->data[1],
138                 pSlpOutBuf->size[0],pSlpOutBuf->size[1]);
139             if(nPortIndex == OUTPUT_PORT_INDEX )
140                   pTempBufferHdr->pBuffer  = pSlpOutBuf->handle.paddr[0];
141
142             pExynosPort->extendBufferHeader[i].buf_fd[0] = pSlpOutBuf->handle.dmabuf_fd[0];
143             pExynosPort->extendBufferHeader[i].buf_fd[1] = pSlpOutBuf->handle.dmabuf_fd[1];
144             pExynosPort->extendBufferHeader[i].buf_fd[2] = 0;
145
146             pExynosPort->extendBufferHeader[i].pYUVBuf[0] = pSlpOutBuf->data[0];
147             pExynosPort->extendBufferHeader[i].pYUVBuf[1] = pSlpOutBuf->data[1];
148             pExynosPort->extendBufferHeader[i].pYUVBuf[2] = NULL;
149
150             //pExynosPort->extendBufferHeader[i].tbm_bo[0] = pSlpOutBuf->handle.bo[0];
151             //pExynosPort->extendBufferHeader[i].tbm_bo[1] = pSlpOutBuf->handle.bo[1];
152             //pExynosPort->extendBufferHeader[i].tbm_bo[2] = NULL;
153
154             //pExynosPort->extendBufferHeader[i].size[0] = pSlpOutBuf->size[0];
155             //pExynosPort->extendBufferHeader[i].size[1] = pSlpOutBuf->size[1];
156             //pExynosPort->extendBufferHeader[i].size[2] = 0;
157
158
159 #endif
160             pExynosPort->assignedBufferNum++;
161             if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) {
162                 pExynosPort->portDefinition.bPopulated = OMX_TRUE;
163                 /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
164                 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
165                 /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
166             }
167             *ppBufferHdr = pTempBufferHdr;
168             ret = OMX_ErrorNone;
169             goto EXIT;
170         }
171     }
172
173     Exynos_OSAL_Free(pTempBufferHdr);
174     ret = OMX_ErrorInsufficientResources;
175
176 EXIT:
177     FunctionOut();
178
179     return ret;
180 }
181
182 OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
183     OMX_IN OMX_HANDLETYPE            hComponent,
184     OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
185     OMX_IN OMX_U32                   nPortIndex,
186     OMX_IN OMX_PTR                   pAppPrivate,
187     OMX_IN OMX_U32                   nSizeBytes)
188 {
189     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
190     OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
191     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
192     EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
193     EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
194     OMX_BUFFERHEADERTYPE            *pTempBufferHdr     = NULL;
195     OMX_U8                          *pTempBuffer        = NULL;
196     int                              fdTempBuffer       = -1;
197     MEMORY_TYPE                      eMemType;
198     OMX_U32                          i                  = 0;
199
200     FunctionIn();
201
202     if (hComponent == NULL) {
203         ret = OMX_ErrorBadParameter;
204         goto EXIT;
205     }
206     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
207
208     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
209     if (ret != OMX_ErrorNone) {
210         goto EXIT;
211     }
212
213     if (pOMXComponent->pComponentPrivate == NULL) {
214         ret = OMX_ErrorBadParameter;
215         goto EXIT;
216     }
217     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
218
219     if (pExynosComponent->hComponentHandle == NULL) {
220         ret = OMX_ErrorBadParameter;
221         goto EXIT;
222     }
223     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
224
225     if ((nPortIndex < 0) ||
226         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
227         ret = OMX_ErrorBadPortIndex;
228         goto EXIT;
229     }
230     pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
231 /*
232     if (pExynosPort->portState != OMX_StateIdle ) {
233         ret = OMX_ErrorIncorrectStateOperation;
234         goto EXIT;
235     }
236 */
237     if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
238         ret = OMX_ErrorBadPortIndex;
239         goto EXIT;
240     }
241
242     if (pExynosPort->bufferProcessType & BUFFER_SHARE)
243         eMemType = NORMAL_MEMORY;
244     else
245         eMemType = SYSTEM_MEMORY;
246
247     pTempBuffer = Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nSizeBytes, eMemType);
248     if (pTempBuffer == NULL) {
249         ret = OMX_ErrorInsufficientResources;
250         goto EXIT;
251     }
252     fdTempBuffer = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pTempBuffer);
253
254     pTempBufferHdr = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
255     if (pTempBufferHdr == NULL) {
256         Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
257         ret = OMX_ErrorInsufficientResources;
258         goto EXIT;
259     }
260     Exynos_OSAL_Memset(pTempBufferHdr, 0, sizeof(OMX_BUFFERHEADERTYPE));
261
262     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
263         if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
264             pExynosPort->extendBufferHeader[i].OMXBufferHeader = pTempBufferHdr;
265             pExynosPort->extendBufferHeader[i].buf_fd[0] = fdTempBuffer;
266             pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED);
267             INIT_SET_SIZE_VERSION(pTempBufferHdr, OMX_BUFFERHEADERTYPE);
268             pTempBufferHdr->pBuffer        = pTempBuffer;
269             pTempBufferHdr->nAllocLen      = nSizeBytes;
270             pTempBufferHdr->pAppPrivate    = pAppPrivate;
271             if (nPortIndex == INPUT_PORT_INDEX)
272                 pTempBufferHdr->nInputPortIndex = INPUT_PORT_INDEX;
273             else
274                 pTempBufferHdr->nOutputPortIndex = OUTPUT_PORT_INDEX;
275             pExynosPort->assignedBufferNum++;
276             if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) {
277                 pExynosPort->portDefinition.bPopulated = OMX_TRUE;
278                 /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
279                 Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
280                 /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
281             }
282             *ppBufferHdr = pTempBufferHdr;
283             ret = OMX_ErrorNone;
284             goto EXIT;
285         }
286     }
287
288     Exynos_OSAL_Free(pTempBufferHdr);
289     Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pTempBuffer);
290     ret = OMX_ErrorInsufficientResources;
291
292 EXIT:
293     FunctionOut();
294
295     return ret;
296 }
297
298 OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
299     OMX_IN OMX_HANDLETYPE        hComponent,
300     OMX_IN OMX_U32               nPortIndex,
301     OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
302 {
303     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
304     OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
305     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
306     EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
307     EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
308     OMX_BUFFERHEADERTYPE            *pOMXBufferHdr      = NULL;
309     OMX_U32                          i                  = 0;
310
311     FunctionIn();
312
313     if (hComponent == NULL) {
314         ret = OMX_ErrorBadParameter;
315         goto EXIT;
316     }
317     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
318
319     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
320     if (ret != OMX_ErrorNone) {
321         goto EXIT;
322     }
323
324     if (pOMXComponent->pComponentPrivate == NULL) {
325         ret = OMX_ErrorBadParameter;
326         goto EXIT;
327     }
328     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
329
330     if (pExynosComponent->hComponentHandle == NULL) {
331         ret = OMX_ErrorBadParameter;
332         goto EXIT;
333     }
334     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
335
336     if ((nPortIndex < 0) ||
337         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
338         ret = OMX_ErrorBadPortIndex;
339         goto EXIT;
340     }
341     pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
342
343     if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
344         ret = OMX_ErrorBadPortIndex;
345         goto EXIT;
346     }
347
348     if ((pExynosPort->portState != OMX_StateLoaded) &&
349         (pExynosPort->portState != OMX_StateInvalid)) {
350         (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
351                         pExynosComponent->callbackData,
352                         (OMX_U32)OMX_EventError,
353                         (OMX_U32)OMX_ErrorPortUnpopulated,
354                         nPortIndex, NULL);
355     }
356
357     for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) {
358         if ((pExynosPort->bufferStateAllocate[i] != BUFFER_STATE_FREE) &&
359             (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
360             pOMXBufferHdr = pExynosPort->extendBufferHeader[i].OMXBufferHeader;
361
362             if (pOMXBufferHdr->pBuffer == pBufferHdr->pBuffer) {
363                 if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
364                     Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pOMXBufferHdr->pBuffer);
365                     pOMXBufferHdr->pBuffer = NULL;
366                     pBufferHdr->pBuffer = NULL;
367                 } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) {
368                     ; /* None*/
369                 }
370                 pExynosPort->assignedBufferNum--;
371
372                 if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) {
373                     Exynos_OSAL_Free(pOMXBufferHdr);
374                     pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL;
375                     pBufferHdr = NULL;
376                 }
377
378                 pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
379                 ret = OMX_ErrorNone;
380                 goto EXIT;
381             }
382         }
383     }
384
385 EXIT:
386     if ((ret == OMX_ErrorNone) &&
387         (pExynosPort->assignedBufferNum == 0)) {
388         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
389         /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
390         Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
391         /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
392         pExynosPort->portDefinition.bPopulated = OMX_FALSE;
393     }
394
395     FunctionOut();
396
397     return ret;
398 }
399
400 OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(
401     EXYNOS_OMX_BASEPORT     *pOMXBasePort,
402     OMX_U32                  nPortIndex)
403 {
404     OMX_ERRORTYPE                 ret               = OMX_ErrorNone;
405     EXYNOS_OMX_BASEPORT          *pExynosPort       = NULL;
406     OMX_BUFFERHEADERTYPE         *pTempBufferHdr    = NULL;
407     OMX_U8                       *pTempBuffer       = NULL;
408     OMX_U32                       nBufferSize       = 0;
409     OMX_PARAM_PORTDEFINITIONTYPE  portDefinition;
410
411     ret = OMX_ErrorTunnelingUnsupported;
412 EXIT:
413     return ret;
414 }
415
416 OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(
417     EXYNOS_OMX_BASEPORT     *pOMXBasePort,
418     OMX_U32                  nPortIndex)
419 {
420     OMX_ERRORTYPE            ret            = OMX_ErrorNone;
421     EXYNOS_OMX_BASEPORT     *pExynosPort    = NULL;
422     OMX_BUFFERHEADERTYPE    *pTempBufferHdr = NULL;
423     OMX_U8                  *pTempBuffer    = NULL;
424     OMX_U32                  nBufferSize    = 0;
425
426     ret = OMX_ErrorTunnelingUnsupported;
427 EXIT:
428     return ret;
429 }
430
431 OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
432     OMX_IN OMX_HANDLETYPE hComp,
433     OMX_IN OMX_U32        nPort,
434     OMX_IN OMX_HANDLETYPE hTunneledComp,
435     OMX_IN OMX_U32        nTunneledPort,
436     OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
437 {
438     OMX_ERRORTYPE ret = OMX_ErrorNone;
439
440     ret = OMX_ErrorTunnelingUnsupported;
441 EXIT:
442     return ret;
443 }
444
445 OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(
446     EXYNOS_OMX_BASEPORT     *pExynosPort,
447     EXYNOS_OMX_DATABUFFER   *pDataBuffer[])
448 {
449     OMX_ERRORTYPE ret = OMX_ErrorNone;
450
451     FunctionIn();
452
453     *pDataBuffer = NULL;
454
455     if (pExynosPort->portWayType == WAY1_PORT) {
456         *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
457     } else if (pExynosPort->portWayType == WAY2_PORT) {
458         pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
459         pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
460     }
461
462 EXIT:
463     FunctionOut();
464
465     return ret;
466 }
467
468 OMX_ERRORTYPE Exynos_OMX_FlushPort(
469     OMX_COMPONENTTYPE   *pOMXComponent,
470     OMX_S32              nPortIndex)
471 {
472     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
473     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
474     EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
475     OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
476     EXYNOS_OMX_DATABUFFER    *pDataBuffer[2]    = {NULL, NULL};
477     EXYNOS_OMX_MESSAGE       *pMessage          = NULL;
478     OMX_S32                   nSemaCnt          = 0;
479     int                       i                 = 0;
480
481     FunctionIn();
482 #ifdef SLP_PLATFORM
483     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "flushPort idx:%d", nPortIndex);
484 #endif
485
486     if (pOMXComponent == NULL) {
487         ret = OMX_ErrorBadParameter;
488         goto EXIT;
489     }
490
491     if (pOMXComponent->pComponentPrivate == NULL) {
492         ret = OMX_ErrorBadParameter;
493         goto EXIT;
494     }
495     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
496
497     if ((nPortIndex < 0) ||
498         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
499         ret = OMX_ErrorBadPortIndex;
500         goto EXIT;
501     }
502     pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
503
504     while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
505         Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &nSemaCnt);
506         if (nSemaCnt == 0)
507             Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
508
509         Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
510         pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
511         if ((pMessage != NULL) &&
512             (pMessage->messageType != EXYNOS_OMX_CommandFakeBuffer)) {
513             pBufferHdr = (OMX_BUFFERHEADERTYPE *)pMessage->pCmdData;
514             pBufferHdr->nFilledLen = 0;
515
516             if (nPortIndex == OUTPUT_PORT_INDEX) {
517                 Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
518             } else if (nPortIndex == INPUT_PORT_INDEX) {
519                 Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
520             }
521         }
522         Exynos_OSAL_Free(pMessage);
523         pMessage = NULL;
524     }
525
526     Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer);
527     if ((pDataBuffer[0] != NULL) &&
528         (pDataBuffer[0]->dataValid == OMX_TRUE)) {
529         if (nPortIndex == INPUT_PORT_INDEX)
530             Exynos_FlushInputBufferReturn(pOMXComponent, pDataBuffer[0]);
531         else if (nPortIndex == OUTPUT_PORT_INDEX)
532             Exynos_FlushOutputBufferReturn(pOMXComponent, pDataBuffer[0]);
533     }
534     if ((pDataBuffer[1] != NULL) &&
535         (pDataBuffer[1]->dataValid == OMX_TRUE)) {
536         if (nPortIndex == INPUT_PORT_INDEX)
537             Exynos_FlushInputBufferReturn(pOMXComponent, pDataBuffer[1]);
538         else if (nPortIndex == OUTPUT_PORT_INDEX)
539             Exynos_FlushOutputBufferReturn(pOMXComponent, pDataBuffer[1]);
540     }
541
542     if (pExynosComponent->bMultiThreadProcess == OMX_TRUE) {
543         if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
544             if (pExynosPort->processData.bufferHeader != NULL) {
545                 if (nPortIndex == INPUT_PORT_INDEX) {
546                     Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
547                 } else if (nPortIndex == OUTPUT_PORT_INDEX) {
548                     Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
549                 }
550             }
551             Exynos_ResetCodecData(&pExynosPort->processData);
552
553             for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
554                 if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
555                     if (nPortIndex == OUTPUT_PORT_INDEX) {
556                         Exynos_OMX_OutputBufferReturn(pOMXComponent,
557                                                       pExynosPort->extendBufferHeader[i].OMXBufferHeader);
558                     } else if (nPortIndex == INPUT_PORT_INDEX) {
559                         Exynos_OMX_InputBufferReturn(pOMXComponent,
560                                                      pExynosPort->extendBufferHeader[i].OMXBufferHeader);
561                     }
562                 }
563             }
564         }
565     } else {
566         Exynos_ResetCodecData(&pExynosPort->processData);
567     }
568
569     while (1) {
570         OMX_S32 cnt = 0;
571         Exynos_OSAL_Get_SemaphoreCount(pExynosPort->bufferSemID, &cnt);
572         if (cnt <= 0)
573             break;
574         Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
575     }
576     Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ);
577
578 EXIT:
579     FunctionOut();
580
581     return ret;
582 }
583
584 OMX_ERRORTYPE Exynos_OMX_BufferFlush(
585     OMX_COMPONENTTYPE   *pOMXComponent,
586     OMX_S32              nPortIndex,
587     OMX_BOOL             bEvent)
588 {
589     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
590     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
591     EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc          = NULL;
592     EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
593     EXYNOS_OMX_DATABUFFER           *pDataBuffer[2]     = {NULL, NULL};
594     OMX_U32                          i                  = 0;
595
596     FunctionIn();
597 #ifdef SLP_PLATFORM
598     Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "bufferFlush idx:%d", nPortIndex);
599 #endif
600
601     if (pOMXComponent == NULL) {
602         ret = OMX_ErrorBadParameter;
603         goto EXIT;
604     }
605
606     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
607     if (ret != OMX_ErrorNone) {
608         goto EXIT;
609     }
610
611     if (pOMXComponent->pComponentPrivate == NULL) {
612         ret = OMX_ErrorBadParameter;
613         goto EXIT;
614     }
615     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
616
617     if (pExynosComponent->hComponentHandle == NULL) {
618         ret = OMX_ErrorBadParameter;
619         goto EXIT;
620     }
621     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
622
623     if ((nPortIndex < 0) ||
624         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
625         ret = OMX_ErrorBadPortIndex;
626         goto EXIT;
627     }
628     pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
629
630     Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex);
631
632     pExynosPort->bIsPortFlushed = OMX_TRUE;
633
634     if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
635         Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
636     } else {
637         Exynos_OSAL_SignalSet(pExynosPort->pauseEvent);
638     }
639
640     Exynos_OMX_GetFlushBuffer(pExynosPort, pDataBuffer);
641     if (pDataBuffer[0] == NULL) {
642         ret = OMX_ErrorBadParameter;
643         goto EXIT;
644     }
645
646     if (pExynosPort->bufferProcessType & BUFFER_COPY)
647         Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
648     Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
649
650     pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex);
651
652     Exynos_OSAL_MutexLock(pDataBuffer[0]->bufferMutex);
653     pVideoEnc->exynos_codec_stop(pOMXComponent, nPortIndex);
654
655     if (pDataBuffer[1] != NULL)
656         Exynos_OSAL_MutexLock(pDataBuffer[1]->bufferMutex);
657
658     ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
659     if (ret != OMX_ErrorNone)
660         goto EXIT;
661
662     if (pExynosPort->bufferProcessType & BUFFER_COPY)
663         pVideoEnc->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex);
664     Exynos_ResetCodecData(&pExynosPort->processData);
665
666     if (ret == OMX_ErrorNone) {
667         if (nPortIndex == INPUT_PORT_INDEX) {
668             pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
669             pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
670             Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
671             Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
672             pExynosComponent->getAllDelayBuffer = OMX_FALSE;
673             pExynosComponent->bSaveFlagEOS = OMX_FALSE;
674             pExynosComponent->reInputData = OMX_FALSE;
675         }
676
677         pExynosPort->bIsPortFlushed = OMX_FALSE;
678         Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex);
679         if (bEvent == OMX_TRUE)
680             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
681                             pExynosComponent->callbackData,
682                             OMX_EventCmdComplete,
683                             OMX_CommandFlush, nPortIndex, NULL);
684     }
685
686     if (pDataBuffer[1] != NULL)
687         Exynos_OSAL_MutexUnlock(pDataBuffer[1]->bufferMutex);
688
689     Exynos_OSAL_MutexUnlock(pDataBuffer[0]->bufferMutex);
690
691 EXIT:
692     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
693         Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
694         pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
695                         pExynosComponent->callbackData,
696                         OMX_EventError,
697                         ret, 0, NULL);
698     }
699
700     FunctionOut();
701
702     return ret;
703 }
704
705 OMX_ERRORTYPE Exynos_InputBufferReturn(
706     OMX_COMPONENTTYPE   *pOMXComponent)
707 {
708     OMX_ERRORTYPE                ret                = OMX_ErrorNone;
709     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
710     EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
711     EXYNOS_OMX_DATABUFFER       *pDataBuffer        = NULL;
712     OMX_BUFFERHEADERTYPE        *pBufferHdr         = NULL;
713
714     FunctionIn();
715
716     if (pOMXComponent == NULL) {
717         ret = OMX_ErrorBadParameter;
718         goto EXIT;
719     }
720
721     if (pOMXComponent->pComponentPrivate == NULL) {
722         ret = OMX_ErrorBadParameter;
723         goto EXIT;
724     }
725     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
726     pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
727
728     if (pExynosPort->bufferProcessType & BUFFER_COPY) {
729         pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
730     } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
731         pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
732     }
733
734     pBufferHdr = pDataBuffer->bufferHeader;
735
736     if (pBufferHdr != NULL) {
737         if (pExynosPort->markType.hMarkTargetComponent != NULL) {
738             pBufferHdr->hMarkTargetComponent = pExynosPort->markType.hMarkTargetComponent;
739             pBufferHdr->pMarkData            = pExynosPort->markType.pMarkData;
740             pExynosPort->markType.hMarkTargetComponent = NULL;
741             pExynosPort->markType.pMarkData = NULL;
742         }
743
744         if (pBufferHdr->hMarkTargetComponent != NULL) {
745             if (pBufferHdr->hMarkTargetComponent == pOMXComponent) {
746                 pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
747                                 pExynosComponent->callbackData,
748                                 OMX_EventMark,
749                                 0, 0, pBufferHdr->pMarkData);
750             } else {
751                 pExynosComponent->propagateMarkType.hMarkTargetComponent = pBufferHdr->hMarkTargetComponent;
752                 pExynosComponent->propagateMarkType.pMarkData = pBufferHdr->pMarkData;
753             }
754         }
755
756         pBufferHdr->nFilledLen = 0;
757         pBufferHdr->nOffset = 0;
758         Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
759     }
760
761     /* reset dataBuffer */
762     Exynos_ResetDataBuffer(pDataBuffer);
763
764 EXIT:
765     FunctionOut();
766
767     return ret;
768 }
769
770 OMX_ERRORTYPE Exynos_FlushInputBufferReturn(
771     OMX_COMPONENTTYPE       *pOMXComponent,
772     EXYNOS_OMX_DATABUFFER   *pDataBuffer)
773 {
774     OMX_ERRORTYPE                ret = OMX_ErrorNone;
775     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
776     EXYNOS_OMX_BASEPORT         *pExynosPort        = NULL;
777     OMX_BUFFERHEADERTYPE        *pBufferHdr         = NULL;
778
779     FunctionIn();
780
781     if (pOMXComponent == NULL) {
782         ret = OMX_ErrorBadParameter;
783         goto EXIT;
784     }
785
786     if (pOMXComponent->pComponentPrivate == NULL) {
787         ret = OMX_ErrorBadParameter;
788         goto EXIT;
789     }
790     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
791     pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
792
793     pBufferHdr = pDataBuffer->bufferHeader;
794
795     if (pBufferHdr != NULL) {
796         if (pExynosPort->markType.hMarkTargetComponent != NULL) {
797             pBufferHdr->hMarkTargetComponent  = pExynosPort->markType.hMarkTargetComponent;
798             pBufferHdr->pMarkData             = pExynosPort->markType.pMarkData;
799             pExynosPort->markType.hMarkTargetComponent = NULL;
800             pExynosPort->markType.pMarkData = NULL;
801         }
802
803         if (pBufferHdr->hMarkTargetComponent != NULL) {
804             if (pBufferHdr->hMarkTargetComponent == pOMXComponent) {
805                 pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
806                                 pExynosComponent->callbackData,
807                                 OMX_EventMark,
808                                 0, 0, pBufferHdr->pMarkData);
809             } else {
810                 pExynosComponent->propagateMarkType.hMarkTargetComponent = pBufferHdr->hMarkTargetComponent;
811                 pExynosComponent->propagateMarkType.pMarkData = pBufferHdr->pMarkData;
812             }
813         }
814
815         pBufferHdr->nFilledLen = 0;
816         pBufferHdr->nOffset = 0;
817         Exynos_OMX_InputBufferReturn(pOMXComponent, pBufferHdr);
818     }
819
820     /* reset dataBuffer */
821     Exynos_ResetDataBuffer(pDataBuffer);
822
823 EXIT:
824     FunctionOut();
825
826     return ret;
827 }
828
829 OMX_ERRORTYPE Exynos_InputBufferGetQueue(
830     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
831 {
832     OMX_ERRORTYPE          ret          = OMX_ErrorUndefined;
833     EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
834     EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
835     EXYNOS_OMX_DATABUFFER *pDataBuffer  = NULL;
836
837     FunctionIn();
838
839     if (pExynosComponent == NULL) {
840         ret = OMX_ErrorBadParameter;
841         goto EXIT;
842     }
843     pExynosPort = &(pExynosComponent->pExynosPort[INPUT_PORT_INDEX]);
844     pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
845
846     if (pExynosComponent->currentState != OMX_StateExecuting) {
847         ret = OMX_ErrorUndefined;
848         goto EXIT;
849     } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
850                (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
851         Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
852         if (pDataBuffer->dataValid != OMX_TRUE) {
853             pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
854             if (pMessage == NULL) {
855                 ret = OMX_ErrorUndefined;
856                 goto EXIT;
857             }
858             if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) {
859                 Exynos_OSAL_Free(pMessage);
860                 ret = OMX_ErrorCodecFlush;
861                 goto EXIT;
862             }
863
864             pDataBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
865             pDataBuffer->allocSize     = pDataBuffer->bufferHeader->nAllocLen;
866             pDataBuffer->dataLen       = pDataBuffer->bufferHeader->nFilledLen;
867             pDataBuffer->remainDataLen = pDataBuffer->dataLen;
868             pDataBuffer->usedDataLen   = 0;
869             pDataBuffer->dataValid     = OMX_TRUE;
870             pDataBuffer->nFlags        = pDataBuffer->bufferHeader->nFlags;
871             pDataBuffer->timeStamp     = pDataBuffer->bufferHeader->nTimeStamp;
872
873             Exynos_OSAL_Free(pMessage);
874
875 #ifndef SLP_PLATFORM
876             if (pDataBuffer->allocSize <= pDataBuffer->dataLen)
877                 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", pDataBuffer->allocSize, pDataBuffer->dataLen);
878 #endif
879         }
880         ret = OMX_ErrorNone;
881     }
882 EXIT:
883     FunctionOut();
884
885     return ret;
886 }
887
888 OMX_ERRORTYPE Exynos_OutputBufferReturn(
889     OMX_COMPONENTTYPE   *pOMXComponent)
890 {
891     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
892     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
893     EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
894     EXYNOS_OMX_DATABUFFER    *pDataBuffer       = NULL;
895     OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
896
897     FunctionIn();
898
899     if (pOMXComponent == NULL) {
900         ret = OMX_ErrorBadParameter;
901         goto EXIT;
902     }
903
904     if (pOMXComponent->pComponentPrivate == NULL) {
905         ret = OMX_ErrorBadParameter;
906         goto EXIT;
907     }
908     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
909     pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
910
911     pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
912     pBufferHdr = pDataBuffer->bufferHeader;
913
914     if (pBufferHdr != NULL) {
915         pBufferHdr->nFilledLen = pDataBuffer->remainDataLen;
916         pBufferHdr->nOffset    = 0;
917         pBufferHdr->nFlags     = pDataBuffer->nFlags;
918         pBufferHdr->nTimeStamp = pDataBuffer->timeStamp;
919
920         if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
921             pBufferHdr->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
922             pBufferHdr->pMarkData            = pExynosComponent->propagateMarkType.pMarkData;
923             pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
924             pExynosComponent->propagateMarkType.pMarkData = NULL;
925         }
926
927         if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
928             pBufferHdr->nFilledLen = 0;
929             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "event OMX_BUFFERFLAG_EOS!!!");
930             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
931                             pExynosComponent->callbackData,
932                             OMX_EventBufferFlag,
933                             OUTPUT_PORT_INDEX,
934                             pBufferHdr->nFlags, NULL);
935         }
936
937         Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
938     }
939
940     /* reset dataBuffer */
941     Exynos_ResetDataBuffer(pDataBuffer);
942
943 EXIT:
944     FunctionOut();
945
946     return ret;
947 }
948
949 OMX_ERRORTYPE Exynos_FlushOutputBufferReturn(
950     OMX_COMPONENTTYPE       *pOMXComponent,
951     EXYNOS_OMX_DATABUFFER   *pDataBuffer)
952 {
953     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
954     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
955     OMX_BUFFERHEADERTYPE     *pBufferHdr        = NULL;
956
957     FunctionIn();
958
959     if (pOMXComponent == NULL) {
960         ret = OMX_ErrorBadParameter;
961         goto EXIT;
962     }
963
964     if (pOMXComponent->pComponentPrivate == NULL) {
965         ret = OMX_ErrorBadParameter;
966         goto EXIT;
967     }
968     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
969     pBufferHdr = pDataBuffer->bufferHeader;
970
971     if (pBufferHdr != NULL) {
972         pBufferHdr->nFilledLen = pDataBuffer->remainDataLen;
973         pBufferHdr->nOffset    = 0;
974         pBufferHdr->nFlags     = pDataBuffer->nFlags;
975         pBufferHdr->nTimeStamp = pDataBuffer->timeStamp;
976
977         if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
978             pBufferHdr->hMarkTargetComponent    = pExynosComponent->propagateMarkType.hMarkTargetComponent;
979             pBufferHdr->pMarkData               = pExynosComponent->propagateMarkType.pMarkData;
980             pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
981             pExynosComponent->propagateMarkType.pMarkData = NULL;
982         }
983
984         if ((pBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
985             pBufferHdr->nFilledLen = 0;
986             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "event OMX_BUFFERFLAG_EOS!!!");
987             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
988                             pExynosComponent->callbackData,
989                             OMX_EventBufferFlag,
990                             OUTPUT_PORT_INDEX,
991                             pBufferHdr->nFlags, NULL);
992         }
993         Exynos_OMX_OutputBufferReturn(pOMXComponent, pBufferHdr);
994     }
995
996     /* reset dataBuffer */
997     Exynos_ResetDataBuffer(pDataBuffer);
998
999 EXIT:
1000     FunctionOut();
1001
1002     return ret;
1003 }
1004
1005 OMX_ERRORTYPE Exynos_OutputBufferGetQueue(
1006     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
1007 {
1008     OMX_ERRORTYPE          ret          = OMX_ErrorUndefined;
1009     EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
1010     EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
1011     EXYNOS_OMX_DATABUFFER *pDataBuffer  = NULL;
1012
1013     FunctionIn();
1014
1015     if (pExynosComponent == NULL) {
1016         ret = OMX_ErrorBadParameter;
1017         goto EXIT;
1018     }
1019     pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
1020
1021     if (pExynosPort->bufferProcessType & BUFFER_COPY) {
1022         pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
1023     } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
1024         pDataBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
1025     }
1026
1027     if (pExynosComponent->currentState != OMX_StateExecuting) {
1028         ret = OMX_ErrorUndefined;
1029         goto EXIT;
1030     } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
1031                (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
1032         Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
1033         if (pDataBuffer->dataValid != OMX_TRUE) {
1034             pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
1035             if (pMessage == NULL) {
1036                 ret = OMX_ErrorUndefined;
1037                 goto EXIT;
1038             }
1039             if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) {
1040                 Exynos_OSAL_Free(pMessage);
1041                 ret = OMX_ErrorCodecFlush;
1042                 goto EXIT;
1043             }
1044
1045             pDataBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
1046             pDataBuffer->allocSize     = pDataBuffer->bufferHeader->nAllocLen;
1047             pDataBuffer->dataLen       = 0; //dataBuffer->bufferHeader->nFilledLen;
1048             pDataBuffer->remainDataLen = pDataBuffer->dataLen;
1049             pDataBuffer->usedDataLen   = 0; //dataBuffer->bufferHeader->nOffset;
1050             pDataBuffer->dataValid     = OMX_TRUE;
1051             /* pDataBuffer->nFlags             = pDataBuffer->bufferHeader->nFlags; */
1052             /* pDtaBuffer->nTimeStamp         = pDataBuffer->bufferHeader->nTimeStamp; */
1053 /*
1054             if (pExynosPort->bufferProcessType & BUFFER_SHARE)
1055                 pDataBuffer->pPrivate      = pDataBuffer->bufferHeader->pOutputPortPrivate;
1056             else if (pExynosPort->bufferProcessType & BUFFER_COPY) {
1057                 pExynosPort->processData.dataBuffer = pDataBuffer->bufferHeader->pBuffer;
1058                 pExynosPort->processData.allocSize  = pDataBuffer->bufferHeader->nAllocLen;
1059             }
1060 */
1061             Exynos_OSAL_Free(pMessage);
1062         }
1063         ret = OMX_ErrorNone;
1064     }
1065 EXIT:
1066     FunctionOut();
1067
1068     return ret;
1069 }
1070
1071 OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(
1072     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent)
1073 {
1074     OMX_BUFFERHEADERTYPE  *pBufferHdr   = NULL;
1075     EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
1076     EXYNOS_OMX_MESSAGE    *pMessage     = NULL;
1077
1078     FunctionIn();
1079
1080     if (pExynosComponent == NULL) {
1081         pBufferHdr = NULL;
1082         goto EXIT;
1083     }
1084     pExynosPort = &(pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX]);
1085
1086     if (pExynosComponent->currentState != OMX_StateExecuting) {
1087         pBufferHdr = NULL;
1088         goto EXIT;
1089     } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
1090                (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
1091         Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
1092
1093         pMessage = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
1094         if (pMessage == NULL) {
1095             pBufferHdr = NULL;
1096             goto EXIT;
1097         }
1098         if (pMessage->messageType == EXYNOS_OMX_CommandFakeBuffer) {
1099             Exynos_OSAL_Free(pMessage);
1100             pBufferHdr = NULL;
1101             goto EXIT;
1102         }
1103
1104         pBufferHdr  = (OMX_BUFFERHEADERTYPE *)(pMessage->pCmdData);
1105         Exynos_OSAL_Free(pMessage);
1106     }
1107
1108 EXIT:
1109     FunctionOut();
1110
1111     return pBufferHdr;
1112 }
1113
1114 OMX_ERRORTYPE Exynos_CodecBufferEnqueue(
1115     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
1116     OMX_U32                      nPortIndex,
1117     OMX_PTR                      pData)
1118 {
1119     OMX_ERRORTYPE          ret         = OMX_ErrorNone;
1120     EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
1121
1122     FunctionIn();
1123
1124     if (pExynosComponent == NULL) {
1125         ret = OMX_ErrorBadParameter;
1126         goto EXIT;
1127     }
1128
1129     if ((nPortIndex < 0) ||
1130         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1131         ret = OMX_ErrorBadPortIndex;
1132         goto EXIT;
1133     }
1134     pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
1135
1136     if (pData == NULL) {
1137         ret = OMX_ErrorInsufficientResources;
1138         goto EXIT;
1139     }
1140
1141     ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)pData);
1142     if (ret != 0) {
1143         ret = OMX_ErrorUndefined;
1144         goto EXIT;
1145     }
1146     Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
1147
1148     ret = OMX_ErrorNone;
1149
1150 EXIT:
1151     FunctionOut();
1152
1153     return ret;
1154 }
1155
1156 OMX_ERRORTYPE Exynos_CodecBufferDequeue(
1157     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
1158     OMX_U32                      nPortIndex,
1159     OMX_PTR                     *pData)
1160 {
1161     OMX_ERRORTYPE          ret         = OMX_ErrorNone;
1162     EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
1163     OMX_PTR                pTempData   = NULL;
1164
1165     FunctionIn();
1166
1167     if (pExynosComponent == NULL) {
1168         ret = OMX_ErrorBadParameter;
1169         goto EXIT;
1170     }
1171
1172     if ((nPortIndex < 0) ||
1173         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1174         ret = OMX_ErrorBadPortIndex;
1175         goto EXIT;
1176     }
1177     pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
1178
1179     Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
1180     pTempData = (OMX_PTR)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ);
1181     if (pTempData != NULL) {
1182         *pData = (OMX_PTR)pTempData;
1183         ret = OMX_ErrorNone;
1184     } else {
1185         *pData = NULL;
1186         ret = OMX_ErrorUndefined;
1187     }
1188
1189 EXIT:
1190     FunctionOut();
1191
1192     return ret;
1193 }
1194
1195 OMX_ERRORTYPE Exynos_CodecBufferReset(
1196     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent,
1197     OMX_U32                      nPortIndex)
1198 {
1199     OMX_ERRORTYPE          ret          = OMX_ErrorNone;
1200     EXYNOS_OMX_BASEPORT   *pExynosPort  = NULL;
1201
1202     FunctionIn();
1203
1204     if (pExynosComponent == NULL) {
1205         ret = OMX_ErrorBadParameter;
1206         goto EXIT;
1207     }
1208
1209     if ((nPortIndex < 0) ||
1210         (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1211         ret = OMX_ErrorBadPortIndex;
1212         goto EXIT;
1213     }
1214     pExynosPort = &(pExynosComponent->pExynosPort[nPortIndex]);
1215
1216     ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ);
1217     if (ret != 0) {
1218         ret = OMX_ErrorUndefined;
1219         goto EXIT;
1220     }
1221
1222     while (1) {
1223         int cnt = 0;
1224         Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt);
1225         if (cnt > 0)
1226             Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
1227         else
1228             break;
1229     }
1230     ret = OMX_ErrorNone;
1231
1232 EXIT:
1233     FunctionOut();
1234
1235     return ret;
1236 }
1237
1238 OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter(
1239     OMX_IN OMX_HANDLETYPE hComponent,
1240     OMX_IN OMX_INDEXTYPE  nParamIndex,
1241     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1242 {
1243     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1244     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1245     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1246     EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
1247
1248     FunctionIn();
1249
1250     if (hComponent == NULL) {
1251         ret = OMX_ErrorBadParameter;
1252         goto EXIT;
1253     }
1254     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1255
1256     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1257     if (ret != OMX_ErrorNone) {
1258         goto EXIT;
1259     }
1260
1261     if (pOMXComponent->pComponentPrivate == NULL) {
1262         ret = OMX_ErrorBadParameter;
1263         goto EXIT;
1264     }
1265     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1266
1267     if (pExynosComponent->currentState == OMX_StateInvalid) {
1268         ret = OMX_ErrorInvalidState;
1269         goto EXIT;
1270     }
1271
1272     if (pComponentParameterStructure == NULL) {
1273         ret = OMX_ErrorBadParameter;
1274         goto EXIT;
1275     }
1276
1277     switch (nParamIndex) {
1278     case OMX_IndexParamVideoInit:
1279     {
1280         OMX_PORT_PARAM_TYPE *pPortParam = (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
1281         ret = Exynos_OMX_Check_SizeVersion(pPortParam, sizeof(OMX_PORT_PARAM_TYPE));
1282         if (ret != OMX_ErrorNone) {
1283             goto EXIT;
1284         }
1285
1286         pPortParam->nPorts           = pExynosComponent->portParam.nPorts;
1287         pPortParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
1288         ret = OMX_ErrorNone;
1289     }
1290         break;
1291     case OMX_IndexParamVideoPortFormat:
1292     {
1293         OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat     = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
1294         OMX_U32                         nPortIndex      = pPortFormat->nPortIndex;
1295         OMX_U32                         nIndex          = pPortFormat->nIndex;
1296         EXYNOS_OMX_BASEPORT            *pExynosPort     = NULL;
1297         OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef        = NULL;
1298         OMX_U32                         nSupportFormat  = 0;
1299
1300         ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1301         if (ret != OMX_ErrorNone) {
1302             goto EXIT;
1303         }
1304
1305         if ((nPortIndex < 0) ||
1306             (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1307             ret = OMX_ErrorBadPortIndex;
1308             goto EXIT;
1309         }
1310
1311         if (nPortIndex == INPUT_PORT_INDEX) {
1312             pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1313             pPortDef = &pExynosPort->portDefinition;
1314
1315             switch (nIndex) {
1316             case supportFormat_0:
1317                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1318                 pPortFormat->eColorFormat       = OMX_COLOR_FormatYUV420Planar;
1319                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1320                 break;
1321             case supportFormat_1:
1322                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1323                 pPortFormat->eColorFormat       = OMX_COLOR_FormatYUV420SemiPlanar;
1324                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1325                 break;
1326             case supportFormat_2:
1327                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1328                 pPortFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12Tiled;
1329                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1330                 break;
1331             case supportFormat_3:
1332                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1333                 pPortFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV21Linear;
1334                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1335                 break;
1336             case supportFormat_4:
1337 #ifdef SLP_PLATFORM
1338                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "can not support this format");
1339 #else
1340                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1341                 pPortFormat->eColorFormat       = OMX_COLOR_FormatAndroidOpaque;
1342                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1343 #endif
1344                 break;
1345             case supportFormat_5:
1346                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1347                 pPortFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
1348                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1349                 break;
1350             case supportFormat_6:
1351                 pPortFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1352                 pPortFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd;
1353                 pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1354                 break;
1355             default:
1356                 if (nIndex > supportFormat_0) {
1357                     ret = OMX_ErrorNoMore;
1358                     goto EXIT;
1359                 }
1360                 break;
1361             }
1362         } else if (nPortIndex == OUTPUT_PORT_INDEX) {
1363             nSupportFormat = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
1364             if (nIndex > nSupportFormat) {
1365                 ret = OMX_ErrorNoMore;
1366                 goto EXIT;
1367             }
1368
1369             pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1370             pPortDef = &pExynosPort->portDefinition;
1371
1372             pPortFormat->eCompressionFormat = pPortDef->format.video.eCompressionFormat;
1373             pPortFormat->eColorFormat       = pPortDef->format.video.eColorFormat;
1374             pPortFormat->xFramerate         = pPortDef->format.video.xFramerate;
1375         }
1376         ret = OMX_ErrorNone;
1377     }
1378         break;
1379     case OMX_IndexParamVideoBitrate:
1380     {
1381         OMX_VIDEO_PARAM_BITRATETYPE     *pVideoBitrate  = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
1382         OMX_U32                          nPortIndex     = pVideoBitrate->nPortIndex;
1383         EXYNOS_OMX_BASEPORT             *pExynosPort    = NULL;
1384         EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc      = NULL;
1385         OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef       = NULL;
1386
1387         if (nPortIndex != OUTPUT_PORT_INDEX) {
1388             ret = OMX_ErrorBadPortIndex;
1389             goto EXIT;
1390         } else {
1391             pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1392             if (pVideoEnc == NULL) {
1393                 ret = OMX_ErrorBadParameter;
1394                 goto EXIT;
1395             }
1396             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1397             pPortDef = &pExynosPort->portDefinition;
1398
1399             pVideoBitrate->eControlRate = pVideoEnc->eControlRate[nPortIndex];
1400             pVideoBitrate->nTargetBitrate = pPortDef->format.video.nBitrate;
1401         }
1402         ret = OMX_ErrorNone;
1403     }
1404         break;
1405     case OMX_IndexParamVideoQuantization:
1406     {
1407         OMX_VIDEO_PARAM_QUANTIZATIONTYPE  *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
1408         OMX_U32                            nPortIndex         = pVideoQuantization->nPortIndex;
1409         EXYNOS_OMX_BASEPORT               *pExynosPort        = NULL;
1410         EXYNOS_OMX_VIDEOENC_COMPONENT     *pVideoEnc          = NULL;
1411         OMX_PARAM_PORTDEFINITIONTYPE      *pPortDef           = NULL;
1412
1413         if (nPortIndex != OUTPUT_PORT_INDEX) {
1414             ret = OMX_ErrorBadPortIndex;
1415             goto EXIT;
1416         } else {
1417             pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1418             if (pVideoEnc == NULL) {
1419                 ret = OMX_ErrorBadParameter;
1420                 goto EXIT;
1421             }
1422             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1423             pPortDef = &pExynosPort->portDefinition;
1424
1425             pVideoQuantization->nQpI = pVideoEnc->quantization.nQpI;
1426             pVideoQuantization->nQpP = pVideoEnc->quantization.nQpP;
1427             pVideoQuantization->nQpB = pVideoEnc->quantization.nQpB;
1428         }
1429         ret = OMX_ErrorNone;
1430     }
1431         break;
1432     case OMX_IndexParamPortDefinition:
1433     {
1434         OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1435         OMX_U32                       nPortIndex    = pPortDef->nPortIndex;
1436         EXYNOS_OMX_BASEPORT          *pExynosPort   = NULL;
1437
1438         if ((nPortIndex < 0) ||
1439             (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1440             ret = OMX_ErrorBadPortIndex;
1441             goto EXIT;
1442         }
1443
1444         ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1445         if (ret != OMX_ErrorNone) {
1446             goto EXIT;
1447         }
1448
1449         pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1450         Exynos_OSAL_Memcpy(pPortDef, &pExynosPort->portDefinition, pPortDef->nSize);
1451
1452 #ifdef USE_STOREMETADATA
1453         if ((nPortIndex == 0) &&
1454             (pExynosPort->bStoreMetaData == OMX_TRUE)) {
1455             pPortDef->nBufferSize = MAX_INPUT_METADATA_BUFFER_SIZE;
1456         }
1457 #endif
1458     }
1459         break;
1460     default:
1461     {
1462         ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1463     }
1464         break;
1465     }
1466 EXIT:
1467     FunctionOut();
1468
1469     return ret;
1470 }
1471
1472 OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter(
1473     OMX_IN OMX_HANDLETYPE hComponent,
1474     OMX_IN OMX_INDEXTYPE  nParamIndex,
1475     OMX_IN OMX_PTR        pComponentParameterStructure)
1476 {
1477     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1478     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1479     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1480     EXYNOS_OMX_BASEPORT      *pExynosPort       = NULL;
1481
1482     FunctionIn();
1483
1484     if (hComponent == NULL) {
1485         ret = OMX_ErrorBadParameter;
1486         goto EXIT;
1487     }
1488     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1489
1490     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1491     if (ret != OMX_ErrorNone) {
1492         goto EXIT;
1493     }
1494
1495     if (pOMXComponent->pComponentPrivate == NULL) {
1496         ret = OMX_ErrorBadParameter;
1497         goto EXIT;
1498     }
1499     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1500
1501     if (pExynosComponent->currentState == OMX_StateInvalid) {
1502         ret = OMX_ErrorInvalidState;
1503         goto EXIT;
1504     }
1505
1506     if (pComponentParameterStructure == NULL) {
1507         ret = OMX_ErrorBadParameter;
1508         goto EXIT;
1509     }
1510
1511     switch (nParamIndex) {
1512     case OMX_IndexParamVideoPortFormat:
1513     {
1514         OMX_VIDEO_PARAM_PORTFORMATTYPE *pPortFormat     = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
1515         OMX_U32                         nPortIndex      = pPortFormat->nPortIndex;
1516         OMX_U32                         nIndex          = pPortFormat->nIndex;
1517         OMX_PARAM_PORTDEFINITIONTYPE   *pPortDef        = NULL;
1518         OMX_U32                         nSupportFormat  = 0;
1519
1520         ret = Exynos_OMX_Check_SizeVersion(pPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1521         if (ret != OMX_ErrorNone) {
1522             goto EXIT;
1523         }
1524
1525         if ((nPortIndex < 0) ||
1526             (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1527             ret = OMX_ErrorBadPortIndex;
1528             goto EXIT;
1529         }
1530         pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
1531
1532         pPortDef->format.video.eColorFormat       = pPortFormat->eColorFormat;
1533         pPortDef->format.video.eCompressionFormat = pPortFormat->eCompressionFormat;
1534         pPortDef->format.video.xFramerate         = pPortFormat->xFramerate;
1535     }
1536         break;
1537     case OMX_IndexParamVideoBitrate:
1538     {
1539         OMX_VIDEO_PARAM_BITRATETYPE     *pVideoBitrate = (OMX_VIDEO_PARAM_BITRATETYPE *)pComponentParameterStructure;
1540         OMX_U32                          nPortIndex    = pVideoBitrate->nPortIndex;
1541         EXYNOS_OMX_BASEPORT             *pExynosPort   = NULL;
1542         EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc     = NULL;
1543         OMX_PARAM_PORTDEFINITIONTYPE    *pPortDef      = NULL;
1544
1545         if (nPortIndex != OUTPUT_PORT_INDEX) {
1546             ret = OMX_ErrorBadPortIndex;
1547             goto EXIT;
1548         } else {
1549             pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1550             if (pVideoEnc == NULL) {
1551                 ret = OMX_ErrorBadParameter;
1552                 goto EXIT;
1553             }
1554             pPortDef = &(pExynosComponent->pExynosPort[nPortIndex].portDefinition);
1555
1556             pVideoEnc->eControlRate[nPortIndex] = pVideoBitrate->eControlRate;
1557             pPortDef->format.video.nBitrate = pVideoBitrate->nTargetBitrate;
1558         }
1559         ret = OMX_ErrorNone;
1560     }
1561         break;
1562     case OMX_IndexParamVideoQuantization:
1563     {
1564         OMX_VIDEO_PARAM_QUANTIZATIONTYPE *pVideoQuantization = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)pComponentParameterStructure;
1565         OMX_U32                           nPortIndex         = pVideoQuantization->nPortIndex;
1566         EXYNOS_OMX_BASEPORT              *pExynosPort        = NULL;
1567         EXYNOS_OMX_VIDEOENC_COMPONENT    *pVideoEnc          = NULL;
1568         OMX_PARAM_PORTDEFINITIONTYPE     *pPortDef           = NULL;
1569
1570         if (nPortIndex != OUTPUT_PORT_INDEX) {
1571             ret = OMX_ErrorBadPortIndex;
1572             goto EXIT;
1573         } else {
1574             pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1575             if (pVideoEnc == NULL) {
1576                 ret = OMX_ErrorBadParameter;
1577                 goto EXIT;
1578             }
1579             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1580             pPortDef = &pExynosPort->portDefinition;
1581
1582             pVideoEnc->quantization.nQpI = pVideoQuantization->nQpI;
1583             pVideoEnc->quantization.nQpP = pVideoQuantization->nQpP;
1584             pVideoEnc->quantization.nQpB = pVideoQuantization->nQpB;
1585         }
1586         ret = OMX_ErrorNone;
1587     }
1588         break;
1589     case OMX_IndexParamPortDefinition:
1590     {
1591         OMX_PARAM_PORTDEFINITIONTYPE *pPortDef      = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1592         OMX_U32                       nPortIndex    = pPortDef->nPortIndex;
1593         EXYNOS_OMX_BASEPORT          *pExynosPort   = NULL;
1594         OMX_U32 width, height, size;
1595
1596         if ((nPortIndex < 0) ||
1597             (nPortIndex >= pExynosComponent->portParam.nPorts)) {
1598             ret = OMX_ErrorBadPortIndex;
1599             goto EXIT;
1600         }
1601
1602         ret = Exynos_OMX_Check_SizeVersion(pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1603         if (ret != OMX_ErrorNone) {
1604             goto EXIT;
1605         }
1606
1607         pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1608
1609         if ((pExynosComponent->currentState != OMX_StateLoaded) &&
1610             (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1611             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1612                 ret = OMX_ErrorIncorrectStateOperation;
1613                 goto EXIT;
1614             }
1615         }
1616
1617         if (pPortDef->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1618             ret = OMX_ErrorBadParameter;
1619             goto EXIT;
1620         }
1621
1622         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDef, pPortDef->nSize);
1623         if (nPortIndex == INPUT_PORT_INDEX) {
1624             pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1625             Exynos_UpdateFrameSize(pOMXComponent);
1626             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosOutputPort->portDefinition.nBufferSize: %d",
1627                             pExynosPort->portDefinition.nBufferSize);
1628         }
1629         ret = OMX_ErrorNone;
1630     }
1631         break;
1632 #ifdef USE_STOREMETADATA
1633     case OMX_IndexParamStoreMetaDataBuffer:
1634     {
1635         ret = Exynos_OSAL_SetANBParameter(hComponent, nParamIndex, pComponentParameterStructure);
1636     }
1637         break;
1638 #endif
1639     default:
1640     {
1641         ret = Exynos_OMX_SetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1642     }
1643         break;
1644     }
1645 EXIT:
1646     FunctionOut();
1647
1648     return ret;
1649 }
1650
1651 OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig(
1652     OMX_HANDLETYPE  hComponent,
1653     OMX_INDEXTYPE   nParamIndex,
1654     OMX_PTR         pComponentConfigStructure)
1655 {
1656     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1657     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1658     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1659
1660     FunctionIn();
1661
1662     if ((hComponent == NULL) ||
1663         (pComponentConfigStructure == NULL)) {
1664         ret = OMX_ErrorBadParameter;
1665         goto EXIT;
1666     }
1667     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1668
1669     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1670     if (ret != OMX_ErrorNone) {
1671         goto EXIT;
1672     }
1673
1674     if (pOMXComponent->pComponentPrivate == NULL) {
1675         ret = OMX_ErrorBadParameter;
1676         goto EXIT;
1677     }
1678     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1679
1680     if (pExynosComponent->currentState == OMX_StateInvalid) {
1681         ret = OMX_ErrorInvalidState;
1682         goto EXIT;
1683     }
1684
1685     switch (nParamIndex) {
1686     case OMX_IndexConfigVideoBitrate:
1687     {
1688         OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
1689         OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
1690         EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
1691
1692         if (nPortIndex != OUTPUT_PORT_INDEX) {
1693             ret = OMX_ErrorBadPortIndex;
1694             goto EXIT;
1695         } else {
1696             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1697             pConfigBitrate->nEncodeBitrate = pExynosPort->portDefinition.format.video.nBitrate;
1698         }
1699     }
1700         break;
1701     case OMX_IndexConfigVideoFramerate:
1702     {
1703         OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
1704         OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
1705         EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
1706
1707         if (nPortIndex != OUTPUT_PORT_INDEX) {
1708             ret = OMX_ErrorBadPortIndex;
1709             goto EXIT;
1710         } else {
1711             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1712             pConfigFramerate->xEncodeFramerate = pExynosPort->portDefinition.format.video.xFramerate;
1713         }
1714     }
1715         break;
1716     default:
1717     {
1718         ret = Exynos_OMX_GetConfig(hComponent, nParamIndex, pComponentConfigStructure);
1719     }
1720         break;
1721     }
1722 EXIT:
1723     FunctionOut();
1724
1725     return ret;
1726 }
1727
1728 OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig(
1729     OMX_HANDLETYPE  hComponent,
1730     OMX_INDEXTYPE   nParamIndex,
1731     OMX_PTR         pComponentConfigStructure)
1732     {
1733     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1734     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1735     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1736
1737     FunctionIn();
1738
1739     if ((hComponent == NULL) ||
1740         (pComponentConfigStructure == NULL)) {
1741         ret = OMX_ErrorBadParameter;
1742         goto EXIT;
1743     }
1744     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1745
1746     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1747     if (ret != OMX_ErrorNone) {
1748         goto EXIT;
1749     }
1750
1751     if (pOMXComponent->pComponentPrivate == NULL) {
1752         ret = OMX_ErrorBadParameter;
1753         goto EXIT;
1754     }
1755     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1756
1757     if (pExynosComponent->currentState == OMX_StateInvalid) {
1758         ret = OMX_ErrorInvalidState;
1759         goto EXIT;
1760     }
1761
1762     switch (nParamIndex) {
1763     case OMX_IndexConfigVideoBitrate:
1764     {
1765         OMX_VIDEO_CONFIG_BITRATETYPE *pConfigBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
1766         OMX_U32                       nPortIndex     = pConfigBitrate->nPortIndex;
1767         EXYNOS_OMX_BASEPORT          *pExynosPort    = NULL;
1768
1769         if (nPortIndex != OUTPUT_PORT_INDEX) {
1770             ret = OMX_ErrorBadPortIndex;
1771             goto EXIT;
1772         } else {
1773             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1774             pExynosPort->portDefinition.format.video.nBitrate = pConfigBitrate->nEncodeBitrate;
1775         }
1776     }
1777         break;
1778     case OMX_IndexConfigVideoFramerate:
1779     {
1780         OMX_CONFIG_FRAMERATETYPE *pConfigFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
1781         OMX_U32                   nPortIndex       = pConfigFramerate->nPortIndex;
1782         EXYNOS_OMX_BASEPORT      *pExynosPort      = NULL;
1783
1784         if (nPortIndex != OUTPUT_PORT_INDEX) {
1785             ret = OMX_ErrorBadPortIndex;
1786             goto EXIT;
1787         } else {
1788             pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
1789             pExynosPort->portDefinition.format.video.xFramerate = pConfigFramerate->xEncodeFramerate;
1790         }
1791     }
1792         break;
1793     case OMX_IndexConfigVideoIntraVOPRefresh:
1794     {
1795         OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure;
1796         EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
1797         OMX_U32                        nPortIndex        = pIntraRefreshVOP->nPortIndex;
1798
1799         if (pExynosComponent->hComponentHandle == NULL) {
1800             ret = OMX_ErrorBadParameter;
1801             goto EXIT;
1802         }
1803         pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1804
1805         if (nPortIndex != OUTPUT_PORT_INDEX) {
1806             ret = OMX_ErrorBadPortIndex;
1807             goto EXIT;
1808         } else {
1809             pVideoEnc->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP;
1810         }
1811     }
1812         break;
1813     default:
1814     {
1815         ret = Exynos_OMX_SetConfig(hComponent, nParamIndex, pComponentConfigStructure);
1816     }
1817         break;
1818     }
1819 EXIT:
1820     FunctionOut();
1821
1822     return ret;
1823 }
1824
1825 OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex(
1826     OMX_IN OMX_HANDLETYPE  hComponent,
1827     OMX_IN OMX_STRING      szParamName,
1828     OMX_OUT OMX_INDEXTYPE *pIndexType)
1829 {
1830     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1831     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1832     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1833
1834     FunctionIn();
1835
1836     if (hComponent == NULL) {
1837         ret = OMX_ErrorBadParameter;
1838         goto EXIT;
1839     }
1840     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1841
1842     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1843     if (ret != OMX_ErrorNone) {
1844         goto EXIT;
1845     }
1846
1847     if (pOMXComponent->pComponentPrivate == NULL) {
1848         ret = OMX_ErrorBadParameter;
1849         goto EXIT;
1850     }
1851     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1852
1853     if ((szParamName == NULL) || (pIndexType == NULL)) {
1854         ret = OMX_ErrorBadParameter;
1855         goto EXIT;
1856     }
1857
1858     if (pExynosComponent->currentState == OMX_StateInvalid) {
1859         ret = OMX_ErrorInvalidState;
1860         goto EXIT;
1861     }
1862
1863 #ifdef USE_STOREMETADATA
1864     if (Exynos_OSAL_Strcmp(szParamName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
1865         *pIndexType = (OMX_INDEXTYPE)OMX_IndexParamStoreMetaDataBuffer;
1866     } else {
1867         ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType);
1868     }
1869 #else
1870     ret = Exynos_OMX_GetExtensionIndex(hComponent, szParamName, pIndexType);
1871 #endif
1872 EXIT:
1873     FunctionOut();
1874
1875     return ret;
1876 }