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