#include <stdio.h>
#include <stdlib.h>
#include "omxcore.h"
#include "omx_base_audio_port.h"
#include "omx_dtsxdec_component.h"
#include "OMX_Audio.h"
#include "core_struct_version.h"
#include "omx_mtk_extend.h"
#include "sched.h"
#include <dlfcn.h>
#include <stdint.h>
#include "sndbar_dbg.h"

#define LOGE(_stmt...) \
    do{ \
        if(0) \
        { \
            printf("[omx_dtsxdec_component][%s@L%d]", __FUNCTION__, __LINE__);   \
            printf(_stmt); \
        } \
      }   \
    while(0)

OMX_U8* pOMXProcessTmpBuf = NULL;
static int count = 0;
static long int total_len = 0;
OMX_AUDIO_PARAM_PCMMODETYPE gOutputPcmMode;

/* sndbar log variable */
static int sndbar_dbg_cfg_log_level = SNDBAR_LOG_INFO;
static int sndbar_dbg_cfg_latency_log_level = SNDBAR_LOG_OFF;
static int sndbar_dbg_cfg_latency_log_num = 300;

static int sndbar_dbg_cfg_dump_dtsxdec_in = 0;
static struct sndbar_dbg_dump_t sndbar_dump_dtsxdec_in;

static int sndbar_dbg_cfg_dump_dtsxdec_out = 0;
static struct sndbar_dbg_dump_t sndbar_dump_dtsxdec_out;
static int i4_Times_before = 1;
static int i4_Times_after = 1;

static inline void utils_check_time_too_long (struct timespec* begin, struct timespec* end, long thres_ms, char* msg)
{
    long t1 = (begin->tv_sec * 1000) + (begin->tv_nsec / (1000 * 1000));
    long t2 = (end->tv_sec * 1000) + (end->tv_nsec / (1000 * 1000));

    if ((t2 - t1) > thres_ms)
    {
        printf ("[dtsxdec] (too slow: %ld ms) %s\n", t2 - t1, msg);
    }
}
void InitOutputPCMFormat()
{
    gOutputPcmMode.nSize = sizeof(gOutputPcmMode);
    gOutputPcmMode.nPortIndex = 1;
    gOutputPcmMode.nChannels = 2;
    gOutputPcmMode.eNumData = OMX_NumericalDataSigned;
    gOutputPcmMode.eEndian = OMX_EndianLittle;
    gOutputPcmMode.bInterleaved = OMX_TRUE;
    gOutputPcmMode.nBitPerSample = 32;
    gOutputPcmMode.nSamplingRate = 48000;
    gOutputPcmMode.ePCMMode = OMX_AUDIO_PCMModeLinear;
    gOutputPcmMode.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
    gOutputPcmMode.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
    gOutputPcmMode.eChannelMapping[2] = OMX_AUDIO_ChannelCF;
    gOutputPcmMode.eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
    gOutputPcmMode.eChannelMapping[4] = OMX_AUDIO_ChannelLS;
    gOutputPcmMode.eChannelMapping[5] = OMX_AUDIO_ChannelRS;
}

typedef struct _GST_INFO_DTSX
{
    int32_t   stream_type;
    int32_t   object_audio;
    int32_t   dts_comp_gain;     //provide info for UI showing MQA flag
    uint32_t  dts_detail_type;
    uint32_t  dts_sample_rate;      //for mw time show
    uint32_t  dts_stream_layout;      //for mw time show
    uint32_t  dts_bitrate;   //bitstream orginal sample rate

    int32_t dts_dialog_avail;
    int32_t dts_dialog_min;
    int32_t dts_dialog_max;
    int32_t dts_dialog_resolution;
    int32_t dts_analog_compgain;

    int32_t dts_stream_ch_num;
    int32_t dts_stream_ch_mask;

    uint32_t eIsStreamHadT1ccFlag;  // imax For T1CC get Type1Flag imax
    uint32_t u4T1ccProcessMode;  // For T1CC get Type1ProcessMode
    uint32_t u4T1ccState;  // For T1CC get Type1ProcessSta
} GST_INFO_DTSX;


static int checkAnyPortBeingFlushed(omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private)
{
    omx_base_PortType *pPort;
    int ret = OMX_FALSE, i;

    if (omx_type1_decoder_component_Private->state == OMX_StateLoaded ||
        omx_type1_decoder_component_Private->state == OMX_StateInvalid)
    {
        return 0;
    }

    pthread_mutex_lock(&omx_type1_decoder_component_Private->flush_mutex);
    for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
    {
        pPort = omx_type1_decoder_component_Private->ports[i];
        if (PORT_IS_BEING_FLUSHED(pPort))
        {
            ret = OMX_TRUE;
            break;
        }
    }
    pthread_mutex_unlock(&omx_type1_decoder_component_Private->flush_mutex);
    return ret;
}

