#ifndef __ADAPTOR_CORE_KERNEL_H__
#define __ADAPTOR_CORE_KERNEL_H__

#include "OMX_Core.h"
#include "OMX_Component.h"
#include "OMX_Types.h"
#include "OMX_Audio.h"
#include "queue.h"
#include "pthread.h"
#include "tsemaphore.h"
#include "omx_dec_comp_intf.h"
#include "ctrl_adaptor_intf.h"
#include "adaptor_cli_intf.h"

#define ADAPTOR_SUPPORT_MULTI_DECODER_NUM    3
#define AUD_ADAPTOR_COMP_CMD_QUEUE_SIZE    32
#define AUD_ADAPTOR_CHECK_FRAME_BYTE_SIZE    256

typedef enum DEC_ADAPTOR_PLAYBACE_STATE_MACHINE_TYPE
{
    DEC_ADAPTOR_PLAYBACE_STATE_DecStoppedUnLoaded = 0,
    DEC_ADAPTOR_PLAYBACE_STATE_DecLoadingIniting,
    DEC_ADAPTOR_PLAYBACE_STATE_DecLoadedInited,
    DEC_ADAPTOR_PLAYBACE_STATE_DecPlayPrepare,
    DEC_ADAPTOR_PLAYBACE_STATE_DecPlaying,
    DEC_ADAPTOR_PLAYBACE_STATE_DecWaitingAVD,
    DEC_ADAPTOR_PLAYBACE_STATE_DecFlushing,
    DEC_ADAPTOR_PLAYBACE_STATE_DecFlushed,
    DEC_ADAPTOR_PLAYBACE_STATE_DecStopping,
    DEC_ADAPTOR_PLAYBACE_STATE_Error = 0x7FFFFFFF,
}DEC_ADAPTOR_PLAYBACE_STATE_MACHINE_TYPE;

typedef enum DEC_ADAPTOR_PLAYBACE_CMD_TYPE
{
    DEC_ADAPTOR_PLAYBACE_CMD_Unknown = 0,
    DEC_ADAPTOR_PLAYBACE_CMD_Load,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_Play,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_DecInfoChgNfy,    // come from decoder
    DEC_ADAPTOR_PLAYBACE_CMD_DecOutputBufFullNfy,    // come from adaptor
    DEC_ADAPTOR_PLAYBACE_CMD_SetSYSInfo,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_StartDecoding,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_Stop,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_StopDoneNfy,    // come from dec decoder
    DEC_ADAPTOR_PLAYBACE_CMD_Flush,    // come from dec mngr
    DEC_ADAPTOR_PLAYBACE_CMD_FlushDoneNfy,    // come from decoder
}DEC_ADAPTOR_PLAYBACE_CMD_TYPE;

typedef struct DEC_ADAPTOR_PCM_INFO_STRUCT
{
    OMX_U32 u4SampleNumPerChannel;
    OMX_U32 u4BitsPerSample;
    OMX_U32 u4NeedBytesPerSample;
    OMX_U32 u4SampleIsLittleEnd;
    pcm_access_mode eAccessMode;

}DEC_ADAPTOR_PCM_INFO_STRUCT;

typedef struct DEC_ADAPTOR_CALLBACK_STRUCT
{
    void *pAdaptComp;
    UINT32 u4AfifoDecReadPtr;
    UINT32 u4QueryPTS;
    AUD_DEC_UPDATE_INFO rDecUpdateInfo;
}DEC_ADAPTOR_CALLBACK_STRUCT;

