int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data)
{
    SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle;
    if (queue == NULL)
        return -1;

    SEC_OSAL_MutexLock(queue->qMutex);

    if ((queue->last->data != NULL) || (queue->numElem >= MAX_QUEUE_ELEMENTS)) {
        SEC_OSAL_MutexUnlock(queue->qMutex);
        return -1;
    }
    queue->last->data = data;
    queue->last = queue->last->qNext;
    queue->numElem++;

    SEC_OSAL_MutexUnlock(queue->qMutex);
    return 0;
}
int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum)
{
    SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle;
    if (queue == NULL)
        return -1;

    SEC_OSAL_MutexLock(queue->qMutex);
    queue->numElem = ElemNum; 
    SEC_OSAL_MutexUnlock(queue->qMutex);
    return ElemNum;
}
int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle)
{
    int ElemNum = 0;
    SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle;
    if (queue == NULL)
        return -1;

    SEC_OSAL_MutexLock(queue->qMutex);
    ElemNum = queue->numElem;
    SEC_OSAL_MutexUnlock(queue->qMutex);
    return ElemNum;
}
void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle)
{
    void *data = NULL;
    SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle;
    if (queue == NULL)
        return NULL;

    SEC_OSAL_MutexLock(queue->qMutex);

    if ((queue->first->data == NULL) || (queue->numElem <= 0)) {
        SEC_OSAL_MutexUnlock(queue->qMutex);
        return NULL;
    }
    data = queue->first->data;
    queue->first->data = NULL;
    queue->first = queue->first->qNext;
    queue->numElem--;

    SEC_OSAL_MutexUnlock(queue->qMutex);
    return data;
}
OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms)
{
    SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle;
    OMX_ERRORTYPE         ret = OMX_ErrorNone;
    struct timespec       timeout;
    struct timeval        now;
    int                   funcret = 0;
    OMX_U32               tv_us;

    FunctionIn();

    if (!event) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    gettimeofday(&now, NULL);

    tv_us = now.tv_usec + ms * 1000;
    timeout.tv_sec = now.tv_sec + tv_us / 1000000;
    timeout.tv_nsec = (tv_us % 1000000) * 1000;

    ret = SEC_OSAL_MutexLock(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    if (ms == 0) {
        if (!event->signal)
            ret = OMX_ErrorTimeout;
    } else if (ms == DEF_MAX_WAIT_TIME) {
        while (!event->signal)
            pthread_cond_wait(&event->condition, (pthread_mutex_t *)(event->mutex));
        ret = OMX_ErrorNone;
    } else {
        while (!event->signal) {
            funcret = pthread_cond_timedwait(&event->condition, (pthread_mutex_t *)(event->mutex), &timeout);
            if ((!event->signal) && (funcret == ETIMEDOUT)) {
                ret = OMX_ErrorTimeout;
                break;
            }
        }
    }

    SEC_OSAL_MutexUnlock(event->mutex);

EXIT:
    FunctionOut();

    return ret;
}
OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle)
{
    SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle;
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (!event) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    ret = SEC_OSAL_MutexLock(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    if (pthread_cond_destroy(&event->condition)) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    ret = SEC_OSAL_MutexUnlock(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    ret = SEC_OSAL_MutexTerminate(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorUndefined;
        goto EXIT;
    }

    SEC_OSAL_Free(event);

EXIT:
    return ret;
}
OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle)
{
    SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle;
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (!event) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    ret = SEC_OSAL_MutexLock(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    event->signal = OMX_FALSE;

    SEC_OSAL_MutexUnlock(event->mutex);

EXIT:
    return ret;
}
OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle)
{
    SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle;
    OMX_ERRORTYPE ret = OMX_ErrorNone;

    if (!event) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    ret = SEC_OSAL_MutexLock(event->mutex);
    if (ret != OMX_ErrorNone) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }

    event->signal = OMX_TRUE;
    pthread_cond_signal(&event->condition);

    SEC_OSAL_MutexUnlock(event->mutex);

EXIT:
    return ret;
}
OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex)
{
    OMX_ERRORTYPE          ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT *pSECComponent = NULL;
    OMX_S32                portIndex = 0;
    OMX_U32                i = 0, cnt = 0;
    SEC_OMX_DATABUFFER      *flushBuffer = NULL;

    FunctionIn();

    if (pOMXComponent == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
    if (ret != OMX_ErrorNone) {
        goto EXIT;
    }

    if (pOMXComponent->pComponentPrivate == NULL) {
        ret = OMX_ErrorBadParameter;
        goto EXIT;
    }
    pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;

    cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1;

    /* port flush*/
    for(i = 0; i < cnt; i++) {
        if (nPortIndex == ALL_PORT_INDEX)
            portIndex = i;
        else
            portIndex = nPortIndex;

        pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE;

        flushBuffer = &pSECComponent->secDataBuffer[portIndex];

        SEC_OSAL_MutexLock(flushBuffer->bufferMutex);
        ret = SEC_OMX_FlushPort(pOMXComponent, portIndex);
        SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex);

        pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE;

        if (portIndex == INPUT_PORT_INDEX) {
            pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE;
            pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE;
            SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
            SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
            pSECComponent->getAllDelayBuffer = OMX_FALSE;
            pSECComponent->bSaveFlagEOS = OMX_FALSE;
            pSECComponent->reInputData = OMX_FALSE;
        } else if (portIndex == OUTPUT_PORT_INDEX) {
            pSECComponent->remainOutputData = OMX_FALSE;
        }
    }

    for(i = 0; i < cnt; i++) {
        if (nPortIndex == ALL_PORT_INDEX)
            portIndex = i;
        else
            portIndex = nPortIndex;

        ret = SEC_OMX_DisablePort(pOMXComponent, portIndex);
        pSECComponent->pSECPort[portIndex].bIsPortDisabled = OMX_FALSE;
        if (ret == OMX_ErrorNone) {
            pSECComponent->pCallbacks->EventHandler(pOMXComponent,
                            pSECComponent->callbackData,
                            OMX_EventCmdComplete,
                            OMX_CommandPortDisable, portIndex, NULL);
        }
    }

EXIT:
    if (ret != OMX_ErrorNone) {
        pSECComponent->pCallbacks->EventHandler(pOMXComponent,
                        pSECComponent->callbackData,
                        OMX_EventError,
                        ret, 0, NULL);
    }

    FunctionOut();

    return ret;
}