/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author$
 * $Date$
 * $RCSfile: dmx_mm_if.h,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file dmx_mm_if.h
 *  Interface of demux driver
 */


#ifndef DMX_MM_IF_H
#define DMX_MM_IF_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#include "x_lint.h"

LINT_EXT_HEADER_BEGIN

#include "dmx_if.h"

#ifndef CC_SECURE_WORLD
#include "mpv_drvif.h"
#endif

#include "x_timer.h"

LINT_EXT_HEADER_END


//-----------------------------------------------------------------------------
// Configurations
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------
/// PVR Play
#define PVRPLAY_FLAGS_BUFFER               0x00000001
#define PVRPLAY_FLAGS_TIMESTAMP            0x00000002
#define PVRPLAY_FLAGS_THRESHOLD            0x00000004
#define PVRPLAY_FLAGS_CALLBACK             0x00000008
#define PVRPLAY_FLAGS_MODE                 0x00000010
#define PVRPLAY_FLAGS_REMUX_DIRECTION      0x00000020
#define PVRPLAY_FLAGS_ALL                  0xFFFFFFFF
#define PVRPLAY_FLAGS_NONE                 0x00000000

#define DMX_MM_STRUCT_NUM                  DMX_NUM_PID_INDEX

/// Multi-media
#define DMX_MM_FLAG_NONE                    0x00000000
#define DMX_MM_FLAG_VALID                   0x00000001
#define DMX_MM_FLAG_TYPE                    0x00000002
#define DMX_MM_FLAG_BUF                     0x00000004
#define DMX_MM_FLAG_SEARCH_START_CODE       0x00000008
#define DMX_MM_FLAG_NOTIFY                  0x00000020
#define DMX_MM_FLAG_DEVICE_ID               0x00000040
#define DMX_MM_FLAG_COMPLETE_MSG            0x00000080
#define DMX_MM_FLAG_INSTANCE_TAG            0x00008000  /* DMX_PID_FLAG_INSTANCE_TAG */
#define DMX_MM_FLAG_RPU						0x00010000
#define DMX_MM_FLAG_ALL                     0xFFFFFFFF

/// DRM
#define DMX_MM_DRM_FLAG_OFFSET              0x00000001
#define DMX_MM_DRM_FLAG_ENCRYLEN            0x00000002
#define DMX_MM_DRM_FLAG_CBC                 0x00000004
#define DMX_MM_DRM_FLAG_KEY                 0x00000008
#define DMX_MM_DRM_FLAG_ENCRYPT             0x00000010
#define DMX_MM_DRM_FLAG_NONE                0x00000000
#define DMX_MM_DRM_FLAG_ALL                 0xFFFFFFFF
#define DMX_MM_DRM_FLAG_SAMPLE_ID           0x00000010
#define DMX_MM_DRM_FLAG_CHUNK_LEN           0x00000020

#define DMX_AUDIO_HANDLER_NULL_PIDX         0xFF

#define DMX_MAX_INSTANCE                    2   // TS, PS max instance

#define DMX_PS_MOVE_DATA_Q_SIZE     40
#define DMX_PS_MOVE_DATA_Q_PIDX     35
#define DMX_PS_STRUCT_NUM           16

//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------

typedef struct
{
    BOOL fgEnable;                  ///< En/Dis-able (see DMX_PID_FLAG_VALID)
    BOOL fgAllocateBuffer;          ///< Allocate buffer
    BOOL fgEnableSsidFilter;        ///< Enable substream_id filtering (see DMX_PID_FLAG_SUBSTREAM_ID)
    UINT8  u1KeyIndex;              ///< Index of the scrambling key
    UINT8  u1StreamID;              ///< Stream ID
    UINT8  u1SubstreamID;           ///< Substream ID
    UPTR u4BufAddr;               ///< Buffer address
    UPTR u4BufSize;               ///< Buffer size
    UPTR u4Rp;                    ///< Read pointer
    UPTR u4Wp;                    ///< Write pointer
    UPTR u4PeakBufFull;           ///< Peak fullness of the buffer, to
                                    ///< estimate the required ES FIFO size
    DMX_PID_TYPE_T  ePidType;       ///< Type of data (PSI, Video, Audio, etc.)
    DMX_DESC_MODE_T eDescMode;      ///< Descrambling mode
    PFN_DMX_NOTIFY pfnNotify;       ///< Callback function
    void*          pvNotifyTag;     ///< Tag value of callback function
    PFN_DMX_NOTIFY pfnScramble;     ///< Callback function of scramble state
    void*          pvScrambleTag;   ///< Tag value of scramble callback function

    void *pvInstanceTag;            ///< Tag for supporting multiple instances (used only by v-dec)
    UINT8 u1ChannelId;
    UINT8 u1DeviceId;
} DMX_PS_T;


