Home | History | Annotate | Download | only in common
      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_Baseport.c
     20  * @brief
     21  * @author     SeungBeom Kim (sbcrux.kim (at) samsung.com)
     22  *             HyeYeon Chung (hyeon.chung (at) samsung.com)
     23  * @version    2.0.0
     24  * @history
     25  *    2012.02.20 : Create
     26  */
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 #include <string.h>
     31 
     32 #include "Exynos_OMX_Macros.h"
     33 #include "Exynos_OSAL_Event.h"
     34 #include "Exynos_OSAL_Semaphore.h"
     35 #include "Exynos_OSAL_Mutex.h"
     36 
     37 #include "Exynos_OMX_Baseport.h"
     38 #include "Exynos_OMX_Basecomponent.h"
     39 
     40 #undef  EXYNOS_LOG_TAG
     41 #define EXYNOS_LOG_TAG    "EXYNOS_BASE_PORT"
     42 #define EXYNOS_LOG_OFF
     43 //#define EXYNOS_TRACE_ON
     44 #include "Exynos_OSAL_Log.h"
     45 
     46 
     47 OMX_ERRORTYPE Exynos_OMX_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
     48 {
     49     OMX_ERRORTYPE             ret = OMX_ErrorNone;
     50     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
     51     EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
     52     OMX_U32                   i = 0;
     53 
     54     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
     55     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
     56         if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
     57             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
     58             break;
     59         }
     60     }
     61 
     62     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
     63     pExynosComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
     64 
     65     return ret;
     66 }
     67 
     68 OMX_ERRORTYPE Exynos_OMX_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent, OMX_BUFFERHEADERTYPE* bufferHeader)
     69 {
     70     OMX_ERRORTYPE             ret = OMX_ErrorNone;
     71     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
     72     EXYNOS_OMX_BASEPORT      *pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
     73     OMX_U32                   i = 0;
     74 
     75     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
     76     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
     77         if (bufferHeader == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
     78             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_FALSE;
     79             break;
     80         }
     81     }
     82 
     83     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
     84     pExynosComponent->pCallbacks->FillBufferDone(pOMXComponent, pExynosComponent->callbackData, bufferHeader);
     85 
     86     return ret;
     87 }
     88 
     89 OMX_ERRORTYPE Exynos_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex, OMX_BOOL bEvent)
     90 {
     91     OMX_ERRORTYPE             ret = OMX_ErrorNone;
     92     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
     93     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
     94     OMX_S32                   portIndex = 0;
     95     EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
     96     OMX_U32                   i = 0, cnt = 0;
     97 
     98     FunctionIn();
     99 
    100     if (pOMXComponent == NULL) {
    101         ret = OMX_ErrorBadParameter;
    102         goto EXIT;
    103     }
    104     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    105     if (ret != OMX_ErrorNone) {
    106         goto EXIT;
    107     }
    108 
    109     if (pOMXComponent->pComponentPrivate == NULL) {
    110         ret = OMX_ErrorBadParameter;
    111         goto EXIT;
    112     }
    113     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    114 
    115     cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
    116 
    117     for (i = 0; i < cnt; i++) {
    118         if (nPortIndex == ALL_PORT_INDEX)
    119             portIndex = i;
    120         else
    121             portIndex = nPortIndex;
    122 
    123         pExynosComponent->exynos_BufferFlush(pOMXComponent, portIndex, bEvent);
    124     }
    125 
    126 EXIT:
    127     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
    128         Exynos_OSAL_Log(EXYNOS_LOG_ERROR,"%s : %d", __FUNCTION__, __LINE__);
    129         pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
    130                         pExynosComponent->callbackData,
    131                         OMX_EventError,
    132                         ret, 0, NULL);
    133     }
    134 
    135     FunctionOut();
    136 
    137     return ret;
    138 }
    139 
    140 OMX_ERRORTYPE Exynos_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
    141 {
    142     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    143     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    144     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    145     OMX_U32                i = 0, cnt = 0;
    146 
    147     FunctionIn();
    148 
    149     pExynosPort = &pExynosComponent->pExynosPort[portIndex];
    150 
    151     if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
    152         Exynos_OSAL_SemaphoreWait(pExynosPort->loadedResource);
    153         pExynosPort->portDefinition.bPopulated = OMX_TRUE;
    154     }
    155     pExynosPort->exceptionFlag = GENERAL_STATE;
    156     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
    157 
    158     ret = OMX_ErrorNone;
    159 
    160 EXIT:
    161     FunctionOut();
    162 
    163     return ret;
    164 }
    165 
    166 OMX_ERRORTYPE Exynos_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex)
    167 {
    168     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    169     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    170     OMX_S32                portIndex = 0;
    171     OMX_U32                i = 0, cnt = 0;
    172 
    173     FunctionIn();
    174 
    175     if (pOMXComponent == NULL) {
    176         ret = OMX_ErrorBadParameter;
    177         goto EXIT;
    178     }
    179     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    180     if (ret != OMX_ErrorNone) {
    181         goto EXIT;
    182     }
    183 
    184     if (pOMXComponent->pComponentPrivate == NULL) {
    185         ret = OMX_ErrorBadParameter;
    186         goto EXIT;
    187     }
    188     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    189 
    190     cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1;
    191 
    192     for (i = 0; i < cnt; i++) {
    193         if (nPortIndex == ALL_PORT_INDEX)
    194             portIndex = i;
    195         else
    196             portIndex = nPortIndex;
    197 
    198         ret = Exynos_OMX_EnablePort(pOMXComponent, portIndex);
    199         if (ret == OMX_ErrorNone) {
    200             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
    201                             pExynosComponent->callbackData,
    202                             OMX_EventCmdComplete,
    203                             OMX_CommandPortEnable, portIndex, NULL);
    204         }
    205     }
    206 
    207 EXIT:
    208     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
    209             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
    210                             pExynosComponent->callbackData,
    211                             OMX_EventError,
    212                             ret, 0, NULL);
    213         }
    214 
    215     FunctionOut();
    216 
    217     return ret;
    218 }
    219 
    220 OMX_ERRORTYPE Exynos_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex)
    221 {
    222     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    223     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    224     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    225     OMX_U32                i = 0, elemNum = 0;
    226     EXYNOS_OMX_MESSAGE       *message;
    227 
    228     FunctionIn();
    229 
    230     pExynosPort = &pExynosComponent->pExynosPort[portIndex];
    231 
    232     if (!CHECK_PORT_ENABLED(pExynosPort)) {
    233         ret = OMX_ErrorNone;
    234         goto EXIT;
    235     }
    236 
    237     if (pExynosComponent->currentState != OMX_StateLoaded) {
    238         if (CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)) {
    239             while (Exynos_OSAL_GetElemNum(&pExynosPort->bufferQ) > 0) {
    240                 message = (EXYNOS_OMX_MESSAGE*)Exynos_OSAL_Dequeue(&pExynosPort->bufferQ);
    241                 Exynos_OSAL_Free(message);
    242             }
    243         }
    244         pExynosPort->portDefinition.bPopulated = OMX_FALSE;
    245         Exynos_OSAL_SemaphoreWait(pExynosPort->unloadedResource);
    246     }
    247     pExynosPort->portDefinition.bEnabled = OMX_FALSE;
    248     ret = OMX_ErrorNone;
    249 
    250 EXIT:
    251     FunctionOut();
    252 
    253     return ret;
    254 }
    255 
    256 OMX_ERRORTYPE Exynos_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex)
    257 {
    258     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    259     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    260     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    261     OMX_S32                portIndex = 0;
    262     OMX_U32                i = 0, cnt = 0;
    263     EXYNOS_OMX_DATABUFFER    *flushPortBuffer[2] = {NULL, NULL};
    264 
    265     FunctionIn();
    266 
    267     if (pOMXComponent == NULL) {
    268         ret = OMX_ErrorBadParameter;
    269         goto EXIT;
    270     }
    271     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    272     if (ret != OMX_ErrorNone) {
    273         goto EXIT;
    274     }
    275 
    276     if (pOMXComponent->pComponentPrivate == NULL) {
    277         ret = OMX_ErrorBadParameter;
    278         goto EXIT;
    279     }
    280     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    281 
    282     cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;
    283 
    284     /* port flush*/
    285     for(i = 0; i < cnt; i++) {
    286         if (nPortIndex == ALL_PORT_INDEX)
    287             portIndex = i;
    288         else
    289             portIndex = nPortIndex;
    290 
    291         Exynos_OMX_BufferFlushProcess(pOMXComponent, portIndex, OMX_FALSE);
    292     }
    293 
    294     for(i = 0; i < cnt; i++) {
    295         if (nPortIndex == ALL_PORT_INDEX)
    296             portIndex = i;
    297         else
    298             portIndex = nPortIndex;
    299 
    300         ret = Exynos_OMX_DisablePort(pOMXComponent, portIndex);
    301         pExynosComponent->pExynosPort[portIndex].bIsPortDisabled = OMX_FALSE;
    302         if (ret == OMX_ErrorNone) {
    303             pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
    304                             pExynosComponent->callbackData,
    305                             OMX_EventCmdComplete,
    306                             OMX_CommandPortDisable, portIndex, NULL);
    307         }
    308     }
    309 
    310 EXIT:
    311     if ((ret != OMX_ErrorNone) && (pOMXComponent != NULL) && (pExynosComponent != NULL)) {
    312         pExynosComponent->pCallbacks->EventHandler(pOMXComponent,
    313                         pExynosComponent->callbackData,
    314                         OMX_EventError,
    315                         ret, 0, NULL);
    316     }
    317 
    318     FunctionOut();
    319 
    320     return ret;
    321 }
    322 
    323 OMX_ERRORTYPE Exynos_OMX_EmptyThisBuffer(
    324     OMX_IN OMX_HANDLETYPE        hComponent,
    325     OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
    326 {
    327     OMX_ERRORTYPE           ret = OMX_ErrorNone;
    328     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    329     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    330     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    331     OMX_BOOL               findBuffer = OMX_FALSE;
    332     EXYNOS_OMX_MESSAGE       *message;
    333     OMX_U32                i = 0;
    334 
    335     FunctionIn();
    336 
    337     if (hComponent == NULL) {
    338         ret = OMX_ErrorBadParameter;
    339         goto EXIT;
    340     }
    341     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    342     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    343     if (ret != OMX_ErrorNone) {
    344         goto EXIT;
    345     }
    346 
    347     if (pOMXComponent->pComponentPrivate == NULL) {
    348         ret = OMX_ErrorBadParameter;
    349         goto EXIT;
    350     }
    351     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    352     if (pExynosComponent->currentState == OMX_StateInvalid) {
    353         ret = OMX_ErrorInvalidState;
    354         goto EXIT;
    355     }
    356 
    357     if (pBuffer == NULL) {
    358         ret = OMX_ErrorBadParameter;
    359         goto EXIT;
    360     }
    361     if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) {
    362         ret = OMX_ErrorBadPortIndex;
    363         goto EXIT;
    364     }
    365 
    366     ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    367     if (ret != OMX_ErrorNone) {
    368         goto EXIT;
    369     }
    370 
    371     if ((pExynosComponent->currentState != OMX_StateIdle) &&
    372         (pExynosComponent->currentState != OMX_StateExecuting) &&
    373         (pExynosComponent->currentState != OMX_StatePause)) {
    374         ret = OMX_ErrorIncorrectStateOperation;
    375         goto EXIT;
    376     }
    377 
    378     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
    379     if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
    380         ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) &&
    381         (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
    382         ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
    383         (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
    384         ret = OMX_ErrorIncorrectStateOperation;
    385         goto EXIT;
    386     }
    387 
    388     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
    389     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
    390         if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
    391             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
    392             findBuffer = OMX_TRUE;
    393             break;
    394         }
    395     }
    396 
    397     if (findBuffer == OMX_FALSE) {
    398         ret = OMX_ErrorBadParameter;
    399         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    400         goto EXIT;
    401     }
    402 
    403     message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
    404     if (message == NULL) {
    405         ret = OMX_ErrorInsufficientResources;
    406         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    407         goto EXIT;
    408     }
    409     message->messageType = EXYNOS_OMX_CommandEmptyBuffer;
    410     message->messageParam = (OMX_U32) i;
    411     message->pCmdData = (OMX_PTR)pBuffer;
    412 
    413     ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
    414     if (ret != 0) {
    415         ret = OMX_ErrorUndefined;
    416         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    417         goto EXIT;
    418     }
    419     ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
    420     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    421 
    422 EXIT:
    423     FunctionOut();
    424 
    425     return ret;
    426 }
    427 
    428 OMX_ERRORTYPE Exynos_OMX_FillThisBuffer(
    429     OMX_IN OMX_HANDLETYPE        hComponent,
    430     OMX_IN OMX_BUFFERHEADERTYPE *pBuffer)
    431 {
    432     OMX_ERRORTYPE           ret = OMX_ErrorNone;
    433     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    434     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    435     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    436     OMX_BOOL               findBuffer = OMX_FALSE;
    437     EXYNOS_OMX_MESSAGE       *message;
    438     OMX_U32                i = 0;
    439 
    440     FunctionIn();
    441 
    442     if (hComponent == NULL) {
    443         ret = OMX_ErrorBadParameter;
    444         goto EXIT;
    445     }
    446     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    447     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    448     if (ret != OMX_ErrorNone) {
    449         goto EXIT;
    450     }
    451 
    452     if (pOMXComponent->pComponentPrivate == NULL) {
    453         ret = OMX_ErrorBadParameter;
    454         goto EXIT;
    455     }
    456     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    457     if (pExynosComponent->currentState == OMX_StateInvalid) {
    458         ret = OMX_ErrorInvalidState;
    459         goto EXIT;
    460     }
    461 
    462     if (pBuffer == NULL) {
    463         ret = OMX_ErrorBadParameter;
    464         goto EXIT;
    465     }
    466     if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) {
    467         ret = OMX_ErrorBadPortIndex;
    468         goto EXIT;
    469     }
    470 
    471     ret = Exynos_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
    472     if (ret != OMX_ErrorNone) {
    473         goto EXIT;
    474     }
    475 
    476     if ((pExynosComponent->currentState != OMX_StateIdle) &&
    477         (pExynosComponent->currentState != OMX_StateExecuting) &&
    478         (pExynosComponent->currentState != OMX_StatePause)) {
    479         ret = OMX_ErrorIncorrectStateOperation;
    480         goto EXIT;
    481     }
    482 
    483     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
    484     if ((!CHECK_PORT_ENABLED(pExynosPort)) ||
    485         ((CHECK_PORT_BEING_FLUSHED(pExynosPort) || CHECK_PORT_BEING_DISABLED(pExynosPort)) &&
    486         (!CHECK_PORT_TUNNELED(pExynosPort) || !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort))) ||
    487         ((pExynosComponent->transientState == EXYNOS_OMX_TransStateExecutingToIdle) &&
    488         (CHECK_PORT_TUNNELED(pExynosPort) && !CHECK_PORT_BUFFER_SUPPLIER(pExynosPort)))) {
    489         ret = OMX_ErrorIncorrectStateOperation;
    490         goto EXIT;
    491     }
    492 
    493     Exynos_OSAL_MutexLock(pExynosPort->hPortMutex);
    494     for (i = 0; i < pExynosPort->portDefinition.nBufferCountActual; i++) {
    495         if (pBuffer == pExynosPort->extendBufferHeader[i].OMXBufferHeader) {
    496             pExynosPort->extendBufferHeader[i].bBufferInOMX = OMX_TRUE;
    497             findBuffer = OMX_TRUE;
    498             break;
    499         }
    500     }
    501 
    502     if (findBuffer == OMX_FALSE) {
    503         ret = OMX_ErrorBadParameter;
    504         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    505         goto EXIT;
    506     }
    507 
    508     message = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_MESSAGE));
    509     if (message == NULL) {
    510         ret = OMX_ErrorInsufficientResources;
    511         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    512         goto EXIT;
    513     }
    514     message->messageType = EXYNOS_OMX_CommandFillBuffer;
    515     message->messageParam = (OMX_U32) i;
    516     message->pCmdData = (OMX_PTR)pBuffer;
    517 
    518     ret = Exynos_OSAL_Queue(&pExynosPort->bufferQ, (void *)message);
    519     if (ret != 0) {
    520         ret = OMX_ErrorUndefined;
    521         Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    522         goto EXIT;
    523     }
    524 
    525     ret = Exynos_OSAL_SemaphorePost(pExynosPort->bufferSemID);
    526     Exynos_OSAL_MutexUnlock(pExynosPort->hPortMutex);
    527 
    528 EXIT:
    529     FunctionOut();
    530 
    531     return ret;
    532 }
    533 
    534 OMX_ERRORTYPE Exynos_OMX_Port_Constructor(OMX_HANDLETYPE hComponent)
    535 {
    536     OMX_ERRORTYPE          ret = OMX_ErrorNone;
    537     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
    538     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    539     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    540     EXYNOS_OMX_BASEPORT      *pExynosInputPort = NULL;
    541     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = NULL;
    542     int i = 0;
    543 
    544     FunctionIn();
    545 
    546     if (hComponent == NULL) {
    547         ret = OMX_ErrorBadParameter;
    548         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
    549         goto EXIT;
    550     }
    551     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    552     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    553     if (ret != OMX_ErrorNone) {
    554         goto EXIT;
    555     }
    556 
    557     if (pOMXComponent->pComponentPrivate == NULL) {
    558         ret = OMX_ErrorBadParameter;
    559         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
    560         goto EXIT;
    561     }
    562     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    563 
    564     INIT_SET_SIZE_VERSION(&pExynosComponent->portParam, OMX_PORT_PARAM_TYPE);
    565     pExynosComponent->portParam.nPorts = ALL_PORT_NUM;
    566     pExynosComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX;
    567 
    568     pExynosPort = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
    569     if (pExynosPort == NULL) {
    570         ret = OMX_ErrorInsufficientResources;
    571         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
    572         goto EXIT;
    573     }
    574     Exynos_OSAL_Memset(pExynosPort, 0, sizeof(EXYNOS_OMX_BASEPORT) * ALL_PORT_NUM);
    575     pExynosComponent->pExynosPort = pExynosPort;
    576 
    577     /* Input Port */
    578     pExynosInputPort = &pExynosPort[INPUT_PORT_INDEX];
    579 
    580     Exynos_OSAL_QueueCreate(&pExynosInputPort->bufferQ, MAX_QUEUE_ELEMENTS);
    581 
    582     pExynosInputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    583     if (pExynosInputPort->extendBufferHeader == NULL) {
    584         Exynos_OSAL_Free(pExynosPort);
    585         pExynosPort = NULL;
    586         ret = OMX_ErrorInsufficientResources;
    587         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
    588         goto EXIT;
    589     }
    590     Exynos_OSAL_Memset(pExynosInputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    591 
    592     pExynosInputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
    593     if (pExynosInputPort->bufferStateAllocate == NULL) {
    594         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    595         pExynosInputPort->extendBufferHeader = NULL;
    596         Exynos_OSAL_Free(pExynosPort);
    597         pExynosPort = NULL;
    598         ret = OMX_ErrorInsufficientResources;
    599         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
    600         goto EXIT;
    601     }
    602     Exynos_OSAL_Memset(pExynosInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
    603 
    604     pExynosInputPort->bufferSemID = NULL;
    605     pExynosInputPort->assignedBufferNum = 0;
    606     pExynosInputPort->portState = OMX_StateMax;
    607     pExynosInputPort->bIsPortFlushed = OMX_FALSE;
    608     pExynosInputPort->bIsPortDisabled = OMX_FALSE;
    609     pExynosInputPort->tunneledComponent = NULL;
    610     pExynosInputPort->tunneledPort = 0;
    611     pExynosInputPort->tunnelBufferNum = 0;
    612     pExynosInputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
    613     pExynosInputPort->tunnelFlags = 0;
    614     ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->loadedResource);
    615     if (ret != OMX_ErrorNone) {
    616         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    617         pExynosInputPort->bufferStateAllocate = NULL;
    618         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    619         pExynosInputPort->extendBufferHeader = NULL;
    620         Exynos_OSAL_Free(pExynosPort);
    621         pExynosPort = NULL;
    622         goto EXIT;
    623     }
    624     ret = Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->unloadedResource);
    625     if (ret != OMX_ErrorNone) {
    626         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
    627         pExynosInputPort->loadedResource = NULL;
    628         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    629         pExynosInputPort->bufferStateAllocate = NULL;
    630         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    631         pExynosInputPort->extendBufferHeader = NULL;
    632         Exynos_OSAL_Free(pExynosPort);
    633         pExynosPort = NULL;
    634         goto EXIT;
    635     }
    636 
    637     INIT_SET_SIZE_VERSION(&pExynosInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
    638     pExynosInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX;
    639     pExynosInputPort->portDefinition.eDir = OMX_DirInput;
    640     pExynosInputPort->portDefinition.nBufferCountActual = 0;
    641     pExynosInputPort->portDefinition.nBufferCountMin = 0;
    642     pExynosInputPort->portDefinition.nBufferSize = 0;
    643     pExynosInputPort->portDefinition.bEnabled = OMX_FALSE;
    644     pExynosInputPort->portDefinition.bPopulated = OMX_FALSE;
    645     pExynosInputPort->portDefinition.eDomain = OMX_PortDomainMax;
    646     pExynosInputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
    647     pExynosInputPort->portDefinition.nBufferAlignment = 0;
    648     pExynosInputPort->markType.hMarkTargetComponent = NULL;
    649     pExynosInputPort->markType.pMarkData = NULL;
    650     pExynosInputPort->exceptionFlag = GENERAL_STATE;
    651 
    652     /* Output Port */
    653     pExynosOutputPort = &pExynosPort[OUTPUT_PORT_INDEX];
    654 
    655     Exynos_OSAL_QueueCreate(&pExynosOutputPort->bufferQ, MAX_QUEUE_ELEMENTS); /* For in case of "Output Buffer Share", MAX ELEMENTS(DPB + EDPB) */
    656 
    657     pExynosOutputPort->extendBufferHeader = Exynos_OSAL_Malloc(sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    658     if (pExynosOutputPort->extendBufferHeader == NULL) {
    659         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
    660         pExynosInputPort->unloadedResource = NULL;
    661         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
    662         pExynosInputPort->loadedResource = NULL;
    663         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    664         pExynosInputPort->bufferStateAllocate = NULL;
    665         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    666         pExynosInputPort->extendBufferHeader = NULL;
    667         Exynos_OSAL_Free(pExynosPort);
    668         pExynosPort = NULL;
    669         ret = OMX_ErrorInsufficientResources;
    670         goto EXIT;
    671     }
    672     Exynos_OSAL_Memset(pExynosOutputPort->extendBufferHeader, 0, sizeof(EXYNOS_OMX_BUFFERHEADERTYPE) * MAX_BUFFER_NUM);
    673 
    674     pExynosOutputPort->bufferStateAllocate = Exynos_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM);
    675     if (pExynosOutputPort->bufferStateAllocate == NULL) {
    676         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
    677         pExynosOutputPort->extendBufferHeader = NULL;
    678 
    679         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
    680         pExynosInputPort->unloadedResource = NULL;
    681         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
    682         pExynosInputPort->loadedResource = NULL;
    683         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    684         pExynosInputPort->bufferStateAllocate = NULL;
    685         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    686         pExynosInputPort->extendBufferHeader = NULL;
    687         Exynos_OSAL_Free(pExynosPort);
    688         pExynosPort = NULL;
    689         ret = OMX_ErrorInsufficientResources;
    690         goto EXIT;
    691     }
    692     Exynos_OSAL_Memset(pExynosOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM);
    693 
    694     pExynosOutputPort->bufferSemID = NULL;
    695     pExynosOutputPort->assignedBufferNum = 0;
    696     pExynosOutputPort->portState = OMX_StateMax;
    697     pExynosOutputPort->bIsPortFlushed = OMX_FALSE;
    698     pExynosOutputPort->bIsPortDisabled = OMX_FALSE;
    699     pExynosOutputPort->tunneledComponent = NULL;
    700     pExynosOutputPort->tunneledPort = 0;
    701     pExynosOutputPort->tunnelBufferNum = 0;
    702     pExynosOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified;
    703     pExynosOutputPort->tunnelFlags = 0;
    704     ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->loadedResource);
    705     if (ret != OMX_ErrorNone) {
    706         Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
    707         pExynosOutputPort->bufferStateAllocate = NULL;
    708         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
    709         pExynosOutputPort->extendBufferHeader = NULL;
    710 
    711         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
    712         pExynosInputPort->unloadedResource = NULL;
    713         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
    714         pExynosInputPort->loadedResource = NULL;
    715         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    716         pExynosInputPort->bufferStateAllocate = NULL;
    717         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    718         pExynosInputPort->extendBufferHeader = NULL;
    719         Exynos_OSAL_Free(pExynosPort);
    720         pExynosPort = NULL;
    721         goto EXIT;
    722     }
    723     ret = Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->unloadedResource);
    724     if (ret != OMX_ErrorNone) {
    725         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->loadedResource);
    726         pExynosOutputPort->loadedResource = NULL;
    727         Exynos_OSAL_Free(pExynosOutputPort->bufferStateAllocate);
    728         pExynosOutputPort->bufferStateAllocate = NULL;
    729         Exynos_OSAL_Free(pExynosOutputPort->extendBufferHeader);
    730         pExynosOutputPort->extendBufferHeader = NULL;
    731 
    732         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->unloadedResource);
    733         pExynosInputPort->unloadedResource = NULL;
    734         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->loadedResource);
    735         pExynosInputPort->loadedResource = NULL;
    736         Exynos_OSAL_Free(pExynosInputPort->bufferStateAllocate);
    737         pExynosInputPort->bufferStateAllocate = NULL;
    738         Exynos_OSAL_Free(pExynosInputPort->extendBufferHeader);
    739         pExynosInputPort->extendBufferHeader = NULL;
    740         Exynos_OSAL_Free(pExynosPort);
    741         pExynosPort = NULL;
    742         goto EXIT;
    743     }
    744 
    745     INIT_SET_SIZE_VERSION(&pExynosOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE);
    746     pExynosOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX;
    747     pExynosOutputPort->portDefinition.eDir = OMX_DirOutput;
    748     pExynosOutputPort->portDefinition.nBufferCountActual = 0;
    749     pExynosOutputPort->portDefinition.nBufferCountMin = 0;
    750     pExynosOutputPort->portDefinition.nBufferSize = 0;
    751     pExynosOutputPort->portDefinition.bEnabled = OMX_FALSE;
    752     pExynosOutputPort->portDefinition.bPopulated = OMX_FALSE;
    753     pExynosOutputPort->portDefinition.eDomain = OMX_PortDomainMax;
    754     pExynosOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE;
    755     pExynosOutputPort->portDefinition.nBufferAlignment = 0;
    756     pExynosOutputPort->markType.hMarkTargetComponent = NULL;
    757     pExynosOutputPort->markType.pMarkData = NULL;
    758     pExynosOutputPort->exceptionFlag = GENERAL_STATE;
    759 
    760     pExynosComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE;
    761     pExynosComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
    762     pExynosComponent->checkTimeStamp.startTimeStamp = 0;
    763     pExynosComponent->checkTimeStamp.nStartFlags = 0x0;
    764 
    765     pOMXComponent->EmptyThisBuffer = &Exynos_OMX_EmptyThisBuffer;
    766     pOMXComponent->FillThisBuffer  = &Exynos_OMX_FillThisBuffer;
    767 
    768     ret = OMX_ErrorNone;
    769 EXIT:
    770     FunctionOut();
    771 
    772     return ret;
    773 }
    774 
    775 OMX_ERRORTYPE Exynos_OMX_Port_Destructor(OMX_HANDLETYPE hComponent)
    776 {
    777     OMX_ERRORTYPE             ret = OMX_ErrorNone;
    778     OMX_COMPONENTTYPE        *pOMXComponent = NULL;
    779     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
    780     EXYNOS_OMX_BASEPORT      *pExynosPort = NULL;
    781 
    782     OMX_S32 countValue = 0;
    783     int i = 0;
    784 
    785     FunctionIn();
    786 
    787     if (hComponent == NULL) {
    788         ret = OMX_ErrorBadParameter;
    789         goto EXIT;
    790     }
    791     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
    792     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    793     if (ret != OMX_ErrorNone) {
    794         goto EXIT;
    795     }
    796     if (pOMXComponent->pComponentPrivate == NULL) {
    797         ret = OMX_ErrorBadParameter;
    798         goto EXIT;
    799     }
    800     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    801 
    802     if (pExynosComponent->transientState == EXYNOS_OMX_TransStateLoadedToIdle) {
    803         pExynosComponent->abendState = OMX_TRUE;
    804         for (i = 0; i < ALL_PORT_NUM; i++) {
    805             pExynosPort = &pExynosComponent->pExynosPort[i];
    806             Exynos_OSAL_SemaphorePost(pExynosPort->loadedResource);
    807         }
    808         Exynos_OSAL_SignalWait(pExynosComponent->abendStateEvent, DEF_MAX_WAIT_TIME);
    809         Exynos_OSAL_SignalReset(pExynosComponent->abendStateEvent);
    810     }
    811 
    812     for (i = 0; i < ALL_PORT_NUM; i++) {
    813         pExynosPort = &pExynosComponent->pExynosPort[i];
    814 
    815         Exynos_OSAL_SemaphoreTerminate(pExynosPort->loadedResource);
    816         pExynosPort->loadedResource = NULL;
    817         Exynos_OSAL_SemaphoreTerminate(pExynosPort->unloadedResource);
    818         pExynosPort->unloadedResource = NULL;
    819         Exynos_OSAL_Free(pExynosPort->bufferStateAllocate);
    820         pExynosPort->bufferStateAllocate = NULL;
    821         Exynos_OSAL_Free(pExynosPort->extendBufferHeader);
    822         pExynosPort->extendBufferHeader = NULL;
    823 
    824         Exynos_OSAL_QueueTerminate(&pExynosPort->bufferQ);
    825     }
    826     Exynos_OSAL_Free(pExynosComponent->pExynosPort);
    827     pExynosComponent->pExynosPort = NULL;
    828     ret = OMX_ErrorNone;
    829 EXIT:
    830     FunctionOut();
    831 
    832     return ret;
    833 }
    834 
    835 OMX_ERRORTYPE Exynos_ResetDataBuffer(EXYNOS_OMX_DATABUFFER *pDataBuffer)
    836 {
    837     OMX_ERRORTYPE ret = OMX_ErrorNone;
    838 
    839     if (pDataBuffer == NULL) {
    840         ret = OMX_ErrorBadParameter;
    841         goto EXIT;
    842     }
    843 
    844     pDataBuffer->dataValid     = OMX_FALSE;
    845     pDataBuffer->dataLen       = 0;
    846     pDataBuffer->remainDataLen = 0;
    847     pDataBuffer->usedDataLen   = 0;
    848     pDataBuffer->bufferHeader  = NULL;
    849     pDataBuffer->nFlags        = 0;
    850     pDataBuffer->timeStamp     = 0;
    851     pDataBuffer->pPrivate      = NULL;
    852 
    853 EXIT:
    854     return ret;
    855 }
    856 
    857 OMX_ERRORTYPE Exynos_ResetCodecData(EXYNOS_OMX_DATA *pData)
    858 {
    859     OMX_ERRORTYPE ret = OMX_ErrorNone;
    860 
    861     if (pData == NULL) {
    862         ret = OMX_ErrorBadParameter;
    863         goto EXIT;
    864     }
    865 
    866     pData->dataLen       = 0;
    867     pData->usedDataLen   = 0;
    868     pData->remainDataLen = 0;
    869     pData->nFlags        = 0;
    870     pData->timeStamp     = 0;
    871     pData->pPrivate      = NULL;
    872     pData->bufferHeader  = NULL;
    873 
    874 EXIT:
    875     return ret;
    876 }
    877 
    878 OMX_ERRORTYPE Exynos_Shared_BufferToData(EXYNOS_OMX_DATABUFFER *pUseBuffer, EXYNOS_OMX_DATA *pData, EXYNOS_OMX_PLANE nPlane)
    879 {
    880     OMX_ERRORTYPE ret = OMX_ErrorNone;
    881 
    882     if (nPlane == ONE_PLANE) {
    883         /* Case of Shared Buffer, Only support singlePlaneBuffer */
    884         pData->buffer.singlePlaneBuffer.dataBuffer = pUseBuffer->bufferHeader->pBuffer;
    885     } else {
    886         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support plane");
    887         ret = OMX_ErrorNotImplemented;
    888         goto EXIT;
    889     }
    890 
    891     pData->allocSize     = pUseBuffer->allocSize;
    892     pData->dataLen       = pUseBuffer->dataLen;
    893     pData->usedDataLen   = pUseBuffer->usedDataLen;
    894     pData->remainDataLen = pUseBuffer->remainDataLen;
    895     pData->timeStamp     = pUseBuffer->timeStamp;
    896     pData->nFlags        = pUseBuffer->nFlags;
    897     pData->pPrivate      = pUseBuffer->pPrivate;
    898     pData->bufferHeader  = pUseBuffer->bufferHeader;
    899 
    900 EXIT:
    901     return ret;
    902 }
    903 
    904 OMX_ERRORTYPE Exynos_Shared_DataToBuffer(EXYNOS_OMX_DATA *pData, EXYNOS_OMX_DATABUFFER *pUseBuffer)
    905 {
    906     OMX_ERRORTYPE ret = OMX_ErrorNone;
    907 
    908     pUseBuffer->bufferHeader          = pData->bufferHeader;
    909     pUseBuffer->allocSize             = pData->allocSize;
    910     pUseBuffer->dataLen               = pData->dataLen;
    911     pUseBuffer->usedDataLen           = pData->usedDataLen;
    912     pUseBuffer->remainDataLen         = pData->remainDataLen;
    913     pUseBuffer->timeStamp             = pData->timeStamp;
    914     pUseBuffer->nFlags                = pData->nFlags;
    915     pUseBuffer->pPrivate              = pData->pPrivate;
    916 
    917     return ret;
    918 }
    919