typedef struct DEC_ADAPTOR_COMP_STRUCT
{
    //Decoder ctrl
    OMX_HANDLETYPE hDecOmxCompHandle;
    AUD_DEC_FMT_T eDecFmtId;
    AUD_DEC_ATMOS_DECODER_TYPE_T eAtmosFmt;
    UINT16 u2CompId;
    HANDLE_T tAptCompThdHdl;

    queue_t tAptCompCmdQueue;
    tsem_t tAptCompCmdQueueSem;

    tsem_t tDecMngrWaitAdapActionSem;
    INT32 i4DecMngrWaitAdapActionRet;

    tsem_t tAptCompOmxSem;
    OMX_BOOL isInPortDisabled;
    OMX_BOOL isOutPortDisabled;
    OMX_CALLBACKTYPE tOmxCallback;
    OMX_BUFFERHEADERTYPE *ptOmxInBuffer;
    OMX_BUFFERHEADERTYPE *ptOmxOutBuffer;
    INT32 (*pfAudDecMngrCallback)(UINT16 u2CompId, AUD_DEC_EVENT_T eEvent, VOID *pInfo);
    AUD_DEC_OUTPUT_BUF_T *ptAudDecMngrOutputBuf;
    AUD_DEC_AFIFO_T *ptAudDecMngrAfifo;

    //Decoder static state && capability
    OMX_BOOL eIsKnownMaxFrameSize;
    OMX_U32 u4DecFrameByteSizeMin;
    OMX_U32 u4DecFrameByteSizeMax;
    OMX_U32 u4DecFrameSizeMinMustDividedBy;
    OMX_BOOL eIsDecSupportSpeed;
    COMMON_DEC_SPEED_TYPE eDecSpeedType;

    //Decoder dynamic state
    DEC_ADAPTOR_PLAYBACE_STATE_MACHINE_TYPE eDecLastMachineState;
    DEC_ADAPTOR_PLAYBACE_STATE_MACHINE_TYPE eDecMachineState;
    OMX_BOOL isWaitingInfoChg;
    OMX_BOOL isFlushCmdSent;
    OMX_BOOL isStopCmdSent;
    OMX_BOOL isWaitingFlushDone;
    OMX_BOOL isStartDecodingCmdComingFirst;
    OMX_BOOL isNoDecOutputBufFullNfyAction;
    OMX_U32 u4DecBitrate;
    OMX_U32 u4DecSampleRate;
    OMX_U32 u4DecodedFramesNum;
    OMX_U32 u4DecodedSamplesNum;
    OMX_U32 u4SkipErrFramesNum;
    OMX_U32 u4OutputZeroErrFramesNum;
    OMX_BOOL eDecErrNeedAbort;
    char ai1DecErrReasonStr[128];

    OMX_U32 u4CallbackData;
    DEC_ADAPTOR_CALLBACK_STRUCT AdaptCallback;

    //Decoder info struct (get)
    COMMON_DEC_CHANNEL_LAYOUT_PARAM tDecChLayout;
    COMMON_DEC_PCM_OUTPUT_INFO_PARAM tDecPcmOutputInfo;
    //AUD_DEC_OUTPUT_T tDecOutputInfo;

    //sys info (set)
    //AUD_DEC_REQUEST_INFO_T tDecReqInfo;
    OMX_BOOL eIsDecReqSdRawOutput;
    OMX_BOOL eIsDecReqHdRawOutput;
    COMMON_DEC_SPK_CONFIG_PARAM tDecSpkcfg;
    OMX_U32 u4AudDownSampleRatio;
    OMX_U32 u4AudUpSampleRatio;
    OMX_U32 u4AudSideinfoCfg;
    OMX_U32 u4AudSpeedRatio;

    //debug
    AUD_DEC_ADAPTOR_CLI_MAIN_T *ptAudDecAdaptCliMain;
    FILE *pfAdaptInputDump;
    FILE *pfAdaptOutputDump;
    OMX_S32 i4InputUnderRunCnt;
    OMX_S32 i4OutputUnderRunCnt;
    OMX_U32 u4GetInputByteSize;
    OMX_U32 u4GetOutputByteSize;
    OMX_U32 i4InputBufferDropCnt;
    OMX_U32 i4OutPutBufferDropCnt;

    OMX_U32 pts_cur_pnt;        // pts_cur_pnt: decoder updated afifo read ptr
    OMX_U32 pts_pnt_previous;   // pts_pnt_previous: previous pts_cur_pnt
    OMX_U32 pts_last_prev_pnt;  // pts_last_prev_pnt: previous pts_pnt_previous
    OMX_U32 pts_prs_pnt;        // pts_prs_pnt: pts queue kept AU SA
    OMX_U32 pts_loop_cnt;
    OMX_U32 pts_loop_cnt_pre;
}DEC_ADAPTOR_COMP_STRUCT;

typedef struct DEC_ADAPTOR_MAIN_STRUCT
{
    AUD_DEC_ADAPTOR_TRIGGER_PARAM_STRUCT tAdaptorTriggerParam;
    DEC_ADAPTOR_COMP_STRUCT atDecAdaptorComp[ADAPTOR_SUPPORT_MULTI_DECODER_NUM];
}DEC_ADAPTOR_MAIN_STRUCT;

typedef struct DEC_ADAPTOR_AU_STRUCT
{
    UINT32 u4SA;
    UINT32 u4LoopCnt;
    UINT32 u4PTSL;
    UINT32 u4PTSH;
}DEC_ADAPTOR_AU_STRUCT;

OMX_ERRORTYPE AdaptorOmxDecEventHandler(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_EVENTTYPE eEvent,
                                        OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData);
OMX_ERRORTYPE AdaptorOmxDecEmptyBufferDone(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE* pBuffer);
OMX_ERRORTYPE AdaptorOmxDecFillBufferDone(OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_BUFFERHEADERTYPE* pBuffer);
INT32 i4AdaptorStoppedUnLoadedStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorLoadingInitingStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorLoadedInitedStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorPlayPrepareStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
static AUDIO_SAMPLING_T eAdap2MngrSampleRate(OMX_U32 u4DecSampleRate);
static UINT8 u1ChannelConfig2Cfg(UINT16 u2ChannelConfig0, UINT16 u2ChannelConfig1);
static AUDIO_BITSTREAM_TYPE_T tAudFmt2BitstreamType(AUD_DEC_FMT_T eAudFmt);
INT32 i4AdaptorPlayingStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorWaitingAVDStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorFlushingStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorFlushedStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
INT32 i4AdaptorStopingStateDo(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);
VOID vAudAdaptorMainThread(VOID *pArg);

INT32 i4AdaptorSetDecDropSample(DEC_ADAPTOR_COMP_STRUCT *pCurAdaptorComp);

#endif

