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 "Exynos_OMX_Macros.h"
31#include "Exynos_OSAL_Event.h"
32#include "Exynos_OMX_Venc.h"
33#include "Exynos_OMX_VencControl.h"
34#include "Exynos_OMX_Basecomponent.h"
35#include "Exynos_OSAL_Thread.h"
36#include "Exynos_OSAL_Semaphore.h"
37#include "Exynos_OSAL_Mutex.h"
38#include "Exynos_OSAL_ETC.h"
39#include "Exynos_OSAL_SharedMemory.h"
40
41#ifdef USE_ANB
42#include "Exynos_OSAL_Android.h"
43#endif
44
45#undef  EXYNOS_LOG_TAG
46#define EXYNOS_LOG_TAG    "EXYNOS_VIDEO_ENCCONTROL"
47#define EXYNOS_LOG_OFF
48//#define EXYNOS_TRACE_ON
49#include "Exynos_OSAL_Log.h"
50
51
52OMX_ERRORTYPE Exynos_OMX_UseBuffer(
53    OMX_IN OMX_HANDLETYPE            hComponent,
54    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
55    OMX_IN OMX_U32                   nPortIndex,
56    OMX_IN OMX_PTR                   pAppPrivate,
57    OMX_IN OMX_U32                   nSizeBytes,
58    OMX_IN OMX_U8                   *pBuffer)
59{
60    OMX_ERRORTYPE          ret = OMX_ErrorNone;
61    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
62    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
63    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
64    OMX_BUFFERHEADERTYPE  *temp_bufferHeader = NULL;
65    OMX_U32                i = 0;
66
67    FunctionIn();
68
69    if (hComponent == NULL) {
70        ret = OMX_ErrorBadParameter;
71        goto EXIT;
72    }
73    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
74    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
75    if (ret != OMX_ErrorNone) {
76        goto EXIT;
77    }
78
79    if (pOMXComponent->pComponentPrivate == NULL) {
80        ret = OMX_ErrorBadParameter;
81        goto EXIT;
82    }
83    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
84
85    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
86        ret = OMX_ErrorBadPortIndex;
87        goto EXIT;
88    }
89    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
90
91    if (pExynosPort->portState != OMX_StateIdle) {
92        ret = OMX_ErrorIncorrectStateOperation;
93        goto EXIT;
94    }
95
96    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
97        ret = OMX_ErrorBadPortIndex;
98        goto EXIT;
99    }
100
101    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
102    if (temp_bufferHeader == NULL) {
103        ret = OMX_ErrorInsufficientResources;
104        goto EXIT;
105    }
106    Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
107
108    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
109        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
110            pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
111            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED);
112            INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
113            temp_bufferHeader->pBuffer        = pBuffer;
114            temp_bufferHeader->nAllocLen      = nSizeBytes;
115            temp_bufferHeader->pAppPrivate    = pAppPrivate;
116            if (nPortIndex == INPUT_PORT_INDEX)
117                temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
118            else
119                temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
120
121            pExynosPort->assignedBufferNum++;
122            if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) {
123                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
124                /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
125                Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
126                /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
127            }
128            *ppBufferHdr = temp_bufferHeader;
129            ret = OMX_ErrorNone;
130            goto EXIT;
131        }
132    }
133
134    Exynos_OSAL_Free(temp_bufferHeader);
135    ret = OMX_ErrorInsufficientResources;
136
137EXIT:
138    FunctionOut();
139
140    return ret;
141}
142
143OMX_ERRORTYPE Exynos_OMX_AllocateBuffer(
144    OMX_IN OMX_HANDLETYPE            hComponent,
145    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
146    OMX_IN OMX_U32                   nPortIndex,
147    OMX_IN OMX_PTR                   pAppPrivate,
148    OMX_IN OMX_U32                   nSizeBytes)
149{
150    OMX_ERRORTYPE          ret = OMX_ErrorNone;
151    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
152    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
153    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
154    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
155    OMX_BUFFERHEADERTYPE  *temp_bufferHeader = NULL;
156    OMX_U8                *temp_buffer = NULL;
157    int                    temp_buffer_fd = -1;
158    OMX_U32                i = 0;
159    MEMORY_TYPE            mem_type;
160
161    FunctionIn();
162
163    if (hComponent == NULL) {
164        ret = OMX_ErrorBadParameter;
165        goto EXIT;
166    }
167    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
168    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
169    if (ret != OMX_ErrorNone) {
170        goto EXIT;
171    }
172
173    if (pOMXComponent->pComponentPrivate == NULL) {
174        ret = OMX_ErrorBadParameter;
175        goto EXIT;
176    }
177    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
178    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
179
180    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
181        ret = OMX_ErrorBadPortIndex;
182        goto EXIT;
183    }
184    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
185/*
186    if (pExynosPort->portState != OMX_StateIdle ) {
187        ret = OMX_ErrorIncorrectStateOperation;
188        goto EXIT;
189    }
190*/
191    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
192        ret = OMX_ErrorBadPortIndex;
193        goto EXIT;
194    }
195
196    if (pExynosPort->bufferProcessType == BUFFER_SHARE) {
197        mem_type = NORMAL_MEMORY;
198    } else {
199        mem_type = SYSTEM_MEMORY;
200    }
201    temp_buffer = Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, nSizeBytes, mem_type);
202    if (temp_buffer == NULL) {
203        ret = OMX_ErrorInsufficientResources;
204        goto EXIT;
205    }
206    temp_buffer_fd = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, temp_buffer);
207
208    temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)Exynos_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE));
209    if (temp_bufferHeader == NULL) {
210        Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, temp_buffer);
211        ret = OMX_ErrorInsufficientResources;
212        goto EXIT;
213    }
214    Exynos_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE));
215
216    for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
217        if (pExynosPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) {
218            pExynosPort->extendBufferHeader[i].OMXBufferHeader = temp_bufferHeader;
219            pExynosPort->extendBufferHeader[i].buf_fd[0] = temp_buffer_fd;
220            pExynosPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED);
221            INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE);
222            temp_bufferHeader->pBuffer        = temp_buffer;
223            temp_bufferHeader->nAllocLen      = nSizeBytes;
224            temp_bufferHeader->pAppPrivate    = pAppPrivate;
225            if (nPortIndex == INPUT_PORT_INDEX)
226                temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX;
227            else
228                temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX;
229            pExynosPort->assignedBufferNum++;
230            if (pExynosPort->assignedBufferNum == pExynosPort->portDefinition.nBufferCountActual) {
231                pExynosPort->portDefinition.bPopulated = OMX_TRUE;
232                /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
233                Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
234                /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
235            }
236            *ppBuffer = temp_bufferHeader;
237            ret = OMX_ErrorNone;
238            goto EXIT;
239        }
240    }
241
242    Exynos_OSAL_Free(temp_bufferHeader);
243    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, temp_buffer);
244
245    ret = OMX_ErrorInsufficientResources;
246
247EXIT:
248    FunctionOut();
249
250    return ret;
251}
252
253OMX_ERRORTYPE Exynos_OMX_FreeBuffer(
254    OMX_IN OMX_HANDLETYPE hComponent,
255    OMX_IN OMX_U32        nPortIndex,
256    OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr)
257{
258    OMX_ERRORTYPE          ret = OMX_ErrorNone;
259    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
260    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
261    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
262    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
263    OMX_BUFFERHEADERTYPE  *temp_bufferHeader = NULL;
264    OMX_U8                *temp_buffer = NULL;
265    OMX_U32                i = 0;
266
267    FunctionIn();
268
269    if (hComponent == NULL) {
270        ret = OMX_ErrorBadParameter;
271        goto EXIT;
272    }
273    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
274    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
275    if (ret != OMX_ErrorNone) {
276        goto EXIT;
277    }
278
279    if (pOMXComponent->pComponentPrivate == NULL) {
280        ret = OMX_ErrorBadParameter;
281        goto EXIT;
282    }
283    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
284    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
285
286    if (nPortIndex >= pExynosComponent->portParam.nPorts) {
287        ret = OMX_ErrorBadPortIndex;
288        goto EXIT;
289    }
290    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
291
292    if (CHECK_PORT_TUNNELED(pExynosPort) && CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
293        ret = OMX_ErrorBadPortIndex;
294        goto EXIT;
295    }
296
297    if ((pExynosPort->portState != OMX_StateLoaded) && (pExynosPort->portState != OMX_StateInvalid)) {
298        (*(pExynosComponent->pCallbacks->EventHandler)) (pOMXComponent,
299                        pExynosComponent->callbackData,
300                        (OMX_U32)OMX_EventError,
301                        (OMX_U32)OMX_ErrorPortUnpopulated,
302                        nPortIndex, NULL);
303    }
304
305    for (i = 0; i < /*pExynosPort->portDefinition.nBufferCountActual*/MAX_BUFFER_NUM; i++) {
306        if (((pExynosPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pExynosPort->extendBufferHeader[i].OMXBufferHeader != NULL)) {
307            if (pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer == pBufferHdr->pBuffer) {
308                if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) {
309                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
310                    pExynosPort->extendBufferHeader[i].OMXBufferHeader->pBuffer = NULL;
311                    pBufferHdr->pBuffer = NULL;
312                } else if (pExynosPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) {
313                    ; /* None*/
314                }
315                pExynosPort->assignedBufferNum--;
316                if (pExynosPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) {
317                    Exynos_OSAL_Free(pExynosPort->extendBufferHeader[i].OMXBufferHeader);
318                    pExynosPort->extendBufferHeader[i].OMXBufferHeader = NULL;
319                    pBufferHdr = NULL;
320                }
321                pExynosPort->bufferStateAllocate[i] = BUFFER_STATE_FREE;
322                ret = OMX_ErrorNone;
323                goto EXIT;
324            }
325        }
326    }
327
328EXIT:
329    if (ret == OMX_ErrorNone) {
330        if (pExynosPort->assignedBufferNum == 0) {
331            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosPort->unloadedResource signal set");
332            /* Exynos_OSAL_MutexLock(pExynosComponent->compMutex); */
333            Exynos_OSAL_SemaphorePost(pExynosPort->unloadedResource);
334            /* Exynos_OSAL_MutexUnlock(pExynosComponent->compMutex); */
335            pExynosPort->portDefinition.bPopulated = OMX_FALSE;
336        }
337    }
338
339    FunctionOut();
340
341    return ret;
342}
343
344OMX_ERRORTYPE Exynos_OMX_AllocateTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex)
345{
346    OMX_ERRORTYPE                 ret = OMX_ErrorNone;
347    EXYNOS_OMX_BASEPORT             *pExynosPort = NULL;
348    OMX_BUFFERHEADERTYPE         *temp_bufferHeader = NULL;
349    OMX_U8                       *temp_buffer = NULL;
350    OMX_U32                       bufferSize = 0;
351    OMX_PARAM_PORTDEFINITIONTYPE  portDefinition;
352
353    ret = OMX_ErrorTunnelingUnsupported;
354EXIT:
355    return ret;
356}
357
358OMX_ERRORTYPE Exynos_OMX_FreeTunnelBuffer(EXYNOS_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex)
359{
360    OMX_ERRORTYPE ret = OMX_ErrorNone;
361    EXYNOS_OMX_BASEPORT* pExynosPort = NULL;
362    OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL;
363    OMX_U8 *temp_buffer = NULL;
364    OMX_U32 bufferSize = 0;
365
366    ret = OMX_ErrorTunnelingUnsupported;
367EXIT:
368    return ret;
369}
370
371OMX_ERRORTYPE Exynos_OMX_ComponentTunnelRequest(
372    OMX_IN OMX_HANDLETYPE hComp,
373    OMX_IN OMX_U32        nPort,
374    OMX_IN OMX_HANDLETYPE hTunneledComp,
375    OMX_IN OMX_U32        nTunneledPort,
376    OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup)
377{
378    OMX_ERRORTYPE ret = OMX_ErrorNone;
379
380    ret = OMX_ErrorTunnelingUnsupported;
381EXIT:
382    return ret;
383}
384
385OMX_ERRORTYPE Exynos_OMX_GetFlushBuffer(EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_DATABUFFER *pDataBuffer[])
386{
387    OMX_ERRORTYPE ret = OMX_ErrorNone;
388
389    FunctionIn();
390
391    *pDataBuffer = NULL;
392
393    if (pExynosPort->portWayType == WAY1_PORT) {
394        *pDataBuffer = &pExynosPort->way.port1WayDataBuffer.dataBuffer;
395    } else if (pExynosPort->portWayType == WAY2_PORT) {
396            pDataBuffer[0] = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
397            pDataBuffer[1] = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
398    }
399
400EXIT:
401    FunctionOut();
402
403    return ret;
404}
405
406OMX_ERRORTYPE Exynos_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
407{
408    OMX_ERRORTYPE          ret = OMX_ErrorNone;
409    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
410    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
411    OMX_BUFFERHEADERTYPE     *bufferHeader = NULL;
412    EXYNOS_OMX_DATABUFFER    *pDataPortBuffer[2] = {NULL, NULL};
413    EXYNOS_OMX_MESSAGE       *message = NULL;
414    OMX_U32                flushNum = 0;
415    OMX_S32                semValue = 0;
416    int i = 0, maxBufferNum = 0;
417    FunctionIn();
418
419    pExynosPort = &pExynosComponent->pExynosPort[portIndex];
420
421    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
422        Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &semValue);
423        if (semValue == 0)
424            Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[portIndex].bufferSemID);
425
426        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
427        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
428        if ((message != NULL) && (message->messageType != EXYNOS_OMX_CommandFakeBuffer)) {
429            bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
430            bufferHeader->nFilledLen = 0;
431
432            if (portIndex == OUTPUT_PORT_INDEX) {
433                Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
434            } else if (portIndex == INPUT_PORT_INDEX) {
435                Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
436            }
437        }
438        Exynos_OSAL_Free(message);
439        message = NULL;
440    }
441
442    Exynos_OMX_GetFlushBuffer(pExynosPort, pDataPortBuffer);
443    if (portIndex == INPUT_PORT_INDEX) {
444        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
445            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
446        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
447            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
448    } else if (portIndex == OUTPUT_PORT_INDEX) {
449        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
450            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
451        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
452            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
453    }
454
455    if (pExynosComponent->bMultiThreadProcess == OMX_TRUE) {
456        if (pExynosPort->bufferProcessType == BUFFER_SHARE) {
457            if (pExynosPort->processData.bufferHeader != NULL) {
458                if (portIndex == INPUT_PORT_INDEX) {
459                    Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
460                } else if (portIndex == OUTPUT_PORT_INDEX) {
461                    Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
462                }
463            }
464            Exynos_ResetCodecData(&pExynosPort->processData);
465
466            maxBufferNum = pExynosPort->portDefinition.nBufferCountActual;
467            for (i = 0; i < maxBufferNum; i++) {
468                if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
469                    if (portIndex == OUTPUT_PORT_INDEX) {
470                        Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
471                    } else if (portIndex == INPUT_PORT_INDEX) {
472                        Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
473                    }
474                }
475            }
476        }
477    } else {
478        Exynos_ResetCodecData(&pExynosPort->processData);
479    }
480
481    while(1) {
482        OMX_S32 cnt = 0;
483        Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt);
484        if (cnt <= 0)
485            break;
486        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
487    }
488    Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ);
489
490EXIT:
491    FunctionOut();
492
493    return ret;
494}
495
496OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent)
497{
498    OMX_ERRORTYPE             ret = OMX_ErrorNone;
499    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
500    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
501    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
502    EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
503    OMX_U32                   i = 0, cnt = 0;
504
505    FunctionIn();
506
507    if (pOMXComponent == NULL) {
508        ret = OMX_ErrorBadParameter;
509        goto EXIT;
510    }
511    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
512    if (ret != OMX_ErrorNone) {
513        goto EXIT;
514    }
515
516    if (pOMXComponent->pComponentPrivate == NULL) {
517        ret = OMX_ErrorBadParameter;
518        goto EXIT;
519    }
520    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
521    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
522
523    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex);
524
525    pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE;
526
527    if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
528        Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
529    } else {
530        Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
531    }
532
533    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
534    Exynos_OMX_GetFlushBuffer(pExynosPort, flushPortBuffer);
535
536    if ((pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
537        Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
538    Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
539
540    pVideoEnc->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex);
541    Exynos_OSAL_MutexLock(flushPortBuffer[0]->bufferMutex);
542    pVideoEnc->exynos_codec_stop(pOMXComponent, nPortIndex);
543    Exynos_OSAL_MutexLock(flushPortBuffer[1]->bufferMutex);
544    ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
545    if ((pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
546        pVideoEnc->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex);
547    Exynos_ResetCodecData(&pExynosPort->processData);
548
549    if (ret == OMX_ErrorNone) {
550        if (nPortIndex == INPUT_PORT_INDEX) {
551            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
552            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
553            Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
554            Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
555            pExynosComponent->getAllDelayBuffer = OMX_FALSE;
556            pExynosComponent->bSaveFlagEOS = OMX_FALSE;
557            pExynosComponent->bBehaviorEOS = OMX_FALSE;
558            pExynosComponent->reInputData = OMX_FALSE;
559        }
560
561        pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE;
562        Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex);
563        if (bEvent == OMX_TRUE)
564            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
565                            pExynosComponent->callbackData,
566                            OMX_EventCmdComplete,
567                            OMX_CommandFlush, nPortIndex, NULL);
568    }
569    Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex);
570    Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex);
571
572EXIT:
573    if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
574        Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
575        pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
576                        pExynosComponent->callbackData,
577                        OMX_EventError,
578                        ret, 0, NULL);
579    }
580
581    FunctionOut();
582
583    return ret;
584}
585
586OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer)
587{
588    OMX_ERRORTYPE          ret = OMX_ErrorNone;
589    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
590    EXYNOS_OMX_BASEPORT      *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
591    OMX_BUFFERHEADERTYPE  *bufferHeader = NULL;
592
593    FunctionIn();
594
595    bufferHeader = dataBuffer->bufferHeader;
596
597    if (bufferHeader != NULL) {
598        if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) {
599            bufferHeader->hMarkTargetComponent      = exynosOMXInputPort->markType.hMarkTargetComponent;
600            bufferHeader->pMarkData                 = exynosOMXInputPort->markType.pMarkData;
601            exynosOMXInputPort->markType.hMarkTargetComponent = NULL;
602            exynosOMXInputPort->markType.pMarkData = NULL;
603        }
604
605        if (bufferHeader->hMarkTargetComponent != NULL) {
606            if (bufferHeader->hMarkTargetComponent == pOMXComponent) {
607                pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
608                                pExynosComponent->callbackData,
609                                OMX_EventMark,
610                                0, 0, bufferHeader->pMarkData);
611            } else {
612                pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent;
613                pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData;
614            }
615        }
616
617        bufferHeader->nFilledLen = 0;
618        bufferHeader->nOffset = 0;
619        Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
620    }
621
622    /* reset dataBuffer */
623    Exynos_ResetDataBuffer(dataBuffer);
624
625EXIT:
626    FunctionOut();
627
628    return ret;
629}
630
631OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
632{
633    OMX_ERRORTYPE          ret = OMX_ErrorUndefined;
634    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
635    EXYNOS_OMX_MESSAGE    *message = NULL;
636    EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
637
638    FunctionIn();
639
640    inputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
641
642    if (pExynosComponent->currentState != OMX_StateExecuting) {
643        ret = OMX_ErrorUndefined;
644        goto EXIT;
645    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
646               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
647        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
648        if (inputUseBuffer->dataValid != OMX_TRUE) {
649            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
650            if (message == NULL) {
651                ret = OMX_ErrorUndefined;
652                goto EXIT;
653            }
654            if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
655                Exynos_OSAL_Free(message);
656                ret = OMX_ErrorCodecFlush;
657                goto EXIT;
658            }
659
660            inputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
661            inputUseBuffer->allocSize     = inputUseBuffer->bufferHeader->nAllocLen;
662            inputUseBuffer->dataLen       = inputUseBuffer->bufferHeader->nFilledLen;
663            inputUseBuffer->remainDataLen = inputUseBuffer->dataLen;
664            inputUseBuffer->usedDataLen   = 0;
665            inputUseBuffer->dataValid     = OMX_TRUE;
666            inputUseBuffer->nFlags        = inputUseBuffer->bufferHeader->nFlags;
667            inputUseBuffer->timeStamp     = inputUseBuffer->bufferHeader->nTimeStamp;
668
669            Exynos_OSAL_Free(message);
670
671            if (inputUseBuffer->allocSize <= inputUseBuffer->dataLen)
672                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", inputUseBuffer->allocSize, inputUseBuffer->dataLen);
673        }
674        ret = OMX_ErrorNone;
675    }
676EXIT:
677    FunctionOut();
678
679    return ret;
680}
681
682OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer)
683{
684    OMX_ERRORTYPE          ret = OMX_ErrorNone;
685    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
686    EXYNOS_OMX_BASEPORT      *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
687    OMX_BUFFERHEADERTYPE  *bufferHeader = NULL;
688
689    FunctionIn();
690
691    bufferHeader = dataBuffer->bufferHeader;
692
693    if (bufferHeader != NULL) {
694        bufferHeader->nFilledLen = dataBuffer->remainDataLen;
695        bufferHeader->nOffset    = 0;
696        bufferHeader->nFlags     = dataBuffer->nFlags;
697        bufferHeader->nTimeStamp = dataBuffer->timeStamp;
698
699        if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
700            bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
701            bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData;
702            pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
703            pExynosComponent->propagateMarkType.pMarkData = NULL;
704        }
705
706        if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
707            Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!");
708            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
709                            pExynosComponent->callbackData,
710                            OMX_EventBufferFlag,
711                            OUTPUT_PORT_INDEX,
712                            bufferHeader->nFlags, NULL);
713        }
714
715        Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
716    }
717
718    /* reset dataBuffer */
719    Exynos_ResetDataBuffer(dataBuffer);
720
721EXIT:
722    FunctionOut();
723
724    return ret;
725}
726
727OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
728{
729    OMX_ERRORTYPE       ret = OMX_ErrorUndefined;
730    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
731    EXYNOS_OMX_MESSAGE    *message = NULL;
732    EXYNOS_OMX_DATABUFFER *outputUseBuffer = NULL;
733
734    FunctionIn();
735
736    if ((pExynosPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
737        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
738    } else if (pExynosPort->bufferProcessType == BUFFER_SHARE) {
739        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
740    }
741
742    if (pExynosComponent->currentState != OMX_StateExecuting) {
743        ret = OMX_ErrorUndefined;
744        goto EXIT;
745    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
746               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
747        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
748        if (outputUseBuffer->dataValid != OMX_TRUE) {
749            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
750            if (message == NULL) {
751                ret = OMX_ErrorUndefined;
752                goto EXIT;
753            }
754            if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
755                Exynos_OSAL_Free(message);
756                ret = OMX_ErrorCodecFlush;
757                goto EXIT;
758            }
759
760            outputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
761            outputUseBuffer->allocSize     = outputUseBuffer->bufferHeader->nAllocLen;
762            outputUseBuffer->dataLen       = 0; //dataBuffer->bufferHeader->nFilledLen;
763            outputUseBuffer->remainDataLen = outputUseBuffer->dataLen;
764            outputUseBuffer->usedDataLen   = 0; //dataBuffer->bufferHeader->nOffset;
765            outputUseBuffer->dataValid     = OMX_TRUE;
766            /* dataBuffer->nFlags             = dataBuffer->bufferHeader->nFlags; */
767            /* dataBuffer->nTimeStamp         = dataBuffer->bufferHeader->nTimeStamp; */
768/*
769            if (pExynosPort->bufferProcessType == BUFFER_SHARE)
770                outputUseBuffer->pPrivate      = outputUseBuffer->bufferHeader->pOutputPortPrivate;
771            else if ((pExynosPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
772                pExynosPort->processData.dataBuffer = outputUseBuffer->bufferHeader->pBuffer;
773                pExynosPort->processData.allocSize  = outputUseBuffer->bufferHeader->nAllocLen;
774            }
775*/
776
777            Exynos_OSAL_Free(message);
778        }
779        ret = OMX_ErrorNone;
780    }
781EXIT:
782    FunctionOut();
783
784    return ret;
785
786}
787
788OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
789{
790    OMX_BUFFERHEADERTYPE  *retBuffer = NULL;
791    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
792    EXYNOS_OMX_MESSAGE    *message = NULL;
793
794    FunctionIn();
795
796    if (pExynosComponent->currentState != OMX_StateExecuting) {
797        retBuffer = NULL;
798        goto EXIT;
799    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
800               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
801        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
802
803        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
804        if (message == NULL) {
805            retBuffer = NULL;
806            goto EXIT;
807        }
808        if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
809            Exynos_OSAL_Free(message);
810            retBuffer = NULL;
811            goto EXIT;
812        }
813
814        retBuffer  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
815        Exynos_OSAL_Free(message);
816    }
817
818EXIT:
819    FunctionOut();
820
821    return retBuffer;
822}
823
824OMX_ERRORTYPE Exynos_CodecBufferEnQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR data)
825{
826    OMX_ERRORTYPE       ret = OMX_ErrorNone;
827    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
828
829    FunctionIn();
830
831    pExynosPort= &pExynosComponent->pExynosPort[PortIndex];
832
833    if (data == NULL) {
834        ret = OMX_ErrorInsufficientResources;
835        goto EXIT;
836    }
837
838    ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)data);
839    if (ret != 0) {
840        ret = OMX_ErrorUndefined;
841        goto EXIT;
842    }
843    Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
844
845    ret = OMX_ErrorNone;
846
847EXIT:
848    FunctionOut();
849
850    return ret;
851}
852
853OMX_ERRORTYPE Exynos_CodecBufferDeQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR *data)
854{
855    OMX_ERRORTYPE       ret = OMX_ErrorNone;
856    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
857    OMX_U32 tempData;
858
859    FunctionIn();
860
861    pExynosPort = &pExynosComponent->pExynosPort[PortIndex];
862    Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
863    tempData = (OMX_U32)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ);
864    if (tempData == NULL) {
865        *data = NULL;
866        ret = OMX_ErrorUndefined;
867        goto EXIT;
868    }
869    *data = (OMX_PTR)tempData;
870
871    ret = OMX_ErrorNone;
872
873EXIT:
874    FunctionOut();
875
876    return ret;
877}
878
879OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex)
880{
881    OMX_ERRORTYPE       ret = OMX_ErrorNone;
882    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
883
884    FunctionIn();
885
886    pExynosPort= &pExynosComponent->pExynosPort[PortIndex];
887
888    ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ);
889    if (ret != 0) {
890        ret = OMX_ErrorUndefined;
891        goto EXIT;
892    }
893    while (1) {
894        int cnt = 0;
895        Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt);
896        if (cnt > 0)
897            Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
898        else
899            break;
900    }
901    ret = OMX_ErrorNone;
902
903EXIT:
904    FunctionOut();
905
906    return ret;
907}
908
909OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetParameter(
910    OMX_IN OMX_HANDLETYPE hComponent,
911    OMX_IN OMX_INDEXTYPE  nParamIndex,
912    OMX_INOUT OMX_PTR     ComponentParameterStructure)
913{
914    OMX_ERRORTYPE             ret = OMX_ErrorNone;
915    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
916    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
917    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
918
919    FunctionIn();
920
921    if (hComponent == NULL) {
922        ret = OMX_ErrorBadParameter;
923        goto EXIT;
924    }
925    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
926    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
927    if (ret != OMX_ErrorNone) {
928        goto EXIT;
929    }
930
931    if (pOMXComponent->pComponentPrivate == NULL) {
932        ret = OMX_ErrorBadParameter;
933        goto EXIT;
934    }
935    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
936
937    if (pExynosComponent->currentState == OMX_StateInvalid ) {
938        ret = OMX_ErrorInvalidState;
939        goto EXIT;
940    }
941
942    if (ComponentParameterStructure == NULL) {
943        ret = OMX_ErrorBadParameter;
944        goto EXIT;
945    }
946
947    switch (nParamIndex) {
948    case OMX_IndexParamVideoInit:
949    {
950        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
951        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
952        if (ret != OMX_ErrorNone) {
953            goto EXIT;
954        }
955
956        portParam->nPorts           = pExynosComponent->portParam.nPorts;
957        portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
958        ret = OMX_ErrorNone;
959    }
960        break;
961    case OMX_IndexParamVideoPortFormat:
962    {
963        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
964        OMX_U32                         portIndex = portFormat->nPortIndex;
965        OMX_U32                         index    = portFormat->nIndex;
966        EXYNOS_OMX_BASEPORT            *pExynosPort = NULL;
967        OMX_PARAM_PORTDEFINITIONTYPE   *portDefinition = NULL;
968        OMX_U32                         supportFormatNum = 0;
969
970        ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
971        if (ret != OMX_ErrorNone) {
972            goto EXIT;
973        }
974
975        if ((portIndex >= pExynosComponent->portParam.nPorts)) {
976            ret = OMX_ErrorBadPortIndex;
977            goto EXIT;
978        }
979
980
981        if (portIndex == INPUT_PORT_INDEX) {
982            pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
983            portDefinition = &pExynosPort->portDefinition;
984
985            switch (index) {
986            case supportFormat_0:
987                portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
988                portFormat->eColorFormat       = OMX_COLOR_FormatYUV420Planar;
989                portFormat->xFramerate           = portDefinition->format.video.xFramerate;
990                break;
991            case supportFormat_1:
992                portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
993                portFormat->eColorFormat       = OMX_COLOR_FormatYUV420SemiPlanar;
994                portFormat->xFramerate         = portDefinition->format.video.xFramerate;
995                break;
996            case supportFormat_2:
997                portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
998                portFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12Tiled;
999                portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1000                break;
1001            case supportFormat_3:
1002                portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1003                portFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV21Linear;
1004                portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1005                break;
1006            case supportFormat_4:
1007                portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1008                portFormat->eColorFormat       = OMX_COLOR_FormatAndroidOpaque;
1009                portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1010                break;
1011            default:
1012                if (index > supportFormat_0) {
1013                    ret = OMX_ErrorNoMore;
1014                    goto EXIT;
1015                }
1016                break;
1017            }
1018        } else if (portIndex == OUTPUT_PORT_INDEX) {
1019            supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
1020            if (index > supportFormatNum) {
1021                ret = OMX_ErrorNoMore;
1022                goto EXIT;
1023            }
1024
1025            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1026            portDefinition = &pExynosPort->portDefinition;
1027
1028            portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat;
1029            portFormat->eColorFormat       = portDefinition->format.video.eColorFormat;
1030            portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1031        }
1032        ret = OMX_ErrorNone;
1033    }
1034        break;
1035    case OMX_IndexParamVideoBitrate:
1036    {
1037        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
1038        OMX_U32                          portIndex = videoRateControl->nPortIndex;
1039        EXYNOS_OMX_BASEPORT             *pExynosPort = NULL;
1040        EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc = NULL;
1041        OMX_PARAM_PORTDEFINITIONTYPE    *portDefinition = NULL;
1042
1043        if ((portIndex != OUTPUT_PORT_INDEX)) {
1044            ret = OMX_ErrorBadPortIndex;
1045            goto EXIT;
1046        } else {
1047            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1048            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1049            portDefinition = &pExynosPort->portDefinition;
1050
1051            videoRateControl->eControlRate = pVideoEnc->eControlRate[portIndex];
1052            videoRateControl->nTargetBitrate = portDefinition->format.video.nBitrate;
1053        }
1054        ret = OMX_ErrorNone;
1055    }
1056        break;
1057    case OMX_IndexParamVideoQuantization:
1058    {
1059        OMX_VIDEO_PARAM_QUANTIZATIONTYPE  *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure;
1060        OMX_U32                            portIndex = videoQuantizationControl->nPortIndex;
1061        EXYNOS_OMX_BASEPORT               *pExynosPort = NULL;
1062        EXYNOS_OMX_VIDEOENC_COMPONENT     *pVideoEnc = NULL;
1063        OMX_PARAM_PORTDEFINITIONTYPE      *portDefinition = NULL;
1064
1065        if ((portIndex != OUTPUT_PORT_INDEX)) {
1066            ret = OMX_ErrorBadPortIndex;
1067            goto EXIT;
1068        } else {
1069            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1070            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1071            portDefinition = &pExynosPort->portDefinition;
1072
1073            videoQuantizationControl->nQpI = pVideoEnc->quantization.nQpI;
1074            videoQuantizationControl->nQpP = pVideoEnc->quantization.nQpP;
1075            videoQuantizationControl->nQpB = pVideoEnc->quantization.nQpB;
1076        }
1077        ret = OMX_ErrorNone;
1078    }
1079        break;
1080    case OMX_IndexParamPortDefinition:
1081    {
1082        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1083        OMX_U32                       portIndex = portDefinition->nPortIndex;
1084        EXYNOS_OMX_BASEPORT          *pExynosPort;
1085
1086        if (portIndex >= pExynosComponent->portParam.nPorts) {
1087            ret = OMX_ErrorBadPortIndex;
1088            goto EXIT;
1089        }
1090        ret = Exynos_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1091        if (ret != OMX_ErrorNone) {
1092            goto EXIT;
1093        }
1094
1095        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1096        Exynos_OSAL_Memcpy(portDefinition, &pExynosPort->portDefinition, portDefinition->nSize);
1097
1098#ifdef USE_STOREMETADATA
1099        if ((portIndex == 0) && (pExynosPort->bStoreMetaData == OMX_TRUE)) {
1100            portDefinition->nBufferSize = MAX_INPUT_METADATA_BUFFER_SIZE;
1101        }
1102#endif
1103    }
1104        break;
1105    case OMX_IndexParamVideoIntraRefresh:
1106    {
1107        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)ComponentParameterStructure;
1108        OMX_U32                           portIndex = pIntraRefresh->nPortIndex;
1109        EXYNOS_OMX_VIDEOENC_COMPONENT    *pVideoEnc = NULL;
1110
1111        if (portIndex != OUTPUT_PORT_INDEX) {
1112            ret = OMX_ErrorBadPortIndex;
1113            goto EXIT;
1114        } else {
1115            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1116            pIntraRefresh->eRefreshMode = pVideoEnc->intraRefresh.eRefreshMode;
1117            pIntraRefresh->nAirMBs = pVideoEnc->intraRefresh.nAirMBs;
1118            pIntraRefresh->nAirRef = pVideoEnc->intraRefresh.nAirRef;
1119            pIntraRefresh->nCirMBs = pVideoEnc->intraRefresh.nCirMBs;
1120        }
1121        ret = OMX_ErrorNone;
1122    }
1123        break;
1124    default:
1125    {
1126        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
1127    }
1128        break;
1129    }
1130
1131EXIT:
1132    FunctionOut();
1133
1134    return ret;
1135}
1136OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetParameter(
1137    OMX_IN OMX_HANDLETYPE hComponent,
1138    OMX_IN OMX_INDEXTYPE  nIndex,
1139    OMX_IN OMX_PTR        ComponentParameterStructure)
1140{
1141    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1142    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1143    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1144    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1145
1146    FunctionIn();
1147
1148    if (hComponent == NULL) {
1149        ret = OMX_ErrorBadParameter;
1150        goto EXIT;
1151    }
1152    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1153    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1154    if (ret != OMX_ErrorNone) {
1155        goto EXIT;
1156    }
1157
1158    if (pOMXComponent->pComponentPrivate == NULL) {
1159        ret = OMX_ErrorBadParameter;
1160        goto EXIT;
1161    }
1162    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1163
1164    if (pExynosComponent->currentState == OMX_StateInvalid ) {
1165        ret = OMX_ErrorInvalidState;
1166        goto EXIT;
1167    }
1168
1169    if (ComponentParameterStructure == NULL) {
1170        ret = OMX_ErrorBadParameter;
1171        goto EXIT;
1172    }
1173
1174    switch (nIndex) {
1175    case OMX_IndexParamVideoPortFormat:
1176    {
1177        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
1178        OMX_U32                         portIndex = portFormat->nPortIndex;
1179        OMX_U32                         index    = portFormat->nIndex;
1180        EXYNOS_OMX_BASEPORT            *pExynosPort = NULL;
1181        OMX_PARAM_PORTDEFINITIONTYPE   *portDefinition = NULL;
1182        OMX_U32                         supportFormatNum = 0;
1183
1184        ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1185        if (ret != OMX_ErrorNone) {
1186            goto EXIT;
1187        }
1188
1189        if ((portIndex >= pExynosComponent->portParam.nPorts)) {
1190            ret = OMX_ErrorBadPortIndex;
1191            goto EXIT;
1192        } else {
1193            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1194            portDefinition = &pExynosPort->portDefinition;
1195
1196            portDefinition->format.video.eColorFormat       = portFormat->eColorFormat;
1197            portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat;
1198            portDefinition->format.video.xFramerate         = portFormat->xFramerate;
1199        }
1200    }
1201        break;
1202    case OMX_IndexParamVideoBitrate:
1203    {
1204        OMX_VIDEO_PARAM_BITRATETYPE     *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure;
1205        OMX_U32                          portIndex = videoRateControl->nPortIndex;
1206        EXYNOS_OMX_BASEPORT             *pExynosPort = NULL;
1207        EXYNOS_OMX_VIDEOENC_COMPONENT   *pVideoEnc = NULL;
1208        OMX_PARAM_PORTDEFINITIONTYPE    *portDefinition = NULL;
1209
1210        if ((portIndex != OUTPUT_PORT_INDEX)) {
1211            ret = OMX_ErrorBadPortIndex;
1212            goto EXIT;
1213        } else {
1214            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1215            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1216            portDefinition = &pExynosPort->portDefinition;
1217
1218            pVideoEnc->eControlRate[portIndex] = videoRateControl->eControlRate;
1219            portDefinition->format.video.nBitrate = videoRateControl->nTargetBitrate;
1220        }
1221        ret = OMX_ErrorNone;
1222    }
1223        break;
1224    case OMX_IndexParamVideoQuantization:
1225    {
1226        OMX_VIDEO_PARAM_QUANTIZATIONTYPE *videoQuantizationControl = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)ComponentParameterStructure;
1227        OMX_U32                           portIndex = videoQuantizationControl->nPortIndex;
1228        EXYNOS_OMX_BASEPORT              *pExynosPort = NULL;
1229        EXYNOS_OMX_VIDEOENC_COMPONENT    *pVideoEnc = NULL;
1230        OMX_PARAM_PORTDEFINITIONTYPE     *portDefinition = NULL;
1231
1232        if ((portIndex != OUTPUT_PORT_INDEX)) {
1233            ret = OMX_ErrorBadPortIndex;
1234            goto EXIT;
1235        } else {
1236            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1237            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1238            portDefinition = &pExynosPort->portDefinition;
1239
1240            pVideoEnc->quantization.nQpI = videoQuantizationControl->nQpI;
1241            pVideoEnc->quantization.nQpP = videoQuantizationControl->nQpP;
1242            pVideoEnc->quantization.nQpB = videoQuantizationControl->nQpB;
1243        }
1244        ret = OMX_ErrorNone;
1245    }
1246        break;
1247    case OMX_IndexParamPortDefinition:
1248    {
1249        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1250        OMX_U32                       portIndex = pPortDefinition->nPortIndex;
1251        EXYNOS_OMX_BASEPORT          *pExynosPort;
1252        OMX_U32 width, height, size;
1253
1254        if (portIndex >= pExynosComponent->portParam.nPorts) {
1255            ret = OMX_ErrorBadPortIndex;
1256            goto EXIT;
1257        }
1258        ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1259        if (ret != OMX_ErrorNone) {
1260            goto EXIT;
1261        }
1262
1263        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1264
1265        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1266            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1267                ret = OMX_ErrorIncorrectStateOperation;
1268                goto EXIT;
1269            }
1270        }
1271        if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1272            ret = OMX_ErrorBadParameter;
1273            goto EXIT;
1274        }
1275
1276        Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1277        if (portIndex == INPUT_PORT_INDEX) {
1278            EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1279            Exynos_UpdateFrameSize(pOMXComponent);
1280            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pExynosOutputPort->portDefinition.nBufferSize: %d",
1281                            pExynosOutputPort->portDefinition.nBufferSize);
1282        }
1283        ret = OMX_ErrorNone;
1284    }
1285        break;
1286    case OMX_IndexParamVideoIntraRefresh:
1287    {
1288        OMX_VIDEO_PARAM_INTRAREFRESHTYPE *pIntraRefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)ComponentParameterStructure;
1289        OMX_U32                           portIndex = pIntraRefresh->nPortIndex;
1290        EXYNOS_OMX_VIDEOENC_COMPONENT    *pVideoEnc = NULL;
1291
1292        if (portIndex != OUTPUT_PORT_INDEX) {
1293            ret = OMX_ErrorBadPortIndex;
1294            goto EXIT;
1295        } else {
1296            pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1297            if (pIntraRefresh->eRefreshMode == OMX_VIDEO_IntraRefreshCyclic) {
1298                pVideoEnc->intraRefresh.eRefreshMode = pIntraRefresh->eRefreshMode;
1299                pVideoEnc->intraRefresh.nCirMBs = pIntraRefresh->nCirMBs;
1300                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "OMX_VIDEO_IntraRefreshCyclic Enable, nCirMBs: %d",
1301                                pVideoEnc->intraRefresh.nCirMBs);
1302            } else {
1303                ret = OMX_ErrorUnsupportedSetting;
1304                goto EXIT;
1305            }
1306        }
1307        ret = OMX_ErrorNone;
1308    }
1309        break;
1310#ifdef USE_STOREMETADATA
1311    case OMX_IndexParamStoreMetaDataBuffer:
1312    {
1313        ret = Exynos_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure);
1314    }
1315        break;
1316#endif
1317    default:
1318    {
1319        ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure);
1320    }
1321        break;
1322    }
1323
1324EXIT:
1325    FunctionOut();
1326
1327    return ret;
1328}
1329
1330OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetConfig(
1331    OMX_HANDLETYPE hComponent,
1332    OMX_INDEXTYPE nIndex,
1333    OMX_PTR pComponentConfigStructure)
1334{
1335    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1336    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1337    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1338
1339    FunctionIn();
1340
1341    if (hComponent == NULL || pComponentConfigStructure == NULL) {
1342        ret = OMX_ErrorBadParameter;
1343        goto EXIT;
1344    }
1345    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1346    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1347    if (ret != OMX_ErrorNone) {
1348        goto EXIT;
1349    }
1350    if (pOMXComponent->pComponentPrivate == NULL) {
1351        ret = OMX_ErrorBadParameter;
1352        goto EXIT;
1353    }
1354    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1355    if (pExynosComponent->currentState == OMX_StateInvalid) {
1356        ret = OMX_ErrorInvalidState;
1357        goto EXIT;
1358    }
1359
1360    switch (nIndex) {
1361    case OMX_IndexConfigVideoBitrate:
1362    {
1363        OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
1364        OMX_U32                       portIndex = pEncodeBitrate->nPortIndex;
1365        EXYNOS_OMX_BASEPORT          *pExynosPort = NULL;
1366
1367        if ((portIndex != OUTPUT_PORT_INDEX)) {
1368            ret = OMX_ErrorBadPortIndex;
1369            goto EXIT;
1370        } else {
1371            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1372            pEncodeBitrate->nEncodeBitrate = pExynosPort->portDefinition.format.video.nBitrate;
1373        }
1374    }
1375        break;
1376    case OMX_IndexConfigVideoFramerate:
1377    {
1378        OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
1379        OMX_U32                   portIndex = pFramerate->nPortIndex;
1380        EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1381
1382        if ((portIndex != OUTPUT_PORT_INDEX)) {
1383            ret = OMX_ErrorBadPortIndex;
1384            goto EXIT;
1385        } else {
1386            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1387            pFramerate->xEncodeFramerate = pExynosPort->portDefinition.format.video.xFramerate;
1388        }
1389    }
1390        break;
1391    default:
1392        ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure);
1393        break;
1394    }
1395
1396EXIT:
1397    FunctionOut();
1398
1399    return ret;
1400}
1401
1402OMX_ERRORTYPE Exynos_OMX_VideoEncodeSetConfig(
1403    OMX_HANDLETYPE hComponent,
1404    OMX_INDEXTYPE nIndex,
1405    OMX_PTR pComponentConfigStructure)
1406    {
1407    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1408    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1409    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1410
1411    FunctionIn();
1412
1413    if (hComponent == NULL || pComponentConfigStructure == NULL) {
1414        ret = OMX_ErrorBadParameter;
1415        goto EXIT;
1416    }
1417    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1418    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1419    if (ret != OMX_ErrorNone) {
1420        goto EXIT;
1421    }
1422    if (pOMXComponent->pComponentPrivate == NULL) {
1423        ret = OMX_ErrorBadParameter;
1424        goto EXIT;
1425    }
1426    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1427    if (pExynosComponent->currentState == OMX_StateInvalid) {
1428        ret = OMX_ErrorInvalidState;
1429        goto EXIT;
1430    }
1431
1432    switch (nIndex) {
1433    case OMX_IndexConfigVideoBitrate:
1434    {
1435        OMX_VIDEO_CONFIG_BITRATETYPE *pEncodeBitrate = (OMX_VIDEO_CONFIG_BITRATETYPE *)pComponentConfigStructure;
1436        OMX_U32                       portIndex = pEncodeBitrate->nPortIndex;
1437        EXYNOS_OMX_BASEPORT          *pExynosPort = NULL;
1438
1439        if ((portIndex != OUTPUT_PORT_INDEX)) {
1440            ret = OMX_ErrorBadPortIndex;
1441            goto EXIT;
1442        } else {
1443            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1444            pExynosPort->portDefinition.format.video.nBitrate = pEncodeBitrate->nEncodeBitrate;
1445        }
1446    }
1447        break;
1448    case OMX_IndexConfigVideoFramerate:
1449    {
1450        OMX_CONFIG_FRAMERATETYPE *pFramerate = (OMX_CONFIG_FRAMERATETYPE *)pComponentConfigStructure;
1451        OMX_U32                   portIndex = pFramerate->nPortIndex;
1452        EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1453
1454        if ((portIndex != OUTPUT_PORT_INDEX)) {
1455            ret = OMX_ErrorBadPortIndex;
1456            goto EXIT;
1457        } else {
1458            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1459            pExynosPort->portDefinition.format.video.xFramerate = pFramerate->xEncodeFramerate;
1460        }
1461    }
1462        break;
1463    case OMX_IndexConfigVideoIntraVOPRefresh:
1464    {
1465        OMX_CONFIG_INTRAREFRESHVOPTYPE *pIntraRefreshVOP = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pComponentConfigStructure;
1466        EXYNOS_OMX_VIDEOENC_COMPONENT *pVEncBase = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1467        OMX_U32 portIndex = pIntraRefreshVOP->nPortIndex;
1468
1469        if ((portIndex != OUTPUT_PORT_INDEX)) {
1470            ret = OMX_ErrorBadPortIndex;
1471            goto EXIT;
1472        } else {
1473            pVEncBase->IntraRefreshVOP = pIntraRefreshVOP->IntraRefreshVOP;
1474        }
1475    }
1476        break;
1477    default:
1478        ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure);
1479        break;
1480    }
1481
1482EXIT:
1483    FunctionOut();
1484
1485    return ret;
1486}
1487
1488OMX_ERRORTYPE Exynos_OMX_VideoEncodeGetExtensionIndex(
1489    OMX_IN OMX_HANDLETYPE  hComponent,
1490    OMX_IN OMX_STRING      cParameterName,
1491    OMX_OUT OMX_INDEXTYPE *pIndexType)
1492{
1493    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1494    OMX_COMPONENTTYPE        *pOMXComponent = NULL;
1495    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1496
1497    FunctionIn();
1498
1499    if (hComponent == NULL) {
1500        ret = OMX_ErrorBadParameter;
1501        goto EXIT;
1502    }
1503    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1504    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1505    if (ret != OMX_ErrorNone) {
1506        goto EXIT;
1507    }
1508
1509    if (pOMXComponent->pComponentPrivate == NULL) {
1510        ret = OMX_ErrorBadParameter;
1511        goto EXIT;
1512    }
1513    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1514
1515    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1516        ret = OMX_ErrorBadParameter;
1517        goto EXIT;
1518    }
1519    if (pExynosComponent->currentState == OMX_StateInvalid) {
1520        ret = OMX_ErrorInvalidState;
1521        goto EXIT;
1522    }
1523
1524#ifdef USE_STOREMETADATA
1525    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
1526        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer;
1527    } else {
1528        ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
1529    }
1530#else
1531    ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
1532#endif
1533
1534EXIT:
1535    FunctionOut();
1536
1537    return ret;
1538}
1539