typedef struct
{
    BOOL fgEnable;                  ///< En/Dis-able (see DMX_PID_FLAG_VALID)
    BOOL fgAllocateBuffer;          ///< Allocate buffer
    UINT8  u1KeyIndex;              ///< Index of the scrambling key
    UPTR u4BufAddr;               ///< Buffer address
    USIZE u4BufSize;               ///< Buffer size
    UPTR u4Rp;                    ///< Read pointer
    UPTR u4Wp;                    ///< Write pointer
    UPTR u4PeakBufFull;           ///< Peak fullness of the buffer, to
                                    ///< estimate the required ES FIFO size
    DMX_PID_TYPE_T  ePidType;       ///< Type of data (PSI, Video, Audio, etc.)
    DMX_DESC_MODE_T eDescMode;      ///< Descrambling mode
    PFN_DMX_NOTIFY pfnNotify;       ///< Callback function
    void*          pvNotifyTag;     ///< Tag value of callback function
    PFN_DMX_NOTIFY pfnScramble;     ///< Callback function of scramble state
    void*          pvScrambleTag;   ///< Tag value of scramble callback function

    void *pvInstanceTag;            ///< Tag for supporting multiple instances (used only by v-dec)
    UINT8 u1ChannelId;
    UINT8 u1DeviceId;
    BOOL fgSendCompleteMsg;
    BOOL fgDvEn;
} DMX_ES_T;


/// DRM mode
typedef enum
{
    DMX_DRM_MODE_BYPASS,
    DMX_DRM_MODE_AES,
    DMX_DRM_MODE_AES_OFB,
    DMX_DRM_MODE_AES_SCTE52,
    DMX_DRM_MODE_ND,
    DMX_DRM_MODE_PD,
    DMX_DRM_MODE_AES_ENCRYPTION,
#ifdef DMX_SUPPORT_CPRM
    DMX_DRM_MODE_CPRM_C2D,
    DMX_DRM_MODE_CPRM_C2E,
    DMX_DRM_MODE_CPRM_C2G,
    DMX_DRM_MODE_CPRM_C2DCBC,
#endif // DMX_SUPPORT_CPRM
    DMX_DRM_MODE_UNKNOWN
} DMX_DRM_MODE_T;

typedef struct
{
    BOOL fgCBC;
    UINT8 au1IV[16];
    UINT32 u4KeyBitLen;
    UINT8 au1Key[32];
    UINT32 u4Offset;
    UINT32 u4EncryLen;
    BOOL fgEncrypt;
    UINT32 u4ChunkLen;
    UINT8 au1SampleID[8];
} DMX_MM_DRM_AES_T;

#if defined(DMX_SUPPORT_PDDRM) || defined(CC_DMX_EMULATION)
typedef struct
{
    UPTR u4ContectKeyAddr;
    UINT32 u4ContectKeyLen;
    UINT32 u4ChunkLen;
    UINT32 u4EncryLen;
} DMX_MM_DRM_PD_T;
#endif

//---------------------------------------------------------------------
/// DDI
//---------------------------------------------------------------------
typedef enum
{
    DDI_EVENT_TRANSFER_OK,
    DDI_EVENT_TRANSFER_FAILED
} DDI_EVENT_CODE_T;

typedef BOOL (*PFN_DDI_NOTIFY)(DDI_EVENT_CODE_T);

#define DMX_DDI_FLAG_NONE               0x00000000
#define DMX_DDI_FLAG_MODE               0x00000001      // Set Mode
#define DMX_DDI_FLAG_ALLOCBUF           0x00000002      // Allocate Buffer
#define DMX_DDI_FLAG_CALLBACK           0x00000004      // Set/Get callback
#define DMX_DDI_FLAG_RATE               0x00000008      // Set/Get rate (M/N)
#define DMX_DDI_FLAG_DATA_SIZE          0x00000010      // Get data size in DDI
#define DMX_DDI_FLAG_DEBUG_INFO         0x00001000      // Get debug info
#define DMX_DDI_FLAG_ALL                0xFFFFFFFF

typedef enum
{
    DMX_DDI_PORT_FRAMER0,        // to Demux framer 0
    DMX_DDI_PORT_FRAMER1,
    DMX_DDI_PORT_FRAMER2,
    DMX_DDI_PORT_FRAMER3,
    DMX_DDI_PORT_FRAMER2_BYPASS,
    DMX_DDI_PORT_FRAMER3_BYPASS,
    DMX_DDI_PORT_FRAMER4_BYPASS  // for new dbmport4.
} DMX_DDI_PORT_T;

typedef enum
{
    DMX_DDI_MODE_SINGLE,        // Move a single chunk of data
    DMX_DDI_MODE_STREAM,        // Streaming data may have several chunks
    DMX_DDI_MODE_NONBLOCKING    // Non-blocking DDI DMA operation
} DMX_DDI_MODE_T;

typedef enum
{
    DMX_DDI_STOP,               // DMA is de-activated (in the Stop state)
    DMX_DDI_PLAY                // DMA is activated (in the Play state)
} DMX_DDI_STATE_T;