OMX_ERRORTYPE omx_type1_decoder_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private;
    omx_type1_decoder_component_PortType *pPort = NULL;
    OMX_U32 i;
    type1_dec_component *ptDecCompGot = NULL;
    type1_dec_output_header *ptDecOutputHdr = NULL;
    type1_dec_pcm_attr *ptDecPcmAttr = NULL;
    type1_dec_sideinfo_attr *ptSideInfo = NULL;
    OMX_S32 retval = 0;
    void *handle = NULL;
    OMX_S32 (*fptr)(type1_dec_component **deccomp);
    open_atrace_file();
    atrace_begin("[omx_dtsxdec_component] component_Constructor");

    /* setup sndbar cfg begin */
    sndbar_dbg_cfg_log_level = sndbar_dbg_conf_get_value_int ("/tmp/sndbar_cfg_dtsxdec", "log_level", SNDBAR_LOG_INFO);

    sndbar_dbg_cfg_latency_log_level = sndbar_dbg_conf_get_value_int ("/tmp/sndbar_cfg_dtsxdec", "latency_log_level", SNDBAR_LOG_OFF);
    sndbar_dbg_cfg_latency_log_num = sndbar_dbg_conf_get_value_int ("/tmp/sndbar_cfg_dtsxdec", "latency_log_num", 300);
    sndbar_dbg_log_file_init ("dtsxdec", sndbar_dbg_cfg_latency_log_num);

    sndbar_dbg_cfg_dump_dtsxdec_in = sndbar_dbg_conf_get_value_int ("/tmp/sndbar_cfg_dtsxdec", "dump_dtsxdec_in", 0);
    sndbar_dbg_dump_init (&sndbar_dump_dtsxdec_in, sndbar_dbg_cfg_dump_dtsxdec_in, sndbar_dbg_cfg_dump_dtsxdec_in, "dtsxdec_in");

    sndbar_dbg_cfg_dump_dtsxdec_out = sndbar_dbg_conf_get_value_int ("/tmp/sndbar_cfg_dtsxdec", "dump_dtsxdec_out", 0);
    sndbar_dbg_dump_init (&sndbar_dump_dtsxdec_out, sndbar_dbg_cfg_dump_dtsxdec_out, sndbar_dbg_cfg_dump_dtsxdec_out, "dtsxdec_out");
    /* setup sndbar cfg end */

    handle = dlopen("/usr/lib/libaudio_decoder_dtsx.so", RTLD_LAZY);
    if (handle == NULL)
    {
        SNDBAR_LOGE(sndbar_dbg_cfg_log_level, "/usr/lib/libaudio_decoder_dtsx.so is not exist(%s)\n", dlerror());
        return OMX_ErrorInsufficientResources;
    }
    fptr = NULL;
    fptr = dlsym(handle, "get_decoder_component_description");
    (*fptr)(&ptDecCompGot);

    if (NULL == ptDecCompGot)
    {
        LOGE("ptDecCompGot NULL...\n");
        return OMX_ErrorInsufficientResources;
    }

    RM_RegisterComponent(ptDecCompGot->pcName, MAX_TYPE1_DECODER_COMPONENTS);
    if (!openmaxStandComp->pComponentPrivate)
    {
        LOGE("allocating component private...\n");
        openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_type1_decoder_component_PrivateType));
        if (openmaxStandComp->pComponentPrivate == NULL)
        {
            LOGE("allocating component private fail!\n");
            return OMX_ErrorInsufficientResources;
        }
    }
    else
    {
        LOGE("Error Component %p Already Allocated\n", openmaxStandComp->pComponentPrivate);
    }
    if (NULL == pOMXProcessTmpBuf)
    {
        pOMXProcessTmpBuf = calloc(1, 61310 * 2);
    }

    omx_type1_decoder_component_Private = openmaxStandComp->pComponentPrivate;
    omx_type1_decoder_component_Private->ports = NULL;

    LOGE("call omx_base_component_Constructor...\n");
    err = omx_base_component_Constructor(openmaxStandComp, ptDecCompGot->pcName);
    if (OMX_ErrorNone != err)
    {
        LOGE("omx_base_component_Constructor return fail %d!\n", (int)err);
        return err;
    }

    LOGE("Private->name=%s\n", omx_type1_decoder_component_Private->name);

    omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nStartPortNumber = 0;
    omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts = TYPE1_DECODER_COMP_MAX_PORTS;

    LOGE("Allocate Ports and call port constructor...\n");
    if (omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts && !omx_type1_decoder_component_Private->ports)
    {
        omx_type1_decoder_component_Private->ports = calloc(omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts, sizeof(omx_base_PortType *));
        if (!omx_type1_decoder_component_Private->ports)
        {
            LOGE("omx_type1_decoder_component_Private->ports alloc fail!\n");
            return OMX_ErrorInsufficientResources;
        }
        for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
        {
            omx_type1_decoder_component_Private->ports[i] = calloc(1, sizeof(omx_type1_decoder_component_PortType));
            if (!omx_type1_decoder_component_Private->ports[i])
            {
                LOGE("omx_type1_decoder_component_Private->ports[%d] alloc fail!\n", (int)i);
                return OMX_ErrorInsufficientResources;
            }
        }
    }

    LOGE("construct input ports...\n");
    base_audio_port_Constructor(openmaxStandComp, &omx_type1_decoder_component_Private->ports[0], 0, OMX_TRUE);

    LOGE("construct output ports...\n");
    base_audio_port_Constructor(openmaxStandComp,
                                &omx_type1_decoder_component_Private->ports[omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts - 1],
                                omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts - 1, OMX_FALSE);

    for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
    {
        if (omx_type1_decoder_component_Private->ports && omx_type1_decoder_component_Private->ports[i])
        {
            pPort = (omx_type1_decoder_component_PortType *)omx_type1_decoder_component_Private->ports[i];
            pPort->sPortParam.nBufferCountActual = 40;
            pPort->sPortParam.nBufferCountMin = 40;
        }

        if (i == 0)
        {
            memset(pPort->sPortParam.format.audio.cMIMEType, 0, DEFAULT_MIME_STRING_LENGTH);
            strcpy(pPort->sPortParam.format.audio.cMIMEType, "audio/dtsx");
            pPort->sPortParam.format.audio.pNativeRender = NULL;
            pPort->sPortParam.format.audio.bFlagErrorConcealment  = OMX_FALSE;
            pPort->sPortParam.format.audio.eEncoding = OMX_AUDIO_CodingDTSX;
        }
        else if (i == 1)
        {
            memset(pPort->sPortParam.format.audio.cMIMEType, 0, DEFAULT_MIME_STRING_LENGTH);
            strcpy(pPort->sPortParam.format.audio.cMIMEType, "audio/raw");
            pPort->sPortParam.format.audio.pNativeRender = NULL;
            pPort->sPortParam.format.audio.bFlagErrorConcealment = OMX_FALSE;
            pPort->sPortParam.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
        }
    }

    LOGE("init private member...\n");
    omx_type1_decoder_component_Private->destructor = omx_type1_decoder_component_Destructor;
    openmaxStandComp->SetParameter = omx_type1_decoder_component_SetParameter;
    openmaxStandComp->GetParameter = omx_type1_decoder_component_GetParameter;
    openmaxStandComp->AllocateBuffer = omx_type1_decoder_component_AllocateBuffer;
    openmaxStandComp->FreeBuffer = omx_type1_decoder_component_FreeBuffer;
    if (0 != tsem_init(&(omx_type1_decoder_component_Private->tEventCbSem), 0))
    {
        LOGE("tEventCbSem tsem_init fail!\n");
        return OMX_ErrorInsufficientResources;
    }
    omx_type1_decoder_component_Private->BufferMgmtFunction = omx_type1_decoder_component_BufferMgmtFunction;
    omx_type1_decoder_component_Private->deccomptypeversion = TYPE1_DEC_COMP_VERSION;
    omx_type1_decoder_component_Private->ptDecComp = ptDecCompGot;
    omx_type1_decoder_component_Private->pvDecSelfData = NULL;
    omx_type1_decoder_component_Private->eIsIgnoreDecCurActionErr = OMX_FALSE;
    memset(&(omx_type1_decoder_component_Private->tTmpInputBuf), 0, sizeof(OMX_BUFFERHEADERTYPE));
    memset(&(omx_type1_decoder_component_Private->tTmpOutputBuf), 0, sizeof(OMX_BUFFERHEADERTYPE));

    omx_type1_decoder_component_Private->tTmpOutputBuf.nSize = sizeof(OMX_BUFFERHEADERTYPE);
    omx_type1_decoder_component_Private->tTmpOutputBuf.nAllocLen = TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE +
            (((sizeof(type1_dec_output_header) + sizeof(type1_dec_pcm_attr) + sizeof(type1_dec_sideinfo_attr) + TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) + 16) >> 4) << 4);
    omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer = (OMX_U8 *)calloc(1, omx_type1_decoder_component_Private->tTmpOutputBuf.nAllocLen);
    omx_type1_decoder_component_Private->tTmpOutputBuf.nOffset = ((sizeof(type1_dec_output_header) + sizeof(type1_dec_sideinfo_attr) + sizeof(type1_dec_pcm_attr) + 16) >> 4) << 4;
    omx_type1_decoder_component_Private->tTmpOutputBuf.nFilledLen = omx_type1_decoder_component_Private->tTmpOutputBuf.nOffset;
    if (NULL == omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer)
    {
        LOGE("Alloc Down Sample && Drop Sample buffer fail!\n");
        return OMX_ErrorInsufficientResources;
    }
    memset(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer, 0, omx_type1_decoder_component_Private->tTmpOutputBuf.nOffset);
    ptDecOutputHdr = (type1_dec_output_header *)omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer;

    ptSideInfo = (type1_dec_sideinfo_attr *)(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer + sizeof(type1_dec_output_header) );
    ptDecOutputHdr->ptSideinfoAttrArray = ptSideInfo;
    ptSideInfo->pvSideinfoData = (OMX_PTR)(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer +
                                           omx_type1_decoder_component_Private->tTmpOutputBuf.nOffset);
    ptSideInfo->u4SideinfoNum = 0;

    ptDecPcmAttr = (type1_dec_pcm_attr *)(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer + sizeof(type1_dec_output_header) +
                                          sizeof(type1_dec_sideinfo_attr));
    ptDecOutputHdr->u4Version = TYPE1_DEC_OUTPUT_BUFFER_VERSION;
    ptDecOutputHdr->u4Size = sizeof(type1_dec_output_header);
    ptDecOutputHdr->u4Pcmattrnum = 1;
    ptDecOutputHdr->ptPcmAttrArray = ptDecPcmAttr;

    ptDecPcmAttr->u4Version = TYPE1_DEC_PCM_ATTR_VERSION;
    ptDecPcmAttr->u4Size = sizeof(type1_dec_pcm_attr);
    ptDecPcmAttr->pvPcmData = (OMX_PTR)(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer +
                                        omx_type1_decoder_component_Private->tTmpOutputBuf.nOffset +
                                        TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) +
                                        TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE);;
    ptDecPcmAttr->u4SampleNumPerChannel = 0;

    omx_type1_decoder_component_Private->u4IsDecDownSampleOpen = 0;
    omx_type1_decoder_component_Private->u4IsDecDropSampleOpen = 0;
    omx_type1_decoder_component_Private->u4IsDecUpSampleOpen = 0;
    if (0 != tsem_init(&(omx_type1_decoder_component_Private->tAudDropSampleSem), 1))
    {
        LOGE("tAudDropSampleSem tsem_init fail!\n");
        return OMX_ErrorInsufficientResources;
    }

    omx_type1_decoder_component_Private->fpDecInputDump = NULL;
    omx_type1_decoder_component_Private->fpDecOutputDump = NULL;
    omx_type1_decoder_component_Private->eNotResendData = OMX_FALSE;
    omx_type1_decoder_component_Private->nqualitylevels = 0;
    omx_type1_decoder_component_Private->currentQualityLevel = 0;
    omx_type1_decoder_component_Private->multiResourceLevel = NULL;

    InitOutputPCMFormat();

#if 1                                                           /*add by yuan.fang for setting parament @0514*/
    OMX_MTK_COMMON_DEC_FLOW_CTRL_STRUCT ptOmxMtkDecFlowCtrl;
    memset(&ptOmxMtkDecFlowCtrl, 0, sizeof(ptOmxMtkDecFlowCtrl));
    OMX_PTR pvDecInitInfo = NULL;

    ptOmxMtkDecFlowCtrl.nSize = sizeof(OMX_MTK_COMMON_DEC_FLOW_CTRL_STRUCT);
    ptOmxMtkDecFlowCtrl.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;
    ptOmxMtkDecFlowCtrl.nVersion.s.nVersionMinor = SPECVERSIONMINOR;
    ptOmxMtkDecFlowCtrl.nVersion.s.nRevision = SPECREVISION;
    ptOmxMtkDecFlowCtrl.nVersion.s.nStep = SPECSTEP;
    ptOmxMtkDecFlowCtrl.eDecFlowCtrlType = CommonDecFlowCtrl_DecInit;
    ptOmxMtkDecFlowCtrl.uParam.eDecInitInfo.pvDecInitInfo = pvDecInitInfo;
    ptOmxMtkDecFlowCtrl.uParam.eDecInitInfo.u4DecInitInfoSize = sizeof(AUD_DEC_AUD_INFO_T);

    TYPE1_DEC_ACTION_INTF *ptDecActionIntf = &(omx_type1_decoder_component_Private->ptDecComp->tDecActionIntf);
    atrace_begin("[omx_dtsxdec_component] decoder init");

    OMX_PTR pvDecSelfData = omx_type1_decoder_component_Private->pvDecSelfData;
    OMX_S32 i4DecIntfRet = ptDecActionIntf->decoder_init(&(omx_type1_decoder_component_Private->pvDecSelfData), ptOmxMtkDecFlowCtrl.uParam.eDecInitInfo.pvDecInitInfo, ptOmxMtkDecFlowCtrl.uParam.eDecInitInfo.u4DecInitInfoSize);
    if (i4DecIntfRet < 0)
    {
        err = (OMX_ERRORTYPE)OMX_ErrorDecoderActionIntfError;
        LOGE("decoder_init return OMX_ErrorDecoderActionIntfError\n");
    }
    atrace_end("[omx_dtsxdec_component] decoder init");

