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_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
417    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
418    OMX_BUFFERHEADERTYPE     *bufferHeader = NULL;
419    EXYNOS_OMX_DATABUFFER    *pDataPortBuffer[2] = {NULL, NULL};
420    EXYNOS_OMX_MESSAGE       *message = NULL;
421    OMX_U32                flushNum = 0;
422    OMX_S32                semValue = 0;
423    int i = 0, maxBufferNum = 0;
424    FunctionIn();
425
426    pExynosPort = &pExynosComponent->pExynosPort[portIndex];
427
428    while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
429        Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &semValue);
430        if (semValue == 0)
431            Exynos_OSAL_SemaphorePost(pExynosComponent->pExynosPort[portIndex].bufferSemID);
432
433        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
434        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
435        if ((message != NULL) && (message->messageType != EXYNOS_OMX_CommandFakeBuffer)) {
436            bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData;
437            bufferHeader->nFilledLen = 0;
438
439            if (portIndex == OUTPUT_PORT_INDEX) {
440                Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
441            } else if (portIndex == INPUT_PORT_INDEX) {
442                Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
443            }
444        }
445        Exynos_OSAL_Free(message);
446        message = NULL;
447    }
448
449    Exynos_OMX_GetFlushBuffer(pExynosPort, pDataPortBuffer);
450    if (portIndex == INPUT_PORT_INDEX) {
451        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
452            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
453        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
454            Exynos_InputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
455    } else if (portIndex == OUTPUT_PORT_INDEX) {
456        if (pDataPortBuffer[0]->dataValid == OMX_TRUE)
457            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[0]);
458        if (pDataPortBuffer[1]->dataValid == OMX_TRUE)
459            Exynos_OutputBufferReturn(pOMXComponent, pDataPortBuffer[1]);
460    }
461
462    if (pExynosComponent->bMultiThreadProcess == OMX_TRUE) {
463        if (pExynosPort->bufferProcessType == BUFFER_SHARE) {
464            if (pExynosPort->processData.bufferHeader != NULL) {
465                if (portIndex == INPUT_PORT_INDEX) {
466                    Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
467                } else if (portIndex == OUTPUT_PORT_INDEX) {
468                    Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->processData.bufferHeader);
469                }
470            }
471            Exynos_ResetCodecData(&pExynosPort->processData);
472
473            maxBufferNum = pExynosPort->portDefinition.nBufferCountActual;
474            for (i = 0; i < maxBufferNum; i++) {
475                if (pExynosPort->extendBufferHeader[i].bBufferInOMX == OMX_TRUE) {
476                    if (portIndex == OUTPUT_PORT_INDEX) {
477                        Exynos_OMX_OutputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
478                    } else if (portIndex == INPUT_PORT_INDEX) {
479                        Exynos_OMX_InputBufferReturn(pOMXComponent, pExynosPort->extendBufferHeader[i].OMXBufferHeader);
480                    }
481                }
482            }
483        }
484    } else {
485        Exynos_ResetCodecData(&pExynosPort->processData);
486    }
487
488    if ((pExynosPort->bufferProcessType == BUFFER_SHARE) &&
489        (portIndex == OUTPUT_PORT_INDEX)){
490        EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
491
492        if (pOMXComponent->pComponentPrivate == NULL) {
493            ret = OMX_ErrorBadParameter;
494            goto EXIT;
495        }
496        pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
497        pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
498
499        Exynos_OSAL_RefANB_Reset(pVideoDec->hRefHandle);
500    }
501
502    while(1) {
503        OMX_S32 cnt = 0;
504        Exynos_OSAL_Get_SemaphoreCount(pExynosComponent->pExynosPort[portIndex].bufferSemID, &cnt);
505        if (cnt <= 0)
506            break;
507        Exynos_OSAL_SemaphoreWait(pExynosComponent->pExynosPort[portIndex].bufferSemID);
508    }
509    Exynos_OSAL_ResetQueue(&pExynosPort->bufferQ);
510
511EXIT:
512    FunctionOut();
513
514    return ret;
515}
516
517OMX_ERRORTYPE Exynos_OMX_BufferFlush(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent)
518{
519    OMX_ERRORTYPE             ret = OMX_ErrorNone;
520    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
521    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
522    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
523    EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
524    OMX_U32                   i = 0, cnt = 0;
525
526    FunctionIn();
527
528    if (pOMXComponent == NULL) {
529        ret = OMX_ErrorBadParameter;
530        goto EXIT;
531    }
532    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
533    if (ret != OMX_ErrorNone) {
534        goto EXIT;
535    }
536
537    if (pOMXComponent->pComponentPrivate == NULL) {
538        ret = OMX_ErrorBadParameter;
539        goto EXIT;
540    }
541    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
542    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
543
544    Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush start, port:%d", nPortIndex);
545
546    pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_TRUE;
547
548    if (pExynosComponent->bMultiThreadProcess == OMX_FALSE) {
549        Exynos_OSAL_SignalSet(pExynosComponent->pauseEvent);
550    } else {
551        Exynos_OSAL_SignalSet(pExynosComponent->pExynosPort[nPortIndex].pauseEvent);
552    }
553
554    pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
555    Exynos_OMX_GetFlushBuffer(pExynosPort, flushPortBuffer);
556
557    if ((pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
558        Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
559    Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
560
561    pVideoDec->exynos_codec_bufferProcessRun(pOMXComponent, nPortIndex);
562    Exynos_OSAL_MutexLock(flushPortBuffer[0]->bufferMutex);
563    pVideoDec->exynos_codec_stop(pOMXComponent, nPortIndex);
564    Exynos_OSAL_MutexLock(flushPortBuffer[1]->bufferMutex);
565    ret = Exynos_OMX_FlushPort(pOMXComponent, nPortIndex);
566    if (pVideoDec->bReconfigDPB == OMX_TRUE)
567        pVideoDec->exynos_codec_reconfigAllBuffers(pOMXComponent, nPortIndex);
568    else if ((pExynosComponent->pExynosPort[nPortIndex].bufferProcessType & BUFFER_COPY) == BUFFER_COPY)
569        pVideoDec->exynos_codec_enqueueAllBuffer(pOMXComponent, nPortIndex);
570    Exynos_ResetCodecData(&pExynosPort->processData);
571
572    if (ret == OMX_ErrorNone) {
573        if (nPortIndex == INPUT_PORT_INDEX) {
574            pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
575            pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
576            Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
577            Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
578            pExynosComponent->getAllDelayBuffer = OMX_FALSE;
579            pExynosComponent->bSaveFlagEOS = OMX_FALSE;
580            pExynosComponent->bBehaviorEOS = OMX_FALSE;
581            pExynosComponent->reInputData = OMX_FALSE;
582        }
583
584        pExynosComponent->pExynosPort[nPortIndex].bIsPortFlushed = OMX_FALSE;
585        Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"OMX_CommandFlush EventCmdComplete, port:%d", nPortIndex);
586        if (bEvent == OMX_TRUE)
587            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
588                            pExynosComponent->callbackData,
589                            OMX_EventCmdComplete,
590                            OMX_CommandFlush, nPortIndex, NULL);
591    }
592    Exynos_OSAL_MutexUnlock(flushPortBuffer[1]->bufferMutex);
593    Exynos_OSAL_MutexUnlock(flushPortBuffer[0]->bufferMutex);
594
595EXIT:
596    if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
597        Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
598        pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
599                        pExynosComponent->callbackData,
600                        OMX_EventError,
601                        ret, 0, NULL);
602    }
603
604    FunctionOut();
605
606    return ret;
607}
608
609OMX_ERRORTYPE Exynos_ResolutionUpdate(OMX_COMPONENTTYPE *pOMXComponent)
610{
611    OMX_ERRORTYPE                  ret                = OMX_ErrorNone;
612    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent   = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
613    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec          = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
614    EXYNOS_OMX_BASEPORT           *pInputPort         = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
615    EXYNOS_OMX_BASEPORT           *pOutputPort        = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
616
617    pOutputPort->cropRectangle.nTop     = pOutputPort->newCropRectangle.nTop;
618    pOutputPort->cropRectangle.nLeft    = pOutputPort->newCropRectangle.nLeft;
619    pOutputPort->cropRectangle.nWidth   = pOutputPort->newCropRectangle.nWidth;
620    pOutputPort->cropRectangle.nHeight  = pOutputPort->newCropRectangle.nHeight;
621
622    pInputPort->portDefinition.format.video.nFrameWidth     = pInputPort->newPortDefinition.format.video.nFrameWidth;
623    pInputPort->portDefinition.format.video.nFrameHeight    = pInputPort->newPortDefinition.format.video.nFrameHeight;
624    pInputPort->portDefinition.format.video.nStride         = pInputPort->newPortDefinition.format.video.nStride;
625    pInputPort->portDefinition.format.video.nSliceHeight    = pInputPort->newPortDefinition.format.video.nSliceHeight;
626
627    pOutputPort->portDefinition.nBufferCountActual  = pOutputPort->newPortDefinition.nBufferCountActual;
628    pOutputPort->portDefinition.nBufferCountMin     = pOutputPort->newPortDefinition.nBufferCountMin;
629
630    Exynos_UpdateFrameSize(pOMXComponent);
631
632    return ret;
633}
634
635OMX_ERRORTYPE Exynos_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer)
636{
637    OMX_ERRORTYPE          ret = OMX_ErrorNone;
638    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
639    EXYNOS_OMX_BASEPORT      *exynosOMXInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
640    OMX_BUFFERHEADERTYPE     *bufferHeader = NULL;
641
642    FunctionIn();
643
644    bufferHeader = dataBuffer->bufferHeader;
645
646    if (bufferHeader != NULL) {
647        if (exynosOMXInputPort->markType.hMarkTargetComponent != NULL ) {
648            bufferHeader->hMarkTargetComponent      = exynosOMXInputPort->markType.hMarkTargetComponent;
649            bufferHeader->pMarkData                 = exynosOMXInputPort->markType.pMarkData;
650            exynosOMXInputPort->markType.hMarkTargetComponent = NULL;
651            exynosOMXInputPort->markType.pMarkData = NULL;
652        }
653
654        if (bufferHeader->hMarkTargetComponent != NULL) {
655            if (bufferHeader->hMarkTargetComponent == pOMXComponent) {
656                pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
657                                pExynosComponent->callbackData,
658                                OMX_EventMark,
659                                0, 0, bufferHeader->pMarkData);
660            } else {
661                pExynosComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent;
662                pExynosComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData;
663            }
664        }
665
666        bufferHeader->nFilledLen = 0;
667        bufferHeader->nOffset = 0;
668        Exynos_OMX_InputBufferReturn(pOMXComponent, bufferHeader);
669    }
670
671    /* reset dataBuffer */
672    Exynos_ResetDataBuffer(dataBuffer);
673
674EXIT:
675    FunctionOut();
676
677    return ret;
678}
679
680OMX_ERRORTYPE Exynos_InputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
681{
682    OMX_ERRORTYPE          ret = OMX_ErrorUndefined;
683    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
684    EXYNOS_OMX_MESSAGE    *message = NULL;
685    EXYNOS_OMX_DATABUFFER *inputUseBuffer = NULL;
686
687    FunctionIn();
688
689    inputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
690
691    if (pExynosComponent->currentState != OMX_StateExecuting) {
692        ret = OMX_ErrorUndefined;
693        goto EXIT;
694    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
695               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))) {
696        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
697        if (inputUseBuffer->dataValid != OMX_TRUE) {
698            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
699            if (message == NULL) {
700                ret = OMX_ErrorUndefined;
701                goto EXIT;
702            }
703            if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
704                Exynos_OSAL_Free(message);
705                ret = OMX_ErrorCodecFlush;
706                goto EXIT;
707            }
708
709            inputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
710            inputUseBuffer->allocSize     = inputUseBuffer->bufferHeader->nAllocLen;
711            inputUseBuffer->dataLen       = inputUseBuffer->bufferHeader->nFilledLen;
712            inputUseBuffer->remainDataLen = inputUseBuffer->dataLen;
713            inputUseBuffer->usedDataLen   = 0;
714            inputUseBuffer->dataValid     = OMX_TRUE;
715            inputUseBuffer->nFlags        = inputUseBuffer->bufferHeader->nFlags;
716            inputUseBuffer->timeStamp     = inputUseBuffer->bufferHeader->nTimeStamp;
717
718            Exynos_OSAL_Free(message);
719
720            if (inputUseBuffer->allocSize <= inputUseBuffer->dataLen)
721                Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", inputUseBuffer->allocSize, inputUseBuffer->dataLen);
722        }
723        ret = OMX_ErrorNone;
724    }
725EXIT:
726    FunctionOut();
727
728    return ret;
729}
730
731OMX_ERRORTYPE Exynos_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATABUFFER *dataBuffer)
732{
733    OMX_ERRORTYPE          ret = OMX_ErrorNone;
734    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
735    EXYNOS_OMX_BASEPORT      *exynosOMXOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
736    OMX_BUFFERHEADERTYPE     *bufferHeader = NULL;
737
738    FunctionIn();
739
740    bufferHeader = dataBuffer->bufferHeader;
741
742    if (bufferHeader != NULL) {
743        bufferHeader->nFilledLen = dataBuffer->remainDataLen;
744        bufferHeader->nOffset    = 0;
745        bufferHeader->nFlags     = dataBuffer->nFlags;
746        bufferHeader->nTimeStamp = dataBuffer->timeStamp;
747
748        if ((exynosOMXOutputPort->bStoreMetaData == OMX_TRUE) && (bufferHeader->nFilledLen > 0))
749            bufferHeader->nFilledLen = bufferHeader->nAllocLen;
750
751        if (pExynosComponent->propagateMarkType.hMarkTargetComponent != NULL) {
752            bufferHeader->hMarkTargetComponent = pExynosComponent->propagateMarkType.hMarkTargetComponent;
753            bufferHeader->pMarkData = pExynosComponent->propagateMarkType.pMarkData;
754            pExynosComponent->propagateMarkType.hMarkTargetComponent = NULL;
755            pExynosComponent->propagateMarkType.pMarkData = NULL;
756        }
757
758        if ((bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
759            Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"event OMX_BUFFERFLAG_EOS!!!");
760            pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
761                            pExynosComponent->callbackData,
762                            OMX_EventBufferFlag,
763                            OUTPUT_PORT_INDEX,
764                            bufferHeader->nFlags, NULL);
765        }
766
767        Exynos_OMX_OutputBufferReturn(pOMXComponent, bufferHeader);
768    }
769
770    /* reset dataBuffer */
771    Exynos_ResetDataBuffer(dataBuffer);
772
773EXIT:
774    FunctionOut();
775
776    return ret;
777}
778
779OMX_ERRORTYPE Exynos_OutputBufferGetQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
780{
781    OMX_ERRORTYPE       ret = OMX_ErrorUndefined;
782    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
783    EXYNOS_OMX_MESSAGE    *message = NULL;
784    EXYNOS_OMX_DATABUFFER *outputUseBuffer = NULL;
785
786    FunctionIn();
787
788    if ((pExynosPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
789        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.outputDataBuffer);
790    } else if (pExynosPort->bufferProcessType == BUFFER_SHARE) {
791        outputUseBuffer = &(pExynosPort->way.port2WayDataBuffer.inputDataBuffer);
792    }
793
794    if (pExynosComponent->currentState != OMX_StateExecuting) {
795        ret = OMX_ErrorUndefined;
796        goto EXIT;
797    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
798               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
799        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
800        if (outputUseBuffer->dataValid != OMX_TRUE) {
801            message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
802            if (message == NULL) {
803                ret = OMX_ErrorUndefined;
804                goto EXIT;
805            }
806            if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
807                Exynos_OSAL_Free(message);
808                ret = OMX_ErrorCodecFlush;
809                goto EXIT;
810            }
811
812            outputUseBuffer->bufferHeader  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
813            outputUseBuffer->allocSize     = outputUseBuffer->bufferHeader->nAllocLen;
814            outputUseBuffer->dataLen       = 0; //dataBuffer->bufferHeader->nFilledLen;
815            outputUseBuffer->remainDataLen = outputUseBuffer->dataLen;
816            outputUseBuffer->usedDataLen   = 0; //dataBuffer->bufferHeader->nOffset;
817            outputUseBuffer->dataValid     = OMX_TRUE;
818            /* dataBuffer->nFlags             = dataBuffer->bufferHeader->nFlags; */
819            /* dataBuffer->nTimeStamp         = dataBuffer->bufferHeader->nTimeStamp; */
820/*
821            if (pExynosPort->bufferProcessType == BUFFER_SHARE)
822                outputUseBuffer->pPrivate      = outputUseBuffer->bufferHeader->pOutputPortPrivate;
823            else if ((pExynosPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
824                pExynosPort->processData.dataBuffer = outputUseBuffer->bufferHeader->pBuffer;
825                pExynosPort->processData.allocSize  = outputUseBuffer->bufferHeader->nAllocLen;
826            }
827*/
828
829            Exynos_OSAL_Free(message);
830        }
831        ret = OMX_ErrorNone;
832    }
833EXIT:
834    FunctionOut();
835
836    return ret;
837
838}
839
840OMX_BUFFERHEADERTYPE *Exynos_OutputBufferGetQueue_Direct(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
841{
842    OMX_BUFFERHEADERTYPE  *retBuffer = NULL;
843    EXYNOS_OMX_BASEPORT   *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
844    EXYNOS_OMX_MESSAGE    *message = NULL;
845
846    FunctionIn();
847
848    if (pExynosComponent->currentState != OMX_StateExecuting) {
849        retBuffer = NULL;
850        goto EXIT;
851    } else if ((pExynosComponent->transientState != EXYNOS_OMX_TransStateExecutingToIdle) &&
852               (!CHECK_PORT_BEING_FLUSHED(pExynosPort))){
853        Exynos_OSAL_SemaphoreWait(pExynosPort->bufferSemID);
854
855        message = (EXYNOS_OMX_MESSAGE *)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
856        if (message == NULL) {
857            retBuffer = NULL;
858            goto EXIT;
859        }
860        if (message->messageType == EXYNOS_OMX_CommandFakeBuffer) {
861            Exynos_OSAL_Free(message);
862            retBuffer = NULL;
863            goto EXIT;
864        }
865
866        retBuffer  = (OMX_BUFFERHEADERTYPE *)(message->pCmdData);
867        Exynos_OSAL_Free(message);
868    }
869
870EXIT:
871    FunctionOut();
872
873    return retBuffer;
874}
875
876OMX_ERRORTYPE Exynos_CodecBufferEnQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR data)
877{
878    OMX_ERRORTYPE       ret = OMX_ErrorNone;
879    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
880
881    FunctionIn();
882
883    pExynosPort= &pExynosComponent->pExynosPort[PortIndex];
884
885    if (data == NULL) {
886        ret = OMX_ErrorInsufficientResources;
887        goto EXIT;
888    }
889
890    ret = Exynos_OSAL_Queue(&pExynosPort->codecBufferQ, (void *)data);
891    if (ret != 0) {
892        ret = OMX_ErrorUndefined;
893        goto EXIT;
894    }
895    Exynos_OSAL_SemaphorePost(pExynosPort->codecSemID);
896
897    ret = OMX_ErrorNone;
898
899EXIT:
900    FunctionOut();
901
902    return ret;
903}
904
905OMX_ERRORTYPE Exynos_CodecBufferDeQueue(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex, OMX_PTR *data)
906{
907    OMX_ERRORTYPE       ret = OMX_ErrorNone;
908    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
909    OMX_U32 tempData;
910
911    FunctionIn();
912
913    pExynosPort = &pExynosComponent->pExynosPort[PortIndex];
914    Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
915    tempData = (OMX_U32)Exynos_OSAL_Dequeue(&pExynosPort->codecBufferQ);
916    if (tempData == NULL) {
917        *data = NULL;
918        ret = OMX_ErrorUndefined;
919        goto EXIT;
920    }
921    *data = (OMX_PTR)tempData;
922
923    ret = OMX_ErrorNone;
924
925EXIT:
926    FunctionOut();
927
928    return ret;
929}
930
931OMX_ERRORTYPE Exynos_CodecBufferReset(EXYNOS_OMX_BASECOMPONENT *pExynosComponent, OMX_U32 PortIndex)
932{
933    OMX_ERRORTYPE       ret = OMX_ErrorNone;
934    EXYNOS_OMX_BASEPORT   *pExynosPort = NULL;
935
936    FunctionIn();
937
938    pExynosPort= &pExynosComponent->pExynosPort[PortIndex];
939
940    ret = Exynos_OSAL_ResetQueue(&pExynosPort->codecBufferQ);
941    if (ret != 0) {
942        ret = OMX_ErrorUndefined;
943        goto EXIT;
944    }
945    while (1) {
946        int cnt = 0;
947        Exynos_OSAL_Get_SemaphoreCount(pExynosPort->codecSemID, &cnt);
948        if (cnt > 0)
949            Exynos_OSAL_SemaphoreWait(pExynosPort->codecSemID);
950        else
951            break;
952    }
953    ret = OMX_ErrorNone;
954
955EXIT:
956    FunctionOut();
957
958    return ret;
959}
960
961OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetParameter(
962    OMX_IN OMX_HANDLETYPE hComponent,
963    OMX_IN OMX_INDEXTYPE  nParamIndex,
964    OMX_INOUT OMX_PTR     ComponentParameterStructure)
965{
966    OMX_ERRORTYPE          ret = OMX_ErrorNone;
967    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
968    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
969    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
970
971    FunctionIn();
972
973    if (hComponent == NULL) {
974        ret = OMX_ErrorBadParameter;
975        goto EXIT;
976    }
977    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
978    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
979    if (ret != OMX_ErrorNone) {
980        goto EXIT;
981    }
982
983    if (pOMXComponent->pComponentPrivate == NULL) {
984        ret = OMX_ErrorBadParameter;
985        goto EXIT;
986    }
987    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
988
989    if (pExynosComponent->currentState == OMX_StateInvalid ) {
990        ret = OMX_ErrorInvalidState;
991        goto EXIT;
992    }
993
994    if (ComponentParameterStructure == NULL) {
995        ret = OMX_ErrorBadParameter;
996        goto EXIT;
997    }
998
999    switch (nParamIndex) {
1000    case OMX_IndexParamVideoInit:
1001    {
1002        OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure;
1003        ret = Exynos_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE));
1004        if (ret != OMX_ErrorNone) {
1005            goto EXIT;
1006        }
1007
1008        portParam->nPorts           = pExynosComponent->portParam.nPorts;
1009        portParam->nStartPortNumber = pExynosComponent->portParam.nStartPortNumber;
1010        ret = OMX_ErrorNone;
1011    }
1012        break;
1013    case OMX_IndexParamVideoPortFormat:
1014    {
1015        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
1016        OMX_U32                         portIndex = portFormat->nPortIndex;
1017        OMX_U32                         index    = portFormat->nIndex;
1018        EXYNOS_OMX_BASEPORT               *pExynosPort = NULL;
1019        OMX_PARAM_PORTDEFINITIONTYPE   *portDefinition = NULL;
1020        OMX_U32                         supportFormatNum = 0; /* supportFormatNum = N-1 */
1021
1022        ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1023        if (ret != OMX_ErrorNone) {
1024            goto EXIT;
1025        }
1026
1027        if ((portIndex >= pExynosComponent->portParam.nPorts)) {
1028            ret = OMX_ErrorBadPortIndex;
1029            goto EXIT;
1030        }
1031
1032
1033        if (portIndex == INPUT_PORT_INDEX) {
1034            supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1;
1035            if (index > supportFormatNum) {
1036                ret = OMX_ErrorNoMore;
1037                goto EXIT;
1038            }
1039
1040            pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1041            portDefinition = &pExynosPort->portDefinition;
1042
1043            portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat;
1044            portFormat->eColorFormat       = portDefinition->format.video.eColorFormat;
1045            portFormat->xFramerate           = portDefinition->format.video.xFramerate;
1046        } else if (portIndex == OUTPUT_PORT_INDEX) {
1047            pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1048            portDefinition = &pExynosPort->portDefinition;
1049
1050            if ((pExynosPort->bIsANBEnabled == OMX_FALSE) &&
1051                (pExynosPort->bStoreMetaData == OMX_FALSE)) {
1052                switch (index) {
1053                case supportFormat_0:
1054                    portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1055                    portFormat->eColorFormat       = OMX_COLOR_FormatYUV420Planar;
1056                    portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1057                    break;
1058                case supportFormat_1:
1059                    portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1060                    portFormat->eColorFormat       = OMX_COLOR_FormatYUV420SemiPlanar;
1061                    portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1062                    break;
1063                case supportFormat_2:
1064                    portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1065                    portFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12TPhysicalAddress;
1066                    portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1067                    break;
1068                case supportFormat_3:
1069                    portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1070                    portFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12Tiled;
1071                    portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1072                    break;
1073                default:
1074                    if (index > supportFormat_0) {
1075                        ret = OMX_ErrorNoMore;
1076                        goto EXIT;
1077                    }
1078                    break;
1079                }
1080            } else {
1081                switch (index) {
1082                case supportFormat_0:
1083                    portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused;
1084                    portFormat->eColorFormat       = OMX_SEC_COLOR_FormatNV12Tiled;
1085                    portFormat->xFramerate         = portDefinition->format.video.xFramerate;
1086                    break;
1087                default:
1088                    if (index > supportFormat_0) {
1089                        ret = OMX_ErrorNoMore;
1090                        goto EXIT;
1091                    }
1092                    break;
1093                }
1094            }
1095        }
1096        ret = OMX_ErrorNone;
1097    }
1098        break;
1099#ifdef USE_ANB
1100    case OMX_IndexParamGetAndroidNativeBuffer:
1101    {
1102        ret = Exynos_OSAL_GetANBParameter(hComponent, nParamIndex, ComponentParameterStructure);
1103    }
1104        break;
1105    case OMX_IndexParamPortDefinition:
1106    {
1107        OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1108        OMX_U32                       portIndex = portDefinition->nPortIndex;
1109        EXYNOS_OMX_BASEPORT             *pExynosPort;
1110
1111        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
1112        if (ret != OMX_ErrorNone) {
1113            goto EXIT;
1114        }
1115
1116        /* at this point, GetParameter has done all the verification, we
1117         * just dereference things directly here
1118         */
1119        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1120        if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
1121            (pExynosPort->bStoreMetaData == OMX_TRUE)){
1122            portDefinition->format.video.eColorFormat =
1123                (OMX_COLOR_FORMATTYPE)Exynos_OSAL_OMX2HalPixelFormat(portDefinition->format.video.eColorFormat);
1124            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portDefinition->format.video.eColorFormat:0x%x", portDefinition->format.video.eColorFormat);
1125        }
1126    }
1127        break;
1128#endif
1129    default:
1130    {
1131        ret = Exynos_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
1132    }
1133        break;
1134    }
1135
1136EXIT:
1137    FunctionOut();
1138
1139    return ret;
1140}
1141OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetParameter(
1142    OMX_IN OMX_HANDLETYPE hComponent,
1143    OMX_IN OMX_INDEXTYPE  nIndex,
1144    OMX_IN OMX_PTR        ComponentParameterStructure)
1145{
1146    OMX_ERRORTYPE          ret = OMX_ErrorNone;
1147    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1148    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1149    EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
1150
1151    FunctionIn();
1152
1153    if (hComponent == NULL) {
1154        ret = OMX_ErrorBadParameter;
1155        goto EXIT;
1156    }
1157    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1158    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1159    if (ret != OMX_ErrorNone) {
1160        goto EXIT;
1161    }
1162
1163    if (pOMXComponent->pComponentPrivate == NULL) {
1164        ret = OMX_ErrorBadParameter;
1165        goto EXIT;
1166    }
1167    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1168
1169    if (pExynosComponent->currentState == OMX_StateInvalid ) {
1170        ret = OMX_ErrorInvalidState;
1171        goto EXIT;
1172    }
1173
1174    if (ComponentParameterStructure == NULL) {
1175        ret = OMX_ErrorBadParameter;
1176        goto EXIT;
1177    }
1178
1179    switch (nIndex) {
1180    case OMX_IndexParamVideoPortFormat:
1181    {
1182        OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
1183        OMX_U32                         portIndex = portFormat->nPortIndex;
1184        OMX_U32                         index    = portFormat->nIndex;
1185        EXYNOS_OMX_BASEPORT               *pExynosPort = NULL;
1186        OMX_PARAM_PORTDEFINITIONTYPE   *portDefinition = NULL;
1187        OMX_U32                         supportFormatNum = 0;
1188
1189        ret = Exynos_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
1190        if (ret != OMX_ErrorNone) {
1191            goto EXIT;
1192        }
1193
1194        if ((portIndex >= pExynosComponent->portParam.nPorts)) {
1195            ret = OMX_ErrorBadPortIndex;
1196            goto EXIT;
1197        } else {
1198            pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1199            portDefinition = &pExynosPort->portDefinition;
1200
1201            portDefinition->format.video.eColorFormat       = portFormat->eColorFormat;
1202            portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat;
1203            portDefinition->format.video.xFramerate         = portFormat->xFramerate;
1204
1205            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "portIndex:%d, portFormat->eColorFormat:0x%x", portIndex, portFormat->eColorFormat);
1206        }
1207    }
1208        break;
1209    case OMX_IndexParamPortDefinition:
1210    {
1211        OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
1212        OMX_U32                       portIndex = pPortDefinition->nPortIndex;
1213        EXYNOS_OMX_BASEPORT             *pExynosPort;
1214        OMX_U32 width, height, size;
1215        OMX_U32 realWidth, realHeight;
1216
1217        if (portIndex >= pExynosComponent->portParam.nPorts) {
1218            ret = OMX_ErrorBadPortIndex;
1219            goto EXIT;
1220        }
1221        ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1222        if (ret != OMX_ErrorNone) {
1223            goto EXIT;
1224        }
1225
1226        pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1227
1228        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1229            if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1230                ret = OMX_ErrorIncorrectStateOperation;
1231                goto EXIT;
1232            }
1233        }
1234        if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1235            ret = OMX_ErrorBadParameter;
1236            goto EXIT;
1237        }
1238
1239        Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1240
1241#ifdef USE_ANB // Modified by Google engineer
1242        /* should not affect the format since in ANB case, the caller
1243                * is providing us a HAL format */
1244        if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
1245            (pExynosPort->bStoreMetaData == OMX_TRUE)) {
1246            pExynosPort->portDefinition.format.video.eColorFormat =
1247                Exynos_OSAL_Hal2OMXPixelFormat(pExynosPort->portDefinition.format.video.eColorFormat);
1248        }
1249#endif
1250
1251        realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1252        realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1253        width = ((realWidth + 15) & (~15));
1254        height = ((realHeight + 15) & (~15));
1255        size = (width * height * 3) / 2;
1256        pExynosPort->portDefinition.format.video.nStride = width;
1257        pExynosPort->portDefinition.format.video.nSliceHeight = height;
1258        pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
1259
1260        if (portIndex == INPUT_PORT_INDEX) {
1261            EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1262            pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1263            pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1264            pExynosOutputPort->portDefinition.format.video.nStride = width;
1265            pExynosOutputPort->portDefinition.format.video.nSliceHeight = height;
1266
1267            switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) {
1268            case OMX_COLOR_FormatYUV420Planar:
1269            case OMX_COLOR_FormatYUV420SemiPlanar:
1270            case OMX_SEC_COLOR_FormatNV12TPhysicalAddress:
1271                pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
1272                break;
1273            case OMX_SEC_COLOR_FormatNV12Tiled:
1274                pExynosOutputPort->portDefinition.nBufferSize =
1275                    calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1276                    calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1277                break;
1278            default:
1279                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
1280                ret = OMX_ErrorUnsupportedSetting;
1281                break;
1282            }
1283
1284            if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1285                pExynosOutputPort->portDefinition.nBufferSize =
1286                    calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1287                    calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1288            }
1289        }
1290    }
1291        break;
1292#ifdef USE_ANB
1293    case OMX_IndexParamEnableAndroidBuffers:
1294    case OMX_IndexParamUseAndroidNativeBuffer:
1295    case OMX_IndexParamStoreMetaDataBuffer:
1296    {
1297        ret = Exynos_OSAL_SetANBParameter(hComponent, nIndex, ComponentParameterStructure);
1298    }
1299        break;
1300#endif
1301    case OMX_IndexParamEnableThumbnailMode:
1302    {
1303        EXYNOS_OMX_VIDEO_THUMBNAILMODE *pThumbnailMode = (EXYNOS_OMX_VIDEO_THUMBNAILMODE *)ComponentParameterStructure;
1304        EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1305
1306        ret = Exynos_OMX_Check_SizeVersion(pThumbnailMode, sizeof(EXYNOS_OMX_VIDEO_THUMBNAILMODE));
1307        if (ret != OMX_ErrorNone) {
1308            goto EXIT;
1309        }
1310
1311        pVideoDec->bThumbnailMode = pThumbnailMode->bEnable;
1312        if (pVideoDec->bThumbnailMode == OMX_TRUE) {
1313            EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1314            pExynosOutputPort->portDefinition.nBufferCountMin = 1;
1315            pExynosOutputPort->portDefinition.nBufferCountActual = 1;
1316        }
1317
1318        ret = OMX_ErrorNone;
1319    }
1320        break;
1321    default:
1322    {
1323        ret = Exynos_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure);
1324    }
1325        break;
1326    }
1327
1328EXIT:
1329    FunctionOut();
1330
1331    return ret;
1332}
1333
1334OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetConfig(
1335    OMX_HANDLETYPE hComponent,
1336    OMX_INDEXTYPE nIndex,
1337    OMX_PTR pComponentConfigStructure)
1338{
1339    OMX_ERRORTYPE          ret = OMX_ErrorNone;
1340    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1341    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1342
1343    FunctionIn();
1344
1345    if (hComponent == NULL) {
1346        ret = OMX_ErrorBadParameter;
1347        goto EXIT;
1348    }
1349    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1350    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1351    if (ret != OMX_ErrorNone) {
1352        goto EXIT;
1353    }
1354    if (pOMXComponent->pComponentPrivate == NULL) {
1355        ret = OMX_ErrorBadParameter;
1356        goto EXIT;
1357    }
1358    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1359    if (pComponentConfigStructure == NULL) {
1360        ret = OMX_ErrorBadParameter;
1361        goto EXIT;
1362    }
1363    if (pExynosComponent->currentState == OMX_StateInvalid) {
1364        ret = OMX_ErrorInvalidState;
1365        goto EXIT;
1366    }
1367
1368    switch (nIndex) {
1369    default:
1370        ret = Exynos_OMX_GetConfig(hComponent, nIndex, pComponentConfigStructure);
1371        break;
1372    }
1373
1374EXIT:
1375    FunctionOut();
1376
1377    return ret;
1378}
1379
1380OMX_ERRORTYPE Exynos_OMX_VideoDecodeSetConfig(
1381    OMX_HANDLETYPE hComponent,
1382    OMX_INDEXTYPE nIndex,
1383    OMX_PTR pComponentConfigStructure)
1384{
1385    OMX_ERRORTYPE           ret = OMX_ErrorNone;
1386    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1387    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1388
1389    FunctionIn();
1390
1391    if (hComponent == NULL) {
1392        ret = OMX_ErrorBadParameter;
1393        goto EXIT;
1394    }
1395    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1396    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1397    if (ret != OMX_ErrorNone) {
1398        goto EXIT;
1399    }
1400    if (pOMXComponent->pComponentPrivate == NULL) {
1401        ret = OMX_ErrorBadParameter;
1402        goto EXIT;
1403    }
1404    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1405    if (pComponentConfigStructure == NULL) {
1406        ret = OMX_ErrorBadParameter;
1407        goto EXIT;
1408    }
1409    if (pExynosComponent->currentState == OMX_StateInvalid) {
1410        ret = OMX_ErrorInvalidState;
1411        goto EXIT;
1412    }
1413
1414    switch (nIndex) {
1415    default:
1416        ret = Exynos_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure);
1417        break;
1418    }
1419
1420EXIT:
1421    FunctionOut();
1422
1423    return ret;
1424}
1425
1426OMX_ERRORTYPE Exynos_OMX_VideoDecodeGetExtensionIndex(
1427    OMX_IN OMX_HANDLETYPE  hComponent,
1428    OMX_IN OMX_STRING      cParameterName,
1429    OMX_OUT OMX_INDEXTYPE *pIndexType)
1430{
1431    OMX_ERRORTYPE           ret = OMX_ErrorNone;
1432    OMX_COMPONENTTYPE     *pOMXComponent = NULL;
1433    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1434
1435    FunctionIn();
1436
1437    if (hComponent == NULL) {
1438        ret = OMX_ErrorBadParameter;
1439        goto EXIT;
1440    }
1441    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1442    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1443    if (ret != OMX_ErrorNone) {
1444        goto EXIT;
1445    }
1446
1447    if (pOMXComponent->pComponentPrivate == NULL) {
1448        ret = OMX_ErrorBadParameter;
1449        goto EXIT;
1450    }
1451    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1452
1453    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1454        ret = OMX_ErrorBadParameter;
1455        goto EXIT;
1456    }
1457    if (pExynosComponent->currentState == OMX_StateInvalid) {
1458        ret = OMX_ErrorInvalidState;
1459        goto EXIT;
1460    }
1461
1462#ifdef USE_ANB
1463    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_ANB) == 0) {
1464        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamEnableAndroidBuffers;
1465        goto EXIT;
1466    }
1467    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_ANB) == 0) {
1468        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamGetAndroidNativeBuffer;
1469        goto EXIT;
1470    }
1471    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_USE_ANB) == 0) {
1472        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamUseAndroidNativeBuffer;
1473        goto EXIT;
1474    }
1475#endif
1476    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1477        *pIndexType = OMX_IndexParamEnableThumbnailMode;
1478        goto EXIT;
1479    }
1480#ifdef USE_STOREMETADATA
1481    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER) == 0) {
1482        *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamStoreMetaDataBuffer;
1483        goto EXIT;
1484    }
1485#endif
1486
1487    ret = Exynos_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType);
1488
1489EXIT:
1490    FunctionOut();
1491
1492    return ret;
1493}
1494
1495#ifdef USE_ANB
1496OMX_ERRORTYPE Exynos_Shared_ANBBufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_BASEPORT *pExynosPort, EXYNOS_OMX_PLANE nPlane)
1497{
1498    OMX_ERRORTYPE ret = OMX_ErrorNone;
1499    OMX_U32 width, height;
1500    ExynosVideoPlane planes[MAX_BUFFER_PLANE];
1501
1502    memset(planes, 0, sizeof(planes));
1503
1504    width = pExynosPort->portDefinition.format.video.nFrameWidth;
1505    height = pExynosPort->portDefinition.format.video.nFrameHeight;
1506
1507    if ((pExynosPort->bIsANBEnabled == OMX_TRUE) ||
1508        (pExynosPort->bStoreMetaData == OMX_TRUE)) {
1509        OMX_U32 stride;
1510        if ((pUseBuffer->bufferHeader != NULL) && (pUseBuffer->bufferHeader->pBuffer != NULL)) {
1511            if (pExynosPort->bIsANBEnabled == OMX_TRUE) {
1512                Exynos_OSAL_LockANB(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes);
1513            } else if (pExynosPort->bStoreMetaData == OMX_TRUE) {
1514                Exynos_OSAL_LockMetaData(pUseBuffer->bufferHeader->pBuffer, width, height, pExynosPort->portDefinition.format.video.eColorFormat, &stride, planes);
1515            }
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 if (pExynosPort->bStoreMetaData == OMX_TRUE) {
1575        Exynos_OSAL_UnlockMetaData(pUseBuffer->bufferHeader->pBuffer);
1576    } else {
1577        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1578        ret = OMX_ErrorBadParameter;
1579        goto EXIT;
1580    }
1581
1582EXIT:
1583    return ret;
1584}
1585#endif
1586