typedef struct
{
    DMX_DDI_STATE_T eState;         // internal DDI state
    UPTR u4Rp;                    // Read pointer
    UPTR u4Rip;                   // Read Initial pointer
    UPTR u4Wp;                    // Write pointer
    UPTR u4Ap;                    // Alert pointer
    UPTR u4BufStart;              // starting address of DDI buffer
    UPTR u4BufEnd;                // end address of DDI buffer
    USIZE u4TransferredSize;       // transferred data size
}DMX_DDI_DEBUG_T;

typedef struct
{
    DMX_DDI_MODE_T eMode;   // Single mode or Stream mode
    BOOL fgAllocBuf;
    UPTR u4BufAddr;
    USIZE u4BufSize;
    USIZE u4Threshold;     // INT when buffer is decreased to this value
    USIZE u4DataSize;      // how much data is in the DDI buffer
    UINT32 u4RateN;         // rate = (N / M)  Mbits/sec
    UINT32 u4RateM;         // rate = (N / M)  Mbits/sec
    PFN_DDI_NOTIFY pfnDDINotify;
                            // The callback needs to return FALSE if error.
                            // Otherwise, return TRUE.
    DMX_DDI_DEBUG_T rDebugInfo;     // DDI debug info
} DMX_DDI_T;

typedef enum
{
	DDI_DATA_TYPE_DEFAULT,
	DDI_DATA_TYPE_TLV,
	DDI_DATA_TYPE_ALP,
}DMX_DDI_DATA_TYPE;

typedef struct
{
    UINT8 u1TsIdx;
    UPTR u4BufStart;
    UPTR u4BufEnd;
    UPTR u4Addr;
    USIZE u4Size;
    USIZE u4SkipLen;
    BOOL    fgIommu;
    UINT32  u4MmuTblAddr;
    DMX_DDI_DATA_TYPE eType;
    UINT8   u1DataHeader[DMX_MM_SIGNATURE_DATA_SIZE+1];
}DMX_DDI_MOVE_PARAM_T;
//---------------------------------------------------------------------
/// Multi-media
//---------------------------------------------------------------------

typedef struct
{
    BOOL fgEnable;

    BOOL fgSearchStartCode;
    DMX_PID_TYPE_T ePidType;
    PFN_DMX_NOTIFY pfnCallback;

    BOOL fgAllocBuf;
    UPTR u4BufAddr;
    USIZE u4BufSize;
    UPTR u4Rp;
    UPTR u4Wp;
    void *pvInstanceTag;    // Tag for supporting multiple instances (used only by v-dec)
    UINT8 u1ChannelId;
    UINT8 u1DeviceId;
    BOOL fgSendCompleteMsg;
    BOOL fgDvEn;
} DMX_MM_T;

typedef struct
{
    UINT8 u1Idx;
    UPTR u4BufStart;
    UPTR u4BufEnd;
    UPTR u4StartAddr;
    USIZE u4FrameSize;     // the data size to be transferred in a transaction
                            // For WMV, it's the size of a segment, not of a frame.
    USIZE u4SikpLen;
    UINT32 u4Pts;
    UINT32 u4Dts;

    BOOL fgEOS;             // End of stream
    BOOL fgFrameHead;       // Is a chunk the frame head? (for WMV/TS/PS/ES)
    BOOL fgIgnoreData;
    BOOL fgMoveComplete;
    BOOL fgTrigger;         // Set the Trigger (for NDDRM)
#ifdef DMX_SUPPORT_PDDRM
    BOOL fgPDDRM;
#endif
	BOOL fgNDDRM;
    HAL_TIME_T rTimeHwS;
    UINT32 u4ContainerInfo;
    BOOL fgHDRInfo;
    UINT64 u8TsPicPos;
    BOOL    fgIommuEnable;         //IOMMU Enable or Disable
    UINT32  u4MmuTblAddr;
    UINT8   u1DataHeader[DMX_MM_SIGNATURE_DATA_SIZE+1];
} DMX_MM_DATA_T;

typedef struct
{
    BOOL fgUsed;
    UINT8 u1CmdIndex;

    UINT8 u1Idx;
    UINT8 u1StreamID;
    UPTR u4BufStart;
    UPTR u4BufEnd;
    UPTR u4StartAddr;
    USIZE u4FrameSize;     // the data size to be transferred in a transaction
                            // For WMV, it's the size of a segment, not of a frame.
    UINT32 u4Pts;
    UINT32 u4Dts;

    //BOOL fgEOS;             // End of stream
    //BOOL fgFrameHead;       // Is a chunk the frame head? (for WMV/TS/PS/ES)

    UINT16 u2SkipLen[DMX_PS_MOVE_DATA_Q_SIZE];
    UINT16 u2PayloadLen[DMX_PS_MOVE_DATA_Q_SIZE];
    UPTR u4PayloadEndAddr[DMX_PS_MOVE_DATA_Q_SIZE];

    UINT32 u4TimeOut;
} DMX_PS_MOVEDATA_CMD_T;