#endif
    atrace_end("[omx_dtsxdec_component] component_Constructor");
    return err;
}

OMX_ERRORTYPE omx_type1_decoder_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
{
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = openmaxStandComp->pComponentPrivate;
    TYPE1_DEC_ACTION_INTF *ptDecActionIntf = NULL;
    OMX_U32 i;
    OMX_S32 i4DecActionIntfRet = 0;

    LOGE("In \n");
    atrace_begin("[omx_dtsxdec_component] component_Destructor");

    if (omx_type1_decoder_component_Private->ports)
    {
        for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
        {
            if (omx_type1_decoder_component_Private->ports[i])
            {
                omx_type1_decoder_component_Private->ports[i]->PortDestructor(omx_type1_decoder_component_Private->ports[i]);
            }
        }
        free(omx_type1_decoder_component_Private->ports);
        omx_type1_decoder_component_Private->ports = NULL;
    }

    tsem_deinit(&(omx_type1_decoder_component_Private->tEventCbSem));
    if (NULL != omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer)
    {
        free(omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer);
    }
    omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer = NULL;

    ptDecActionIntf = &(omx_type1_decoder_component_Private->ptDecComp->tDecActionIntf);
    if (NULL != omx_type1_decoder_component_Private->pvDecSelfData)
    {
        if (NULL != ptDecActionIntf->decoder_uninit)
        {
            atrace_begin("[omx_dtsxdec_component] decoder uninit");
            i4DecActionIntfRet = ptDecActionIntf->decoder_uninit(omx_type1_decoder_component_Private->pvDecSelfData);
            if (0 != i4DecActionIntfRet)
            {
                LOGE("Call decoder_uninit meeting error(%d)\n", (int)i4DecActionIntfRet);
            }
            atrace_end("[omx_dtsxdec_component] decoder uninit");
        }
        else
        {
            free(omx_type1_decoder_component_Private->pvDecSelfData);
        }
        omx_type1_decoder_component_Private->pvDecSelfData = NULL;
    }

    if (NULL != omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer)
    {
        free(omx_type1_decoder_component_Private->tTmpOutputBuf.pBuffer);
        LOGE("Free Down Sample && Drop Sample buffer!\n");
    }

    if (NULL != pOMXProcessTmpBuf)
    {
        free(pOMXProcessTmpBuf);
        pOMXProcessTmpBuf = NULL;
        LOGE("Free pOMXProcessTmpBuf!\n");
    }

    if (NULL != omx_type1_decoder_component_Private->fpDecInputDump)
    {
        fclose(omx_type1_decoder_component_Private->fpDecInputDump);
        omx_type1_decoder_component_Private->fpDecInputDump = NULL;
    }
    if (NULL != omx_type1_decoder_component_Private->fpDecOutputDump)
    {
        fclose(omx_type1_decoder_component_Private->fpDecOutputDump);
        omx_type1_decoder_component_Private->fpDecOutputDump = NULL;
    }

    omx_base_component_Destructor(openmaxStandComp);
    atrace_end("[omx_dtsxdec_component] component_Destructor");
    close_atrace_file();

    LOGE("Out\n");

    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_type1_decoder_component_AllocateBuffer(
    OMX_HANDLETYPE hComponent,
    OMX_BUFFERHEADERTYPE** ppBuffer,
    OMX_U32 nPortIndex,
    OMX_PTR pAppPrivate,
    OMX_U32 nSizeBytes)
{
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = (omx_type1_decoder_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
    omx_base_PortType *pPort;
    OMX_ERRORTYPE err;
    OMX_U8* ptmpbuf = NULL;
    OMX_U8* ptmpbuf01 = NULL;
    OMX_U32 bufcpylen = 0;

    LOGE("In %s for component %p\n", __func__, hComponent);

    if (nPortIndex >= (omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainImage].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts))
    {
        LOGE("In %s: wrong port index\n", __func__);
        return OMX_ErrorBadPortIndex;
    }

    if ((nPortIndex < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts - 1) &&
        (omx_type1_decoder_component_Private->tTmpInputBuf.nAllocLen < nSizeBytes * 2))
    {
        ptmpbuf = calloc(1, nSizeBytes * 2);
        if (NULL == ptmpbuf)
        {
            LOGE("in %s, can't alloc buffer for tTmpInputBuf!\n", __func__);
            return OMX_ErrorInsufficientResources;
        }
        if (NULL != omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer)
        {
            LOGE("In %s: warning, temp buffer is not free\n", __func__);
            ptmpbuf01 = (OMX_U8*)(omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer +
                                  omx_type1_decoder_component_Private->tTmpInputBuf.nOffset);
            bufcpylen = omx_type1_decoder_component_Private->tTmpInputBuf.nFilledLen -
                        omx_type1_decoder_component_Private->tTmpInputBuf.nOffset;
            if (bufcpylen > omx_type1_decoder_component_Private->tTmpInputBuf.nFilledLen)
            {
                bufcpylen = 0;
            }
            else
            {
                memcpy(ptmpbuf, ptmpbuf01, bufcpylen);
            }
            free(omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer);
        }
        omx_type1_decoder_component_Private->tTmpInputBuf.nSize = sizeof(OMX_BUFFERHEADERTYPE);
        omx_type1_decoder_component_Private->tTmpInputBuf.pBuffer = ptmpbuf;
        omx_type1_decoder_component_Private->tTmpInputBuf.nAllocLen = nSizeBytes * 2;
        omx_type1_decoder_component_Private->tTmpInputBuf.nFilledLen = bufcpylen;
        omx_type1_decoder_component_Private->tTmpInputBuf.nOffset = 0;
    }

    pPort = omx_type1_decoder_component_Private->ports[nPortIndex];
    err = pPort->Port_AllocateBuffer(pPort, ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
    if (err != OMX_ErrorNone)
    {
        LOGE("In %s, component %p Port_AllocateBuffer return err %i\n", __func__, hComponent, (int)err);
        return err;
    }
    pPort->sPortParam.nBufferSize = nSizeBytes;

    LOGE("Out of %s for component %p buffer %p\n", __func__, hComponent, ppBuffer);
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_type1_decoder_component_FreeBuffer(
    OMX_HANDLETYPE hComponent,
    OMX_U32 nPortIndex,
    OMX_BUFFERHEADERTYPE* pBuffer)
{
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = (omx_type1_decoder_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
    omx_base_PortType *pPort;
    OMX_ERRORTYPE err;

    LOGE("In for component %p\n", hComponent);
    if (nPortIndex >= (omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainImage].nPorts +
                       omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts))
    {
        LOGE("In wrong port index\n");
        return OMX_ErrorBadPortIndex;
    }

    pPort = omx_type1_decoder_component_Private->ports[nPortIndex];
    err = pPort->Port_FreeBuffer(pPort, nPortIndex, pBuffer);
    if (err != OMX_ErrorNone)
    {
        LOGE("Out of for component %p with err %i\n", hComponent, (int)err);
        return err;
    }
    pPort->sPortParam.nBufferSize = 0;
    LOGE("Out of for component %p\n", hComponent);
    return OMX_ErrorNone;
}

OMX_ERRORTYPE omx_type1_decoder_component_GetParameter(
    OMX_HANDLETYPE hComponent,
    OMX_INDEXTYPE nParamIndex,
    OMX_PTR ComponentParameterStructure)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OMX_MTK_COMMON_DEC_PARAM_STRUCT *peType1DecParam = NULL;
    OMX_S32 i4DecIntfRet = 0;
    TYPE1_DEC_ACTION_INTF *ptDecActionIntf = NULL;
    OMX_PTR pvDecSelfData = NULL;

    OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = openmaxStandComp->pComponentPrivate;
    ptDecActionIntf = &(omx_type1_decoder_component_Private->ptDecComp->tDecActionIntf);
    pvDecSelfData = omx_type1_decoder_component_Private->pvDecSelfData;

    if (ComponentParameterStructure == NULL)
    {
        return OMX_ErrorBadParameter;
    }

    LOGE("Getting parameter in: 0x%x\n", nParamIndex);
    switch (nParamIndex)
    {
        case OMX_IndexParamAudioPcm:
        {
            OMX_AUDIO_PARAM_PCMMODETYPE mOutputPcmMode;
            mOutputPcmMode.nSize = sizeof(mOutputPcmMode);
            mOutputPcmMode.nPortIndex = gOutputPcmMode.nPortIndex;
            mOutputPcmMode.nChannels = gOutputPcmMode.nChannels;
            mOutputPcmMode.eNumData = gOutputPcmMode.eNumData;
            mOutputPcmMode.eEndian = gOutputPcmMode.eEndian;
            mOutputPcmMode.bInterleaved = gOutputPcmMode.bInterleaved;
            mOutputPcmMode.nBitPerSample = gOutputPcmMode.nBitPerSample;
            mOutputPcmMode.nSamplingRate = gOutputPcmMode.nSamplingRate;
            mOutputPcmMode.ePCMMode = gOutputPcmMode.ePCMMode;
            mOutputPcmMode.eChannelMapping[0] = gOutputPcmMode.eChannelMapping[0];
            mOutputPcmMode.eChannelMapping[1] = gOutputPcmMode.eChannelMapping[1];
            mOutputPcmMode.eChannelMapping[2] = gOutputPcmMode.eChannelMapping[2];
            mOutputPcmMode.eChannelMapping[3] = gOutputPcmMode.eChannelMapping[3];
            mOutputPcmMode.eChannelMapping[4] = gOutputPcmMode.eChannelMapping[4];
            mOutputPcmMode.eChannelMapping[5] = gOutputPcmMode.eChannelMapping[5];
            mOutputPcmMode.eChannelMapping[6] = gOutputPcmMode.eChannelMapping[6];
            mOutputPcmMode.eChannelMapping[7] = gOutputPcmMode.eChannelMapping[7];

            LOGE("nChannels[%d], nSamplingRate[%d]\n", mOutputPcmMode.nChannels, mOutputPcmMode.nSamplingRate);

            OMX_AUDIO_PARAM_PCMMODETYPE *pPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE *)ComponentParameterStructure;
            if (pPcmMode->nPortIndex == mOutputPcmMode.nPortIndex)
            {
                memcpy(ComponentParameterStructure, &mOutputPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
            }
            break;
        }
        default:
        {
            err = omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
            if (nParamIndex == OMX_IndexParamPortDefinition)
            {
                OMX_PARAM_PORTDEFINITIONTYPE *pPortdef = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure;
                if (pPortdef->nPortIndex == 1)
                {
                    pPortdef->nBufferSize = 448 * 1024;
                }
            }
        }
    }
    return err;
}

OMX_ERRORTYPE omx_type1_decoder_component_SetParameter(
    OMX_HANDLETYPE hComponent,
    OMX_INDEXTYPE nParamIndex,
    OMX_PTR ComponentParameterStructure)
{
    OMX_ERRORTYPE err = OMX_ErrorNone;
    OMX_MTK_COMMON_DEC_PARAM_STRUCT *peType1DecParam = NULL;
    OMX_MTK_COMMON_DEC_FLOW_CTRL_STRUCT *peType1DecFlowCtrl = NULL;
    OMX_S32 i4DecIntfRet = 0;
    TYPE1_DEC_ACTION_INTF *ptDecActionIntf = NULL;
    OMX_PTR pvDecSelfData = NULL;
    OMX_S32 i = 0;

    OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = openmaxStandComp->pComponentPrivate;
    ptDecActionIntf = &(omx_type1_decoder_component_Private->ptDecComp->tDecActionIntf);
    pvDecSelfData = omx_type1_decoder_component_Private->pvDecSelfData;

    if (ComponentParameterStructure == NULL)
    {
        return OMX_ErrorBadParameter;
    }

    LOGE("Setting parameter in: 0x%x\n", nParamIndex);
    switch (nParamIndex)
    {
        case OMX_IndexParamStandardComponentRole:
        {
            OMX_U8 mCompRole[OMX_MAX_STRINGNAME_SIZE] = {0};
            OMX_PARAM_COMPONENTROLETYPE *pRoleParams = (OMX_PARAM_COMPONENTROLETYPE *)ComponentParameterStructure;
            strcpy((char *)mCompRole, (char *)pRoleParams->cRole);
            err = OMX_ErrorNone;
            break;
        }
        case OMX_IndexConfigDTSXDecMode:
        {
            if (NULL == ptDecActionIntf->set_parameter)
            {
                err = (OMX_ERRORTYPE)OMX_ErrorDecoderActionIntfNone;
                LOGE("In %s set_parameter is NULL Error=%x\n", __func__, err);
                break;
            }

            OMX_AUDIO_DTSX_APP_PARAM *ptDtsxParam = (OMX_AUDIO_DTSX_APP_PARAM *)ComponentParameterStructure;
            COMMON_DEC_PARAM_STR_T ptParamStrSetting;
            memset(&ptParamStrSetting, 0, sizeof(ptParamStrSetting));

            if (ptDtsxParam->nDirectmode != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-enabledirectmode%d", ptDtsxParam->nDirectmode);
                LOGE("[set_param]nDirectmode = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nDialogcontrol != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-setdialogcontrol%d", ptDtsxParam->nDialogcontrol);
                LOGE("[set_param]nDialogcontrol = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nDrcpercent != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-DRCPercent%d", ptDtsxParam->nDrcpercent);
                LOGE("[set_param]nDrcpercent = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nspkconfig)
            {
                strcpy(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-speakers");
                LOGE("[set_param]nspkconfig[0] = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                strcpy(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc + 1], ptDtsxParam->nspkconfig);
                LOGE("[set_param]nspkconfig[1] = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc + 1]);
                ptParamStrSetting.i4Argc += 2;
            }

            if (ptDtsxParam->nT1ccmode!= -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-sett1ccmode%d", ptDtsxParam->nT1ccmode);
                LOGE("[set_param]nT1ccmode = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nBitwidth != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-b%d", ptDtsxParam->nBitwidth);
                LOGE("[set_param]nBitwidth = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nUpsamplerate != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-upsamplerate%d", ptDtsxParam->nUpsamplerate);
                LOGE("[set_param]nUpsamplerate = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nAnalogcomp != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-analogcomp%d", ptDtsxParam->nAnalogcomp);
                LOGE("[set_param]nAnalogcomp = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            if (ptDtsxParam->nM6mode != -1)
            {
                sprintf(ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc], "-m6mode%d", ptDtsxParam->nM6mode);
                LOGE("[set_param]nM6mode = %s\n", ptParamStrSetting.szArgv[ptParamStrSetting.i4Argc]);
                ptParamStrSetting.i4Argc++;
            }

            i4DecIntfRet = ptDecActionIntf->set_parameter(pvDecSelfData, CommonDecParam_ParamStrSet, (OMX_PTR)&ptParamStrSetting);
            if (i4DecIntfRet < 0)
            {
                err = (OMX_ERRORTYPE)OMX_ErrorDecoderActionIntfError;
                LOGE("In return OMX_ErrorDecoderActionIntfError\n");
            }

            if (ptDtsxParam->u4Channels != -1)
            {
                gOutputPcmMode.nChannels = ptDtsxParam->u4Channels;
                SNDBAR_LOGD(sndbar_dbg_cfg_log_level, "[omx_dtsxdec_component] get dec_output_channels:%u\n",gOutputPcmMode.nChannels);
            }
            if (ptDtsxParam->u4SampleRate != -1)
            {
                gOutputPcmMode.nSamplingRate= ptDtsxParam->u4SampleRate;
                SNDBAR_LOGD(sndbar_dbg_cfg_log_level, "[omx_dtsxdec_component] get dec_output_samplerate:%u\n",gOutputPcmMode.nSamplingRate);
            }

            break;
        }
        default:
        {
            err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
        }
    }
    return err;
}

void* omx_type1_decoder_component_BufferMgmtFunction(void* param)
{
    OMX_COMPONENTTYPE* openmaxStandComp = NULL;
    omx_type1_decoder_component_PrivateType* omx_type1_decoder_component_Private = NULL;
    omx_base_PortType *pPort[TYPE1_DECODER_COMP_MAX_PORTS] = {NULL};
    tsem_t* pSem[TYPE1_DECODER_COMP_MAX_PORTS] = {NULL};
    queue_t* pQueue[TYPE1_DECODER_COMP_MAX_PORTS] = {NULL};
    OMX_BUFFERHEADERTYPE* pBuffer[TYPE1_DECODER_COMP_MAX_PORTS] = {NULL};
    OMX_BOOL isBufferNeeded[TYPE1_DECODER_COMP_MAX_PORTS] = {0};
    OMX_BOOL isBufferReady = OMX_FALSE;
    OMX_U32 nOutputPortIndex, i;

    OMX_BUFFERHEADERTYPE* ptTmpInputBuf = NULL;
    OMX_PTR pvDecSelfData = NULL;
    TYPE1_DEC_INPUT_BUF tDecInput;
    TYPE1_DEC_OUTPUT_BUF tDecOutput;
    TYPE1_DEC_ACTION_INTF *ptDecActionIntf = NULL;
    type1_dec_output_header *ptDecOutputHdr = NULL;
    type1_dec_pcm_attr *ptDecPcmAttr = NULL;
    type1_dec_sideinfo_attr *ptSideinfoAttr = NULL;
    OMX_U32 u4InputBufConsumed = 0;
    OMX_U32 u4TmpBufRemainSize = 0;
    OMX_U32 u4TmpBufCpySize = 0;
    OMX_BOOL u4IsDecInfoChg = OMX_FALSE;
    OMX_S32 u4DecActionIntfRet = 0;

    OMX_ADAPTOR_CALLBACK_STRUCT *pCallback;
    OMX_U32 u4AfifoDecReadPtr = 0;
    AUD_NOTIFY_INFO rDecNfyInfo;

    openmaxStandComp = (OMX_COMPONENTTYPE*)param;
    omx_type1_decoder_component_Private = (omx_type1_decoder_component_PrivateType*)openmaxStandComp->pComponentPrivate;
    ptDecActionIntf = &(omx_type1_decoder_component_Private->ptDecComp->tDecActionIntf);
    pvDecSelfData = omx_type1_decoder_component_Private->pvDecSelfData;
    ptTmpInputBuf = &(omx_type1_decoder_component_Private->tTmpInputBuf);
    memset(&rDecNfyInfo, 0, sizeof(AUD_NOTIFY_INFO));

    if (NULL == ptDecActionIntf->decode)
    {
        LOGE("There is no decode function exit!\n");
        return NULL;
    }

    for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
    {
        pPort[i] = omx_type1_decoder_component_Private->ports[i];
        pSem[i] = pPort[i]->pBufferSem;
        pQueue[i] = pPort[i]->pBufferQueue;
        pBuffer[i] = NULL;
        isBufferNeeded[i] = OMX_TRUE;
    }
    nOutputPortIndex = omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts - 1;

    while (omx_type1_decoder_component_Private->state == OMX_StateIdle ||
           omx_type1_decoder_component_Private->state == OMX_StateExecuting ||
           omx_type1_decoder_component_Private->state == OMX_StatePause ||
           omx_type1_decoder_component_Private->transientState == OMX_TransStateLoadedToIdle)
    {
        while (checkAnyPortBeingFlushed(omx_type1_decoder_component_Private))
        {
            LOGE("1 signalling flush all cond iF=%d,oF=%d iSemVal=%d,oSemval=%d\n", isBufferNeeded[0], isBufferNeeded[nOutputPortIndex], pSem[0]->semval, pSem[nOutputPortIndex]->semval);
            for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
            {
                if (isBufferNeeded[i] == OMX_FALSE && PORT_IS_BEING_FLUSHED(pPort[i]))
                {
                    pPort[i]->ReturnBufferFunction(pPort[i], pBuffer[i]);
                    pBuffer[i] = NULL;
                    isBufferNeeded[i] = OMX_TRUE;
                    LOGE("Ports are flushing,so returning buffer %i\n", (int)i);
                }
            }

            LOGE("2 signalling flush all cond iF=%d,oF=%d iSemVal=%d,oSemval=%d\n", isBufferNeeded[0], isBufferNeeded[nOutputPortIndex], pSem[0]->semval, pSem[nOutputPortIndex]->semval);

            tsem_up(omx_type1_decoder_component_Private->flush_all_condition);
            tsem_down(omx_type1_decoder_component_Private->flush_condition);
        }

        if (omx_type1_decoder_component_Private->state == OMX_StateLoaded || omx_type1_decoder_component_Private->state == OMX_StateInvalid)
        {
            LOGE("Buffer Management Thread is exiting\n");
            break;
        }

        if ((isBufferNeeded[0] == OMX_TRUE && pSem[0]->semval == 0) &&
            (omx_type1_decoder_component_Private->state != OMX_StateLoaded &&
             omx_type1_decoder_component_Private->state != OMX_StateInvalid) &&
            PORT_IS_ENABLED(pPort[0]) && !PORT_IS_BEING_FLUSHED(pPort[0]) &&
            (0 == ptTmpInputBuf->nFilledLen - ptTmpInputBuf->nOffset))
        {
            tsem_down(omx_type1_decoder_component_Private->bMgmtSem);
        }
        if (checkAnyPortBeingFlushed(omx_type1_decoder_component_Private))
        {
            LOGE("[Buffer_Mgmtfunction]continue....\n");
            continue;
        }
        if (omx_type1_decoder_component_Private->state == OMX_StateLoaded || omx_type1_decoder_component_Private->state == OMX_StateInvalid)
        {
            LOGE("Buffer Management Thread is exiting\n");
            break;
        }

        if ((isBufferNeeded[1] == OMX_TRUE && pSem[1]->semval == 0) &&
            (omx_type1_decoder_component_Private->state != OMX_StateLoaded &&
             omx_type1_decoder_component_Private->state != OMX_StateInvalid) &&
            PORT_IS_ENABLED(pPort[1]) && !PORT_IS_BEING_FLUSHED(pPort[1]))
        {
            tsem_down(omx_type1_decoder_component_Private->bMgmtSem);
        }

        if (checkAnyPortBeingFlushed(omx_type1_decoder_component_Private))
        {
            LOGE("[Buffer_Mgmtfunction]continue....\n");
            continue;
        }
        if (omx_type1_decoder_component_Private->state == OMX_StateLoaded || omx_type1_decoder_component_Private->state == OMX_StateInvalid)
        {
            LOGE("Buffer Management Thread is exiting\n");
            break;
        }

        isBufferReady = OMX_TRUE;
        for (i = 0; i < omx_type1_decoder_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++)
        {
            if (pSem[i]->semval > 0 && isBufferNeeded[i] == OMX_TRUE && PORT_IS_ENABLED(pPort[i]))
            {
                tsem_down(pSem[i]);
                if (pQueue[i]->nelem > 0)
                {
                    isBufferNeeded[i] = OMX_FALSE;
                    LOGE("[Buffer_Mgmtfunction]dequeue pQueue[%d] a buffer\n", i);
                    pBuffer[i] = dequeue(pQueue[i]);
                    if (pBuffer[i] == NULL)
                    {
                        LOGE("Had NULL input buffer!!\n");
                        break;
                    }
                }
                else
                {
                    LOGE("[Buffer_Mgmtfunction]Error,pQueue[%d]->nelem = %d\n", i, pQueue[i]->nelem);
                }
            }
            if (isBufferNeeded[i] == OMX_TRUE)
            {
                isBufferReady = OMX_FALSE;
            }
        }

        if (isBufferReady == OMX_FALSE)
        {
            if (isBufferNeeded[nOutputPortIndex] == OMX_TRUE)
            {
                usleep(10 * 1000);
                continue;
            }
            if (0 == ptTmpInputBuf->nFilledLen - ptTmpInputBuf->nOffset)
            {
                usleep(10 * 1000);
                continue;
            }
        }

        if (omx_type1_decoder_component_Private->state == OMX_StateExecuting)
        {
            tDecInput.pvBuf = (OMX_PTR)(ptTmpInputBuf->pBuffer + ptTmpInputBuf->nOffset);
            tDecInput.u4BufByteSize = ptTmpInputBuf->nFilledLen - ptTmpInputBuf->nOffset;
            if (tDecInput.u4BufByteSize > ptTmpInputBuf->nFilledLen)
            {
                LOGE("the input buffer meet error case!!\n");
                tDecInput.u4BufByteSize = 0;
                ptTmpInputBuf->nFilledLen = ptTmpInputBuf->nOffset;
            }
            if (NULL != pBuffer[0])
            {
                u4TmpBufRemainSize = ptTmpInputBuf->nAllocLen - ptTmpInputBuf->nFilledLen;
                if ((u4TmpBufRemainSize < pBuffer[0]->nFilledLen) && (ptTmpInputBuf->nOffset > 0))
                {
                    if (tDecInput.u4BufByteSize > 0)
                    {
                        memmove(ptTmpInputBuf->pBuffer, tDecInput.pvBuf, tDecInput.u4BufByteSize);
                    }
                    ptTmpInputBuf->nOffset = 0;
                    ptTmpInputBuf->nFilledLen = tDecInput.u4BufByteSize;
                    u4TmpBufRemainSize = ptTmpInputBuf->nAllocLen - ptTmpInputBuf->nFilledLen;
                }
                if (pBuffer[0]->nFilledLen > 0)
                {
                    u4TmpBufCpySize = u4TmpBufRemainSize;
                    if (u4TmpBufCpySize > pBuffer[0]->nFilledLen)
                    {
                        u4TmpBufCpySize = pBuffer[0]->nFilledLen;
                    }
                    if (u4TmpBufCpySize > 0)
                    {
                        memcpy((ptTmpInputBuf->pBuffer + ptTmpInputBuf->nFilledLen), (pBuffer[0]->pBuffer + pBuffer[0]->nOffset), u4TmpBufCpySize);
                        ptTmpInputBuf->nFilledLen += u4TmpBufCpySize;
                        pBuffer[0]->nFilledLen -= u4TmpBufCpySize;
                        pBuffer[0]->nOffset += u4TmpBufCpySize;
                    }
                }
                if ((0 == pBuffer[0]->nFilledLen) && (OMX_BUFFERFLAG_EOS == (pBuffer[0]->nFlags & OMX_BUFFERFLAG_EOS)))
                {
                    ptTmpInputBuf->nFlags |= OMX_BUFFERFLAG_EOS;
                }
                tDecInput.pvBuf = (OMX_PTR)(ptTmpInputBuf->pBuffer + ptTmpInputBuf->nOffset);
                tDecInput.u4BufByteSize = ptTmpInputBuf->nFilledLen - ptTmpInputBuf->nOffset;
            }

            if (tDecInput.u4BufByteSize != 0)
            {
                ptDecOutputHdr = (type1_dec_output_header *)pBuffer[nOutputPortIndex]->pBuffer;
                ptSideinfoAttr = (type1_dec_sideinfo_attr *)(pBuffer[nOutputPortIndex]->pBuffer + sizeof(type1_dec_output_header));
                ptDecPcmAttr = (type1_dec_pcm_attr *)(pBuffer[nOutputPortIndex]->pBuffer + sizeof(type1_dec_output_header) + sizeof(type1_dec_sideinfo_attr));

                pBuffer[nOutputPortIndex]->nOffset = (((sizeof(type1_dec_output_header) + sizeof(type1_dec_sideinfo_attr) + sizeof(type1_dec_pcm_attr) + 16) >> 4) << 4);
                pBuffer[nOutputPortIndex]->nFilledLen = pBuffer[nOutputPortIndex]->nOffset;
                tDecOutput.pvPcmBuf = (OMX_PTR)(pBuffer[nOutputPortIndex]->pBuffer + pBuffer[nOutputPortIndex]->nOffset + TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) + TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE);
                tDecOutput.u4BufUsedByteSize = 0;
                tDecOutput.u4BufTotalByteSize = pBuffer[nOutputPortIndex]->nAllocLen - (pBuffer[nOutputPortIndex]->nOffset + TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) + TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE);
                memset(&(tDecOutput.ePcmInfo), 0, sizeof(TYPE1_DEC_PCM_INFO));
                u4InputBufConsumed = 0;
                u4IsDecInfoChg = 0;

                if (0 != omx_type1_decoder_component_Private->u4CompSideinfoCfg)
                {
                    if ((NULL != pBuffer[0]) && (pBuffer[0]->pInputPortPrivate))
                    {
                        u4AfifoDecReadPtr = (int)((OMX_U32*)pBuffer[0]->pInputPortPrivate) + pBuffer[0]->nOffset - tDecInput.u4BufByteSize;
                    }
                }
                LOGE("starting decode.....\n");
                if(i4_Times_before) {
                    atrace_begin("[omx_dtsxdec_component] decode 1st data");
                    i4_Times_before--;
                }

                static struct timespec dec_time_begin;
                clock_gettime(CLOCK_MONOTONIC, &dec_time_begin);

                u4DecActionIntfRet = ptDecActionIntf->decode(pvDecSelfData, &tDecInput, &tDecOutput, &u4InputBufConsumed, &u4IsDecInfoChg, &rDecNfyInfo);

                static struct timespec dec_time_end;
                clock_gettime(CLOCK_MONOTONIC, &dec_time_end);

                SNDBAR_LOGI_FILE (sndbar_dbg_cfg_latency_log_level, "[dtsxdec][dec] begin: %ld %ld end: %ld %ld, in: %ld out: %ld\n",
                                                         dec_time_begin.tv_sec, dec_time_begin.tv_nsec,
                                                         dec_time_end.tv_sec, dec_time_end.tv_nsec,
                                                         u4InputBufConsumed, tDecOutput.u4BufUsedByteSize);
                utils_check_time_too_long (&dec_time_begin, &dec_time_end, 20, "dtsxdec");

                sndbar_dbg_dump_record (&sndbar_dump_dtsxdec_in, tDecInput.pvBuf, u4InputBufConsumed);
                sndbar_dbg_dump_record (&sndbar_dump_dtsxdec_out, tDecOutput.pvPcmBuf, tDecOutput.u4BufUsedByteSize);

                SNDBAR_LOGT (sndbar_dbg_cfg_log_level, "[dtsxdec] output size: %ld, consumed: %ld (%ld)\n", tDecOutput.u4BufUsedByteSize, u4InputBufConsumed, tDecInput.u4BufByteSize);

                if ((0 != u4InputBufConsumed) && (0 == tDecOutput.ePcmInfo.u4SampleNumPerChannel))
                {
                    LOGE("decode error !\n");
                    if (OMX_TRUE == omx_type1_decoder_component_Private->eForceNfyDecInfoChg)
                    {
                        if (0 != tDecOutput.ePcmInfo.u4ChannelNum)
                        {
                            LOGE("decoder consumed %d byte update output info but not output pcm\n", (int)u4InputBufConsumed);
                            tDecOutput.ePcmInfo.u4SampleNumPerChannel = 64;
                            tDecOutput.u4BufUsedByteSize = tDecOutput.ePcmInfo.u4SampleNumPerChannel * tDecOutput.ePcmInfo.u4NeedBytesPerSample * tDecOutput.ePcmInfo.u4ChannelNum;
                        }

                        if (NULL != omx_type1_decoder_component_Private->fpDecInputDump)
                        {
                            fwrite((void *)(tDecInput.pvBuf), 1, u4InputBufConsumed, omx_type1_decoder_component_Private->fpDecInputDump);
                        }
                        if (NULL != omx_type1_decoder_component_Private->fpDecOutputDump)
                        {
                            fwrite(tDecOutput.pvPcmBuf, 1, tDecOutput.u4BufUsedByteSize, omx_type1_decoder_component_Private->fpDecOutputDump);
                        }
                        LOGE("update read ptr when decoder try decode at the begining.\n");
                        if (ptTmpInputBuf->nOffset > ptTmpInputBuf->nFilledLen)
                        {
                            LOGE("the input buffer meet error case! But continue try!\n");
                            LOGE("Maybe u4InputBufConsumed=%d > tDecInput.u4BufByteSize=%d. Need decoder owner check!\n", (int)u4InputBufConsumed, (int)tDecInput.u4BufByteSize);
                            ptTmpInputBuf->nOffset = ptTmpInputBuf->nFilledLen;
                        }
                        if ((ptTmpInputBuf->nOffset == ptTmpInputBuf->nFilledLen) && (OMX_BUFFERFLAG_EOS == (ptTmpInputBuf->nFlags & OMX_BUFFERFLAG_EOS)))
                        {
                            pBuffer[nOutputPortIndex]->nFlags |= OMX_BUFFERFLAG_EOS;
                            ptTmpInputBuf->nFlags ^= OMX_BUFFERFLAG_EOS;
                        }
                        if (0 == tDecOutput.ePcmInfo.u4ChannelNum)
                        {
                            ptTmpInputBuf->nOffset += u4InputBufConsumed;
                            LOGE("decoder consumed %d byte but not update output info\n", (int)u4InputBufConsumed);
                            continue;
                        }

                    }
                }
                LOGE("checking decode: u4InputBufConsumed = %d, u4SampleNumPerChannel = %d\n", u4InputBufConsumed, tDecOutput.ePcmInfo.u4SampleNumPerChannel);

                if (0 != u4DecActionIntfRet)
                {
                    LOGE("Error position, u4DecActionIntfRet=%d\n", (int)u4DecActionIntfRet);
                    omx_type1_decoder_component_Private->eIsIgnoreDecCurActionErr = OMX_FALSE;
                    (*(omx_type1_decoder_component_Private->callbacks->EventHandler))(openmaxStandComp,
                            omx_type1_decoder_component_Private->callbackData,
                            OMX_EventError,
                            OMX_ErrorDecoderActionIntfError,
                            0,
                            NULL);
                    tsem_down(&(omx_type1_decoder_component_Private->tEventCbSem));
                    if (omx_type1_decoder_component_Private->eIsIgnoreDecCurActionErr == OMX_FALSE) // need chg  ???
                    {
                        continue;
                    }
                }
                else
                {
                    LOGE("decode success...\n");
                    if(i4_Times_after) {
                        atrace_end("[omx_dtsxdec_component] decode 1st data");
                        i4_Times_after--;
                    }
                }
				if (!access("/tmp/dec_done.conf", 0))
				{
					FILE *mfp = NULL;
					mfp = fopen("/tmp/dec_done.pcm", "a+");
					fwrite(tDecOutput.pvPcmBuf, tDecOutput.u4BufUsedByteSize, 1, mfp);
					fclose(mfp);
                }

#if 1 // for debug
                if ( (u4InputBufConsumed != 0)
                    && rDecNfyInfo.fgDecNotify
                    && (omx_type1_decoder_component_Private->callbacks->EventHandler) != NULL)
                {
                    GST_INFO_DTSX info;
                    info.stream_type       = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.stream_type;
                    info.dts_comp_gain     = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_comp_gain;
                    info.dts_bitrate       = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_bitrate;
                    info.dts_detail_type   = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_detail_type;
                    info.dts_sample_rate   = rDecNfyInfo.rAudUpdateInfo.u4out_sample_Rate;
                    info.dts_stream_layout = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_stream_layout;
                    info.object_audio      = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.object_audio;
                    info.dts_dialog_avail  = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_dialog_avail;
                    info.dts_dialog_min    = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_dialog_min;
                    info.dts_dialog_max    = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_dialog_max;
                    info.dts_dialog_resolution = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_dialog_resolution;
                    info.dts_analog_compgain   = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.dts_analog_compgain;
                    info.dts_stream_ch_num = rDecNfyInfo.rAudUpdateInfo.u1stream_ch_num;
                    info.dts_stream_ch_mask = rDecNfyInfo.rAudUpdateInfo.u1stream_ch_mask;
                    info.eIsStreamHadT1ccFlag = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.eIsStreamHadT1ccFlag;
                    info.u4T1ccProcessMode = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.u4T1ccProcessMode;
                    info.u4T1ccState = rDecNfyInfo.rAudUpdateInfo.rCodecInfo.rDTSX.u4T1ccState;

#if 1 // for debug
                    printf ("[debug] dtsx callbackData:%p, callback:%p, stream_type:0x%x, analog_compgain:%d\n",
                        omx_type1_decoder_component_Private->callbackData,
                        omx_type1_decoder_component_Private->callbacks->EventHandler,
                        info.stream_type,
                        info.dts_analog_compgain);

                    printf ("[debug] dts_stream_ch_num:0x%x, dts_stream_ch_mask:0x%x, dts_dialog_avail:0x%x, dts_dialog_min:0x%x, dts_dialog_max:0x%x, dts_dialog_resolution:0x%x, t1cc(flag:%d,mode:%d,state:%d), dts_sample_rate:%d\n",
                        info.dts_stream_ch_num,
                        info.dts_stream_ch_mask,
                        info.dts_dialog_avail,
                        info.dts_dialog_min,
                        info.dts_dialog_max,
                        info.dts_dialog_resolution,
                        info.eIsStreamHadT1ccFlag,
                        info.u4T1ccProcessMode,
                        info.u4T1ccState,
                        info.dts_sample_rate);
#endif

                    (*(omx_type1_decoder_component_Private->callbacks->EventHandler))(openmaxStandComp,
                        omx_type1_decoder_component_Private->callbackData,
                        OMX_EventNotifyCodecInfo,
                        0,
                        0,
                        &info);
                }
#endif

                if ((u4InputBufConsumed != 0) && (0 != omx_type1_decoder_component_Private->u4CompSideinfoCfg) && (tDecOutput.ePcmInfo.u4SampleNumPerChannel != 0)) // need update sideinfo
                {
                    LOGE("Notify OMX_EventDecAskRefreshPTS\n");
                    pCallback = (OMX_ADAPTOR_CALLBACK_STRUCT*)(omx_type1_decoder_component_Private->callbackData);
                    pCallback->u4AfifoDecReadPtr = u4AfifoDecReadPtr;
                    (*(omx_type1_decoder_component_Private->callbacks->EventHandler))(openmaxStandComp,
                            omx_type1_decoder_component_Private->callbackData,
                            OMX_EventDecAskRefreshPTS,
                            OMX_DecoderAskRefreshAction,
                            0,
                            NULL);
                    if (omx_type1_decoder_component_Private->eIsCompFirstSideinfoUpdate)
                    {
                        omx_type1_decoder_component_Private->u4CompSideinfoFirstQueryPTS = pCallback->u4QueryPTS;
                    }
                    if ( !omx_type1_decoder_component_Private->eIsCompFirstSideinfoUpdate && ( (0 == pCallback->u4QueryPTS) || (omx_type1_decoder_component_Private->u4CompSideinfoPreQueryPTS == pCallback->u4QueryPTS)) )
                    {
                        pCallback->u4QueryPTS = omx_type1_decoder_component_Private->u4CompSideinfoPreQueryPTS + (OMX_U32)((OMX_U64)tDecOutput.ePcmInfo.u4SampleNumPerChannel * 45000 / tDecOutput.ePcmInfo.u4SampleRate);
                    }
                    else
                    {
                    }
                    omx_type1_decoder_component_Private->u4CompSideinfoPreQueryPTS = pCallback->u4QueryPTS;
                }

                {
                    ptDecOutputHdr->u4Version = TYPE1_DEC_OUTPUT_BUFFER_VERSION;
                    ptDecOutputHdr->u4Size = sizeof(type1_dec_output_header);
                    ptDecOutputHdr->u4Pcmattrnum = 1;
                    ptDecOutputHdr->ptPcmAttrArray = ptDecPcmAttr;

                    ptDecPcmAttr->u4Version = TYPE1_DEC_PCM_ATTR_VERSION;
                    ptDecPcmAttr->u4Size = sizeof(type1_dec_pcm_attr);
                    ptDecPcmAttr->pvPcmData = (OMX_PTR)(pBuffer[nOutputPortIndex]->pBuffer + pBuffer[nOutputPortIndex]->nOffset + TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) + TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE);

                    ptDecPcmAttr->u4SampleNumPerChannel = tDecOutput.ePcmInfo.u4SampleNumPerChannel;
                    ptDecPcmAttr->u4BitsPerSample = tDecOutput.ePcmInfo.u4BitsPerSample;
                    ptDecPcmAttr->u4NeedBytesPerSample = tDecOutput.ePcmInfo.u4NeedBytesPerSample;
                    ptDecPcmAttr->u4SampleIsLittleEnd = tDecOutput.ePcmInfo.u4SampleIsLittleEnd;
                    ptDecPcmAttr->eAccessMode = tDecOutput.ePcmInfo.eAccessMode;
                    ptDecPcmAttr->u4ChannelConfig0 = tDecOutput.ePcmInfo.u4ChannelConfig0;
                    ptDecPcmAttr->u4ChannelConfig1 = tDecOutput.ePcmInfo.u4ChannelConfig1;
                    ptDecPcmAttr->u4ChannelConfig2 = tDecOutput.ePcmInfo.u4ChannelConfig2;
                    ptDecPcmAttr->u4ChannelNum = tDecOutput.ePcmInfo.u4ChannelNum;
                    ptDecPcmAttr->u4SampleRate = tDecOutput.ePcmInfo.u4SampleRate;

                    if ((tDecOutput.ePcmInfo.u4ChannelNum && tDecOutput.ePcmInfo.u4SampleRate) &&
                        (gOutputPcmMode.nBitPerSample != tDecOutput.ePcmInfo.u4BitsPerSample ||
                         gOutputPcmMode.eEndian != tDecOutput.ePcmInfo.u4SampleIsLittleEnd ||
                         gOutputPcmMode.nChannels != tDecOutput.ePcmInfo.u4ChannelNum ||
                         gOutputPcmMode.nSamplingRate != tDecOutput.ePcmInfo.u4SampleRate))
                    {
                        gOutputPcmMode.nBitPerSample = tDecOutput.ePcmInfo.u4BitsPerSample;
                        gOutputPcmMode.eEndian = tDecOutput.ePcmInfo.u4SampleIsLittleEnd;
                        gOutputPcmMode.nChannels = tDecOutput.ePcmInfo.u4ChannelNum;
                        gOutputPcmMode.nSamplingRate = tDecOutput.ePcmInfo.u4SampleRate;

                        LOGE("nChannels[%d], nSamplingRate[%d]\n", gOutputPcmMode.nChannels, gOutputPcmMode.nSamplingRate);
                        (*(omx_type1_decoder_component_Private->callbacks->EventHandler))(openmaxStandComp, omx_type1_decoder_component_Private->callbackData, OMX_EventPortSettingsChanged, 1, 0, NULL);
                    }

                    if ((1 == u4IsDecInfoChg) || (OMX_TRUE == omx_type1_decoder_component_Private->eForceNfyDecInfoChg))
                    {
                        LOGE("MeetDecInfoChg u4IsDecInfoChg=%d eForceNfyDecInfoChg=%d!\n", (int)u4IsDecInfoChg, (int)omx_type1_decoder_component_Private->eForceNfyDecInfoChg);
                        ptDecOutputHdr->u4IsMeetDecInfoChg = 1;
                        if (1 == u4IsDecInfoChg)
                        {
                            u4IsDecInfoChg = 0;
                        }
                        if (OMX_TRUE == omx_type1_decoder_component_Private->eForceNfyDecInfoChg)
                        {
                            ptDecOutputHdr->u4Pcmattrnum = 1;
                        }
                    }
                    else
                    {
                        ptDecOutputHdr->u4IsMeetDecInfoChg = 0;
                    }

                    if (OMX_TRUE == omx_type1_decoder_component_Private->eNotResendData)
                    {
                        LOGE("eNotResendData case meet dec info change.\n");
                        omx_type1_decoder_component_Private->eForceNfyDecInfoChg = OMX_FALSE;
                        omx_type1_decoder_component_Private->eNotResendData = OMX_FALSE;
                        ptDecOutputHdr->u4IsMeetDecInfoChg = 1;
                        ptDecOutputHdr->u4Pcmattrnum = 1;
                    }

                    if (tDecOutput.u4BufUsedByteSize > tDecOutput.u4BufTotalByteSize)
                    {
                        LOGE("the input buffer meet error case! But continue try!\n");
                        LOGE("tDecOutput.u4BufUsedByteSize(%d) > tDecOutput.u4BufTotalByteSize(%d)!\n", (int)tDecOutput.u4BufUsedByteSize, (int)tDecOutput.u4BufTotalByteSize);
                        tDecOutput.u4BufUsedByteSize = tDecOutput.u4BufTotalByteSize;
                    }

                    if (tDecOutput.u4BufUsedByteSize != ptDecPcmAttr->u4SampleNumPerChannel * ptDecPcmAttr->u4NeedBytesPerSample * ptDecPcmAttr->u4ChannelNum)
                    {
                        LOGE("the output buffer meet error case! But continue try!\n");
                        LOGE("tDecOutput.u4BufUsedByteSize(%d) != u4SampleNumPerChannel(%d) * u4NeedBytesPerSample(%d) * u4ChannelNum(%d)! will use the little value!\n",
                             (int)tDecOutput.u4BufUsedByteSize, (int)ptDecPcmAttr->u4SampleNumPerChannel,
                             (int)ptDecPcmAttr->u4NeedBytesPerSample, (int)ptDecPcmAttr->u4ChannelNum);

                        if (tDecOutput.u4BufUsedByteSize > ptDecPcmAttr->u4SampleNumPerChannel * ptDecPcmAttr->u4NeedBytesPerSample * ptDecPcmAttr->u4ChannelNum)
                        {
                            tDecOutput.u4BufUsedByteSize = ptDecPcmAttr->u4SampleNumPerChannel * ptDecPcmAttr->u4NeedBytesPerSample * ptDecPcmAttr->u4ChannelNum;
                        }
                        else
                        {
                            ptDecPcmAttr->u4SampleNumPerChannel = tDecOutput.u4BufUsedByteSize / ptDecPcmAttr->u4NeedBytesPerSample / ptDecPcmAttr->u4ChannelNum;
                        }
                    }

                    pBuffer[nOutputPortIndex]->nFilledLen += tDecOutput.u4BufUsedByteSize;

                    if ((u4InputBufConsumed != 0) && (0 != omx_type1_decoder_component_Private->u4CompSideinfoCfg) && (tDecOutput.ePcmInfo.u4SampleNumPerChannel != 0)) // need update sideinfo
                    {
                        UINT32 u4SampleUpdateNum;
                        UINT32 u4UpdatePTS;
                        UINT32 u4CompSideinfoDecSize;
                        LOGE("Loop in u4CompSideinfoCfg processing...\n");
                        if (1 == omx_type1_decoder_component_Private->u4IsDecDownSampleOpen)
                        {
                            u4CompSideinfoDecSize = omx_type1_decoder_component_Private->u4CompSideinfoCfg * omx_type1_decoder_component_Private->u4DownsampleRatio;
                        }
                        else if (1 == omx_type1_decoder_component_Private->u4IsDecUpSampleOpen)
                        {
                            u4CompSideinfoDecSize = omx_type1_decoder_component_Private->u4CompSideinfoCfg / omx_type1_decoder_component_Private->u4UpsampleRatio;
                        }
                        else
                        {
                            u4CompSideinfoDecSize = omx_type1_decoder_component_Private->u4CompSideinfoCfg;
                        }
                        u4SampleUpdateNum = ptDecPcmAttr->u4SampleNumPerChannel + omx_type1_decoder_component_Private->u4CompSideinfoRemainSize;
                        while (u4SampleUpdateNum >= u4CompSideinfoDecSize || omx_type1_decoder_component_Private->eIsCompFirstSideinfoUpdate)
                        {
                            S_SIDEINFO tSideinfo;
                            OMX_PTR pvSideinfoFillAddr;
                            if (omx_type1_decoder_component_Private->eIsCompFirstSideinfoUpdate)
                            {
                                u4UpdatePTS = omx_type1_decoder_component_Private->u4CompSideinfoFirstQueryPTS;
                                LOGE("First u4QueryPTS=0x%x, update pts:0x%x, u4SideinfoNum:%d\n", (int)pCallback->u4QueryPTS, (int)u4UpdatePTS, (int)ptSideinfoAttr->u4SideinfoNum);
                                omx_type1_decoder_component_Private->eIsCompFirstSideinfoUpdate = FALSE;
                            }
                            else
                            {
                                u4UpdatePTS = pCallback->u4QueryPTS - (OMX_U32)((OMX_U64)omx_type1_decoder_component_Private->u4CompSideinfoRemainSize * 45000 / ptDecPcmAttr->u4SampleRate);
                                u4SampleUpdateNum -= u4CompSideinfoDecSize;
                                omx_type1_decoder_component_Private->u4CompSideinfoRemainSize = 0;
                                pCallback->u4QueryPTS += (OMX_U32)((OMX_U64)u4CompSideinfoDecSize * 45000 / ptDecPcmAttr->u4SampleRate);
                            }
                            memset(&tSideinfo, 0, sizeof(S_SIDEINFO));
                            tSideinfo.s_info.pts_stch = (u4UpdatePTS & 0xffff0000) >> 16;
                            tSideinfo.s_info.pts_stcl = (u4UpdatePTS & 0xffff);
                            ptDecOutputHdr->ptSideinfoAttrArray = ptSideinfoAttr;
                            ptSideinfoAttr->pvSideinfoData = (OMX_PTR)(pBuffer[nOutputPortIndex]->pBuffer + pBuffer[nOutputPortIndex]->nOffset);
                            if (ptSideinfoAttr->u4SideinfoNum > 5)
                            {
                                LOGE("sideinfo num abnormal:%d\n", (int)ptSideinfoAttr->u4SideinfoNum);
                            }
                            pvSideinfoFillAddr = ptSideinfoAttr->pvSideinfoData + ptSideinfoAttr->u4SideinfoNum * sizeof(S_SIDEINFO);
                            ptSideinfoAttr->u4SideinfoNum++;
                            memcpy(pvSideinfoFillAddr, &tSideinfo, sizeof(S_SIDEINFO));
                        }

                        omx_type1_decoder_component_Private->u4CompSideinfoRemainSize = u4SampleUpdateNum;
                    }

                    if (u4InputBufConsumed > 0)
                    {
                        LOGE("u4InputBufConsumed > 0\n");
                        {
                            if (NULL != omx_type1_decoder_component_Private->fpDecInputDump)
                            {
                                fwrite((void *)(tDecInput.pvBuf), 1, u4InputBufConsumed, omx_type1_decoder_component_Private->fpDecInputDump);
                            }
                            if (NULL != omx_type1_decoder_component_Private->fpDecOutputDump)
                            {
                                fwrite(tDecOutput.pvPcmBuf, 1, tDecOutput.u4BufUsedByteSize, omx_type1_decoder_component_Private->fpDecOutputDump);
                            }
                            ptTmpInputBuf->nOffset += u4InputBufConsumed;
                            if (ptTmpInputBuf->nOffset > ptTmpInputBuf->nFilledLen)
                            {
                                LOGE("the input buffer meet error case! But continue try!\n");
                                LOGE("Maybe u4InputBufConsumed=%d > tDecInput.u4BufByteSize=%d. Need decoder owner check!\n", (int)u4InputBufConsumed, (int)tDecInput.u4BufByteSize);
                                ptTmpInputBuf->nOffset = ptTmpInputBuf->nFilledLen;
                            }
                            if ((ptTmpInputBuf->nOffset == ptTmpInputBuf->nFilledLen) && (OMX_BUFFERFLAG_EOS == (ptTmpInputBuf->nFlags & OMX_BUFFERFLAG_EOS)))
                            {
                                pBuffer[nOutputPortIndex]->nFlags |= OMX_BUFFERFLAG_EOS;
                                ptTmpInputBuf->nFlags ^= OMX_BUFFERFLAG_EOS;
                            }
                        }
                    }
                    else
                    {
                        LOGE("Loop in EOS processing...\n");
                        if (ptDecOutputHdr->u4IsMeetDecInfoChg == 0 && (OMX_BUFFERFLAG_EOS == (ptTmpInputBuf->nFlags & OMX_BUFFERFLAG_EOS)))
                        {
                            LOGE("the input buffer has err raw data(=%d) before eos!\n", (int)(ptTmpInputBuf->nFilledLen - ptTmpInputBuf->nOffset));
                            pBuffer[nOutputPortIndex]->nFlags |= OMX_BUFFERFLAG_EOS;
                            ptDecOutputHdr->u4Pcmattrnum = 0;
                        }
                    }

                    if (OMX_TRUE == omx_type1_decoder_component_Private->eForceNfyDecInfoChg)
                    {
                        omx_type1_decoder_component_Private->eForceNfyDecInfoChg = OMX_FALSE;
                    }

                    if (omx_type1_decoder_component_Private->state == OMX_StatePause && !(checkAnyPortBeingFlushed(omx_type1_decoder_component_Private)))
                    {
                        LOGE("Waiting at paused state...\n");
                        tsem_wait(omx_type1_decoder_component_Private->bStateSem);
                    }

                    if (pBuffer[nOutputPortIndex]->nFilledLen != 0 || (pBuffer[nOutputPortIndex]->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
                    {
                        LOGE("Returning output buffer, nFilledLen[%d], noffset[%d]\n", pBuffer[nOutputPortIndex]->nFilledLen, pBuffer[nOutputPortIndex]->nOffset);

                        pBuffer[nOutputPortIndex]->nFilledLen -= pBuffer[nOutputPortIndex]->nOffset;
                        pBuffer[nOutputPortIndex]->nOffset += TYPE1_MAX_SIDEINFO_NUM * sizeof(S_SIDEINFO) + TYPE1_DECODER_COMP_OUTPUT_BUF_ALIGNED_SAMPLE_BYTE_SIZE;

                        pPort[nOutputPortIndex]->ReturnBufferFunction(pPort[nOutputPortIndex], pBuffer[nOutputPortIndex]);
                        pBuffer[nOutputPortIndex] = NULL;
                        isBufferNeeded[nOutputPortIndex] = OMX_TRUE;
                    }
                }
            }
            else
            {
                if (NULL != pBuffer[0] && (0 == pBuffer[0]->nFilledLen) && (OMX_BUFFERFLAG_EOS == (pBuffer[0]->nFlags & OMX_BUFFERFLAG_EOS)))
                {
                    pBuffer[nOutputPortIndex]->nFlags |= OMX_BUFFERFLAG_EOS;
                    pBuffer[nOutputPortIndex]->nFilledLen = 0;
                    LOGE("Returning output buffer 2\n");
                    pPort[nOutputPortIndex]->ReturnBufferFunction(pPort[nOutputPortIndex], pBuffer[nOutputPortIndex]);
                    pBuffer[nOutputPortIndex] = NULL;
                    isBufferNeeded[nOutputPortIndex] = OMX_TRUE;
                }
                else
                {
                    LOGE("meet error!\n");
                }
            }
        }
        else
        {
            LOGE("maybe output buffer not enable!!\n");
        }

        if (omx_type1_decoder_component_Private->state == OMX_StatePause && !(checkAnyPortBeingFlushed(omx_type1_decoder_component_Private)))
        {
            LOGE("Waiting at paused state...\n");
            tsem_wait(omx_type1_decoder_component_Private->bStateSem);
        }

        if (NULL != pBuffer[0])
        {
            if ((0 == pBuffer[0]->nFilledLen) && PORT_IS_ENABLED(pPort[0]))
            {
                LOGE("Returning intput buffer...\n");
                pPort[0]->ReturnBufferFunction(pPort[0], pBuffer[0]);
                pBuffer[0] = NULL;
                isBufferNeeded[0] = OMX_TRUE;
            }
        }
    }
    return NULL;
}

