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