typedef struct
{
    PFN_DMX_SEND_VIDEO_PES pfnSendVideoPes;     ///< Send video PES
    PFN_DMX_UPDATE_WP pfnUpdateVideoWp;         ///< Update video WP
    PFN_DMX_SEND_AUDIO_PES pfnSendAudioPes;     ///< Send audio PES
} DMX_MM_DECODER_CALLBACKS_T;

//---------------------------------------------------------------------
/// Program Stream
//---------------------------------------------------------------------
#if 0
/// PID types
typedef enum
{
    DMX_PS_STREAM_TYPE_NONE = 0,      ///< None
    DMX_PS_STREAM_TYPE_AUDIO,
    DMX_PS_STREAM_TYPE_VIDEO,
    DMX_PS_STREAM_TYPE_OTHER          ///
} DMX_PS_STREAM_TYPE_T;

typedef struct
{
    BOOL fgEnable;                  ///< Enable or disable
    BOOL fgAllocateBuffer;          ///< Allocate buffer
    UINT8 u1StreamID;               ///< Stream ID
    UINT32 u4BufAddr;               ///< Buffer address
    UINT32 u4BufSize;               ///< Buffer size
    DMX_PS_STREAM_TYPE_T eStreamType;  ///< Stream type
} DMX_PS_STREAM_T;
#endif

//---------------------------------------------------------------------
/// PVR play
//---------------------------------------------------------------------
typedef enum
{
    DMX_PVRPLAY_PORT_FRAMER0,       // TS index: 0
    DMX_PVRPLAY_PORT_FRAMER1,       // TS index: 1
    DMX_PVRPLAY_PORT_FRAMER2,       // TS index: 2
    DMX_PVRPLAY_PORT_FRAMER3,       // TS index: 3
    DMX_PVRPLAY_PORT_FRAMER2_BYPASS,// TS index: 2 bypass
    DMX_PVRPLAY_PORT_FRAMER3_BYPASS, // TS index: 3 bypass
	DMX_PVRPLAY_PORT_FRAMER4_BYPASS, // TS index: 4
	DMX_PVRPLAY_PORT_DBM,
    DMX_PVRPLAY_PORT_TSOUT
} DMX_PVRPLAY_PORT_T;

typedef enum
{
    DMX_PVRPLAY_STATE_STOP,
    DMX_PVRPLAY_STATE_PLAYING
} DMX_PVR_PLAYSTATE_T;

typedef enum
{
    DMX_PVR_PLAY_STREAM,
    DMX_PVR_PLAY_SINGLEMOVE
} DMX_PVR_PLAYMODE_T;


typedef BOOL (*PFN_DMX_PVR_NOTIFY)(UPTR u4Addr, USIZE u4Size);

typedef struct
{
    DMX_PVR_PLAYSTATE_T eState;
    BOOL fgAllocBuf;
    USIZE u4BufSize;
    UPTR u4BufStart;
    UPTR u4BufEnd;
    UPTR u4Wp;
    UPTR u4Rp;
    USIZE u4ThresholdSize;

    UINT8 *pu1Prolog;
    UINT8 *pu1Epilog;
    UINT8 u1PacketSize;
    UINT8 u1PrevSyncOffset;
    UINT8 u1SyncOffset;
    UINT32 u4PrologSize;    // _u1PacketSize * PVR_PROLOG_PACKETS
    UINT32 u4EpilogSize;
    
    BOOL fgIgnoreTimeStamp;
    BOOL fgContainTimeStamp;
    BOOL fg32BitMmu;
    BOOL fg64BitMmu;
    UINT16 u2TimeStampFreqDiv;

    DMX_PVR_PLAYMODE_T eMode;

    PFN_DMX_PVR_NOTIFY pfnPVRNotify;
	BOOL fgRemuxDirection;
} DMX_PVR_PLAY_T;

typedef struct
{
    UPTR u4HwRp;
    UPTR u4HwWp;
    UPTR u4SwRp;
    UPTR u4SwWp;
} DMX_PVRPLAY_BUFPTR_T;

typedef struct
{
    UPTR u4Rp;
    UPTR u4Wp;
} DMX_PVRPLAY_PTR_T;

//---------------------------------------------------------------------
/// DTCP
//---------------------------------------------------------------------
typedef struct
{
    USIZE u4Size;

    UPTR u4SrcBufStart;
    UPTR u4SrcBufEnd;
    UPTR u4SrcStart;

    UPTR u4DstBufStart;
    UPTR u4DstBufEnd;
    UPTR u4DstStart;
} DMX_DTCP_DATA_T;

typedef struct
{
    USIZE u4Size;
    UPTR u4SrcAddr;
    UPTR u4DstAddr;
} DMX_DTCP_BLKDATA_T;

typedef struct
{
    USIZE u4Size;

    UPTR u4SrcBufStart;
    UPTR u4SrcBufEnd;
    UPTR u4SrcStart;

    UPTR u4DstBufStart;
    UPTR u4DstBufEnd;
    UPTR u4DstStart;
} DMX_AES_DATA_T;

typedef struct
{
    USIZE u4Size;
    UPTR u4SrcAddr;
    UPTR u4DstAddr;
} DMX_AES_BLKDATA_T;

