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