typedef struct
{
    BOOL fgUseTimestamp;
    UINT32 u4SingleCount;
    UINT32 u4SingleSize;
    UINT32 u4SingleCheck;
    UINT32 u4MoveCount;
    UINT32 u4MoveSize;
    UINT32 u4MoveCheck;
    UINT32 u4ShiftingCount;
    UINT32 u4DataSize;
} DMX_PVRPLAY_COUNTER_T;

//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Prototype  of inter-file functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Prototype  of public functions
//-----------------------------------------------------------------------------

//---------------------------------------------------------------------
/// PVR
//---------------------------------------------------------------------
EXTERN UPTR Dmx_PVRPlay_GetBufStart(UINT8 u1TsOutIdx);
EXTERN UPTR Dmx_PVRPlay_GetBufEnd(UINT8 u1TsOutIdx);
EXTERN UPTR Dmx_PVRPlay_GetBufRp(UINT8 u1TsOutIdx);
EXTERN UPTR Dmx_PVRPlay_GetBufWp(UINT8 u1TsOutIdx);
EXTERN VOID Dmx_PVRPlay_SetBufStart(UINT8 u1TsOutIdx, UPTR ptr);
EXTERN VOID Dmx_PVRPlay_SetBufEnd(UINT8 u1TsOutIdx, UPTR ptr);
EXTERN VOID Dmx_PVRPlay_SetBufRp(UINT8 u1TsOutIdx, UPTR ptr);
EXTERN VOID Dmx_PVRPlay_SetBufWp(UINT8 u1TsOutIdx, UPTR ptr);
EXTERN VOID Dmx_PVRPlay_SetThreshHold(UINT8 u1TsOutIdx, UINT32 u4Size);
EXTERN BOOL DMX_PVRPlay_SetDBMTestPid(void);
EXTERN BOOL DMX_PVRPlay_FreeDBMTestPid(void);
EXTERN BOOL DMX_PVRPlay_Start(void);
EXTERN BOOL DMX_PVRPlay_Stop(BOOL fgForce);
EXTERN BOOL DMX_PVRPlay_Pause(DMX_PVRPLAY_PTR_T *prPtr);
EXTERN BOOL DMX_PVRPlay_Resume(DMX_PVRPLAY_PTR_T *prPtr);
EXTERN VOID DMX_PVRPlay_Reset(void);
EXTERN BOOL DMX_PVRPlay_GetTimeStamp(UINT8 u1TsOutIdx, UINT32 *pu4RetLocalStamp);
EXTERN DMX_PVR_PLAYSTATE_T DMX_PVRPlay_GetState(void);
EXTERN BOOL DMX_PVRPlay_Set(UINT32 u4Flags, const DMX_PVR_PLAY_T* prPVRPlay);
EXTERN BOOL DMX_PVRPlay_Get(UINT32 u4Flags, DMX_PVR_PLAY_T* prPVRPlay);
EXTERN BOOL DMX_PVRPlay_UpdateWp(UPTR u4Addr, USIZE u4Size);
EXTERN BOOL DMX_PVRPlay_FreeBuf(void);
EXTERN BOOL DMX_PVRPlay_FlushBuf(void);
EXTERN BOOL DMX_PVRPlay_SingleMove(const DMX_MM_DATA_T* prData);
EXTERN BOOL DMX_PVRPlay_TSMoveData(UINT8 u1TsOutIdx, DMX_MM_DATA_T* prData);
EXTERN BOOL DMX_PVRPlay_GetBufPointer(DMX_PVRPLAY_BUFPTR_T *prPtr);
EXTERN BOOL DMX_PVRPlay_SetBuffer(UPTR u4BufStart, UPTR u4BufEnd,
                                  UPTR u4Wp, UPTR u4Rp);
EXTERN BOOL DMX_PVRPlay_RequestReset(void);
EXTERN BOOL DMX_PVRPlay_SetUseDescramble(BOOL fgEnable);

EXTERN void DMX_PVRPlay_GetCounter(DMX_PVRPLAY_COUNTER_T *prCounter);
EXTERN void DMX_PVRPlay_ResetCounter(void);
EXTERN BOOL DMX_PVRPlay_SetPort(DMX_PVRPLAY_PORT_T ePort);
EXTERN BOOL DMX_PVRPlay_SetPortEx2(UINT8 u1TsOutIdx, DMX_PVRPLAY_PORT_T ePort);

EXTERN BOOL DMX_PVRPlay_SendNullPackets(void);
EXTERN BOOL DMX_OpenTimeshift(BOOL fgOpen);



//New

EXTERN BOOL DMX_PVRPlay_StartEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_PVRPlay_StopEx(UINT8 u1TsOutIdx, BOOL fgForce);
EXTERN BOOL DMX_PVRPlay_PauseEx(UINT8 u1TsOutIdx, DMX_PVRPLAY_PTR_T *prPtr);
EXTERN BOOL DMX_PVRPlay_ResumeEx(UINT8 u1TsOutIdx, DMX_PVRPLAY_PTR_T *prPtr);
EXTERN VOID DMX_PVRPlay_ResetEx(UINT8 u1TsOutIdx);
EXTERN DMX_PVR_PLAYSTATE_T DMX_PVRPlay_GetStateEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_PVRPlay_SetEx(UINT8 u1TsOutIdx, UINT32 u4Flags, const DMX_PVR_PLAY_T* prPVRPlay);
EXTERN BOOL DMX_PVRPlay_GetEx(UINT8 u1TsOutIdx,UINT32 u4Flags, DMX_PVR_PLAY_T* prPVRPlay);
EXTERN BOOL DMX_PVRPlay_UpdateWpEx(UINT8 u1TsOutIdx, UPTR u4Addr, USIZE u4Size);
EXTERN BOOL DMX_PVRPlay_FreeBufEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_PVRPlay_FlushBufEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_PVRPlay_SingleMoveEx(UINT8 u1TsOutIdx, const DMX_MM_DATA_T* prData);
EXTERN BOOL DMX_PVRPlay_GetBufPointerEx(UINT8 u1TsOutIdx, DMX_PVRPLAY_BUFPTR_T *prPtr);
EXTERN BOOL DMX_PVRPlay_SetBufferEx(UINT8 u1TsOutIdx, UPTR u4BufStart, UPTR u4BufEnd, UPTR u4Wp, UPTR u4Rp);
EXTERN BOOL DMX_PVRPlay_RequestResetEx(UINT8 u1TsOutIdx);
EXTERN void DMX_PVRPlay_GetCounterEx(UINT8 u1TsOutIdx, DMX_PVRPLAY_COUNTER_T *prCounter);
EXTERN void DMX_PVRPlay_ResetCounterEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_PVRPlay_SetPortEx(UINT8 u1PvrIdx, UINT8 u1TsIdx, UINT8 u1Pidx, 
                            DMX_PVRPLAY_PORT_T ePort, BOOL fgIsTs, BOOL fgIsOutput);
EXTERN BOOL DMX_PVRPlay_SendNullPacketsEx(UINT8 u1TsOutIdx);
EXTERN BOOL DMX_OpenTimeshiftEx(UINT8 u1TsOutIdx, BOOL fgOpen);


//---------------------------------------------------------------------
/// DDI
//---------------------------------------------------------------------
EXTERN BOOL DMX_DDI_Init(void);
EXTERN BOOL DMX_DDI_Set(UINT32 u4Flags, const DMX_DDI_T *prDDI);
EXTERN BOOL DMX_DDI_Get(UINT32 u4Flags, DMX_DDI_T *prDDI);
EXTERN BOOL DMX_DDI_Free(void);

EXTERN BOOL DMX_DDI_FlushBuf(void);
EXTERN USIZE DMX_DDI_GetFreeBufSize(UINT8 u1Inst);
EXTERN BOOL DMX_DDI_SetPacketSize(UINT8 u1PacketSize);
EXTERN BOOL DMX_DDI_SetSyncOffset(UINT8 u1Inst, UINT8 u1Offset);
EXTERN BOOL DMX_DDI_SingleMove(UINT8 u1TsIdx, UPTR u4BufStart, UPTR u4BufEnd,
                               UPTR u4Addr, USIZE u4Size, USIZE u4SkipLen);
EXTERN BOOL DMX_DDI_PowerDown(VOID);
EXTERN BOOL DMX_DDI_130byteEnable(BOOL fgEnable, UINT8 u1PktSize);
EXTERN BOOL DMX_DDI_SendEos(UINT8 u1TsIdx);
EXTERN BOOL DMX_DDI_FillBuf(UPTR u4DataAddr, USIZE u4DataSize, USIZE *pu4FilledSize);
EXTERN BOOL DMX_DDI_StreamStart(void);
EXTERN BOOL DMX_DDI_StreamStop(void);

//---------------------------------------------------------------------
/// Program Stream
//---------------------------------------------------------------------
EXTERN BOOL DMX_PS_SetStream(UINT8 u1Pidx, UINT32 u4Flags, const DMX_PS_T *prPs);
EXTERN BOOL DMX_PS_GetStream(UINT8 u1Pidx, UINT32 u4Flags, DMX_PS_T *prPs);
EXTERN BOOL DMX_PS_FreeStream(UINT8 u1Pidx);
EXTERN BOOL DMX_PS_DetectStreamID(BOOL fgDetect, UINT16 u2Pairs, UINT32 u4Len);
EXTERN BOOL DMX_PS_SetAudioType(UINT8 u1Pidx, DMX_AUDIO_TYPE_T eAudioType);
EXTERN DMX_AUDIO_TYPE_T DMX_PS_GetAudioType(UINT8 u1Pidx);
EXTERN BOOL DMX_PS_SetDataFormat(UINT8 u1Inst, DMX_DATA_FORMAT_T eDataFormat);
EXTERN DMX_DATA_FORMAT_T DMX_PS_GetDataFormat(UINT8 u1Inst);
EXTERN BOOL DMX_PS_SetHDCPKeyIv(UINT8 u1Inst, UINT8 *pu1Key, UINT8 *pu1Iv);

//---------------------------------------------------------------------
/// Elementary Stream
//---------------------------------------------------------------------
EXTERN BOOL DMX_ES_SetPid(UINT8 u1Pidx, UINT32 u4Flags, const DMX_ES_T *prPs);
EXTERN BOOL DMX_ES_GetPid(UINT8 u1Pidx, UINT32 u4Flags, DMX_ES_T *prPs);
EXTERN BOOL DMX_ES_FreePid(UINT8 u1Pidx);
EXTERN BOOL DMX_ES_SetFileLength(UINT8 u1Pidx, UINT32 u4Len);
EXTERN void DMX_ES_SetMoveIndex(UINT8 u1Idx);

//---------------------------------------------------------------------
/// Multi-media
//---------------------------------------------------------------------
EXTERN BOOL DMX_MM_Init(void);
EXTERN BOOL DMX_MM_Set(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_T *prMMStruct);
EXTERN BOOL DMX_MM_Get(UINT8 u1Idx, UINT32 u4Flags, DMX_MM_T *prMMStruct);
EXTERN BOOL DMX_MM_Free(UINT8 u1Idx);

EXTERN VOID DMX_MM_SetSearchStartCode(BOOL fgEnable);
EXTERN BOOL DMX_MM_GetSearchStartCode(VOID);

EXTERN BOOL DMX_MM_SetDRMMode(UINT8 u1Idx, DMX_DRM_MODE_T eMode);
EXTERN DMX_DRM_MODE_T DMX_MM_GetDRMMode(UINT8 u1Idx);
EXTERN BOOL DMX_MM_SetAES(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_MM_SetSecureAES(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM, BOOL fgReload);

EXTERN BOOL DMX_MM_UnlockBuffer(UINT8 u1Idx, UINT8 u1SerialNumber, USIZE u4Size,
                                UPTR u4FrameAddr);
EXTERN BOOL DMX_MM_GetBuffer(UINT8 u1Idx, UINT8 u1SerialNumber, UPTR u4FrameAddr,
                    USIZE u4SkipSize, USIZE u4CopySize, UCHAR* pu1Dest);
EXTERN BOOL DMX_MM_FlushBuffer(UINT8 u1Idx);
EXTERN BOOL DMX_MM_AllocateBuffer(UINT8 u1Idx, USIZE u4Size);
EXTERN BOOL DMX_MM_FreeBuffer(UINT8 u1Idx);
EXTERN BOOL DMX_MM_SendAudioChunk(UINT8 u1Pidx, UPTR u4Wp, UINT32 u4Pts, BOOL fgEOS);
EXTERN UINT8 DMX_MM_GetEnabledPidIndex(DMX_INPUT_TYPE_T eInputType, DMX_PID_TYPE_T ePidType);

//---------------------------------------------------------------------
/// DTCP
//---------------------------------------------------------------------
EXTERN void DMX_DTCP_SetFormat(DMX_INPUT_TYPE_T eInputType);
EXTERN BOOL DMX_DTCP_Set(void);
EXTERN BOOL DMX_DTCP_Free(void);
EXTERN BOOL DMX_DTCP_SetAES(UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_DTCP_MoveData(const DMX_DTCP_DATA_T *prData);
EXTERN BOOL DMX_DTCP_MoveBlockData(const DMX_DTCP_BLKDATA_T *prData);

EXTERN BOOL DMX_AES_SetDecryptInfo(UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_AES_MoveData(const DMX_AES_DATA_T *prData);
EXTERN BOOL DMX_AES_MoveBlockData(const DMX_AES_BLKDATA_T *prBlkData);

EXTERN UINT8 DMX_AES_AllocEngine(void);
EXTERN BOOL DMX_AES_FreeEngine(UINT8 u1Idx);
EXTERN BOOL DMX_AES_SetDecryptInfoEx(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_AES_MoveBlockDataEx(UINT8 u1Idx, const DMX_AES_BLKDATA_T *prBlkData);

EXTERN BOOL DMX_Marlin_SetDecryptInfo(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_Marlin_MoveData(UINT8 u1Idx, const DMX_DTCP_DATA_T *prData);

//---------------------------------------------------------------------
/// ND-DRM
//---------------------------------------------------------------------
EXTERN BOOL DMX_MM_SetNDDRM(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_AES_T *prDRM);
EXTERN BOOL DMX_NDDRM_MoveData(UINT8 u1Idx, const DMX_MM_DATA_T *prData, UINT32 u4TimeOut);

#ifdef DMX_SUPPORT_PDDRM
EXTERN BOOL DMX_MM_SetPDDRM(UINT8 u1Idx, UINT32 u4Flags, const DMX_MM_DRM_PD_T *prDRM);
EXTERN BOOL DMX_PDDRM_Decrypt(UINT8 u1Idx, const DMX_MM_DATA_T *prData);
#endif

//---------------------------------------------------------------------
/// DMX AUDIO HANDLER
//---------------------------------------------------------------------
#ifdef CC_DMX_AUDIO_PREBUF
EXTERN BOOL DMX_AudHandler_SetActivePidx(UINT8 u1Idx);
EXTERN BOOL DMX_AudHandler_SetActivePidxEx(UINT8 u1Idx, UINT8* pu1Buf, USIZE u4Size);
EXTERN BOOL DMX_AudHandler_Set(UINT8 u1Idx, BOOL fgToDec);
EXTERN BOOL DMX_AudHandler_Free(UINT8 u1Idx);
EXTERN BOOL DMX_AudHandler_SeekAndUpdate(UINT8 u1Idx, UINT32 u4Pts, UINT32 *pu4Pts);
EXTERN void DMX_AudHandler_SetEnable(BOOL fgEnable);
EXTERN BOOL DMX_AudHandler_SetQSize(UINT8 u1Idx, UINT16 u2Size);
#endif

//---------------------------------------------------------------------
/// DMX Multiple instance
//---------------------------------------------------------------------
EXTERN void DMX_MUL_EnableMultipleInst(BOOL fgEnable);
EXTERN UINT8 DMX_MUL_GetAvailableInst(DMX_CONN_TYPE_T eConnType);
EXTERN UINT8 DMX_MUL_GetInstByConnType(DMX_CONN_TYPE_T eConnType);
EXTERN BOOL DMX_MUL_FreeInst(UINT8 u1Inst);
EXTERN UINT8 DMX_MUL_GetPidxInstId(UINT8 u1Pidx);
EXTERN BOOL DMX_MUL_SetInstType(UINT8 u1Inst, DMX_INPUT_TYPE_T eInputType);
EXTERN BOOL DMX_MUL_EnableEcp(UINT8 u1Inst, BOOL fgEcpEnable);
EXTERN BOOL DMX_MUL_GetEcp(UINT8 u1Inst);
EXTERN DMX_INPUT_TYPE_T DMX_MUL_GetInstType(UINT8 u1Inst);
EXTERN UINT8 DMX_MUL_GetAvailableFilter(UINT8 u1Inst);
EXTERN UINT8 DMX_MUL_GetAvailablePidx(UINT8 u1Inst);
EXTERN BOOL DMX_MUL_SetTSIdx(UINT8 u1Inst);
EXTERN UINT8 DMX_MUL_GetTSIdx(UINT8 u1Inst);
EXTERN BOOL DMX_MUL_SetSubtitlePidx(UINT8 u1Inst, UINT8 u1Pidx);
EXTERN UINT8 DMX_MUL_GetSubtitlePidx(UINT8 u1Inst);
EXTERN BOOL DMX_MUL_SetPidxInstance(UINT8 u1Inst, UINT8 u1Pidx);
EXTERN BOOL DMX_MUL_FreePidx(UINT8 u1Pidx);
EXTERN BOOL DMX_MUL_FreeFilter(UINT8 u1FilterIndex);
EXTERN BOOL DMX_MUL_MoveData(UINT8 u1Id, DMX_MM_DATA_T *prData);
EXTERN BOOL DMX_MUL_RequestReset(UINT8 u1Id);
EXTERN USIZE DMX_MUL_GetEmptySize(UINT8 u1Inst, DMX_PID_TYPE_T eType, UINT8 u1Pidx);
EXTERN USIZE DMX_MUL_GetMinFreeDRAMBufferSize(UINT8 u1Inst, DMX_PID_TYPE_T eType, UINT8 u1Pidx);
EXTERN BOOL DMX_MUL_SetDecoderCallbacks(UINT8 u1Inst, const DMX_DECODER_CALLBACKS_T* prCallbacks);
EXTERN BOOL DMX_MUL_SetVideoType(UINT8 u1Inst, DMX_VIDEO_TYPE_T eVideoType);
EXTERN BOOL DMX_MUL_ForceToFreeVdec0(BOOL fgEnable);
EXTERN BOOL DMX_MUL_ForceToFreePCR(BOOL fgEnable);
EXTERN BOOL DMX_MUL_SetFifoOutput(UINT8 u1Inst, DMX_PID_TYPE_T ePidType, UINT8 u1ChannelId, BOOL fgEnable);
EXTERN BOOL DMX_MUL_GetMulPidInfo(UINT8 u1Pidx, DMX_MUL_PIDINFO_T* prMulPid);
EXTERN BOOL DMX_MUL_GetMulFilterInfo(UINT8 u1FilterIdx, DMX_MUL_FILTER_INFO_T* prMulFilter);
EXTERN BOOL DMX_MUL_GetMulInstInfo(UINT8 u1InstId, DMX_MUL_INSTINFO_T* prMulInst);
EXTERN UINT8 DMX_MUL_GetTsIdx(UINT8 u1Inst);
EXTERN UINT8 DMX_MUL_GetDtvInstFromTsIdx(UINT8 u1TsIdx);
#endif  // DMX_MM_IF_H

