#ifndef		AVSCODEC_H
#define		AVSCODEC_H

#include	<windows.h> 

#ifndef		AVSAPI
#define 	AVSAPI 		extern "C"	__declspec (dllexport)
#endif

#define	HCODEC	void*

//Encode Level 0:900 fps, 1:600 fps on P4 3.2G
#define Encode_fast             0
#define Encode_slow             1

//DeBlocking Level
#define DBF_NONE                0
#define DBF_Y                   1
#define DBF_YUV                 2
#define DBF_Adaptive_Y          3

//////////////////////////////////////////
//  Flags to acquire codec
//////////////////////////////////////////
#define AVS_COMPRESS            0x00000001
#define AVS_DECOMPRESS          0x00000002
#define AVS_SOLO                0x00000004
#define AVS_SUBNAIL             0x00000008
#define AVS_ULTRAHEADER         0x00000010		// Ultra bitstream header
#define AVS_JPGINVERSE          0x00000020		// MJPG transform to IJPG

//////////////////////////////////////////
//  Flags to compress/decompress
//////////////////////////////////////////
#define AVS_KEYFRAME            0x00000001
#define AVS_HURRYUP             0x00000002

//////////////////////////////////////////
//  Flags to UltraHeader
//////////////////////////////////////////
#define AVS_FIELDMERGE          0x00000001		// Merge Odd/Even field to one frame

//////////////////////////////////////////
//	nMode of ipcd_downscale_info
//////////////////////////////////////////
#define FLAG_RES_FULL           0x00000000
#define FLAG_RES_HALF           0x00000001		// 1/2 * 1/2 original size
#define FLAG_RES_QUARTER        0x00000002		// 1/4 * 1/4 original size
#define FLAG_RES_AUTO           0x00000003		// Downscale resolution depend on input size

//////////////////////////////////////////
#define	FOURCC_RGB15            MAKEFOURCC( 'R', 'G', 'B', '2' )
#define	FOURCC_RGB24            MAKEFOURCC( 'R', 'G', 'B', '3' )
#define	FOURCC_YVU9             MAKEFOURCC( 'Y', 'V', 'U', '9' )
#define	FOURCC_I420             MAKEFOURCC( 'I', '4', '2', '0' )
#define	FOURCC_YUY2             MAKEFOURCC( 'Y', 'U', 'Y', '2' )
#define	FOURCC_YV12             MAKEFOURCC( 'Y', 'V', '1', '2' )

#define	FOURCC_IJPEG            MAKEFOURCC( 'I', 'J', 'P', 'G' )
#define	FOURCC_MotionJPEG       MAKEFOURCC( 'M', 'J', 'P', 'G' )
#define FOURCC_MXPEG            MAKEFOURCC( 'M', 'X', 'P', 'G' )
#define	FOURCC_MPEG4V2          MAKEFOURCC( 'M', 'P', '4', '2' )
#define	FOURCC_XVID             MAKEFOURCC( 'X', 'V', 'I', 'D' )
#define	FOURCC_Indeo50          MAKEFOURCC( 'I', 'V', '5', '0' )
#define	FOURCC_H264             MAKEFOURCC( 'H', '2', '6', '4' )

#define FOURCC_MPEG4ULTRA       MAKEFOURCC( 'M', 'P', '4', 'U' )
#define FOURCC_H264ULTRA        MAKEFOURCC( '2', '6', '4', 'U' )
#define FOURCC_MJPEGULTRA       MAKEFOURCC( 'J', 'P', 'G', 'U' )
#define FOURCC_IJPEGULTRA       MAKEFOURCC( 'I', 'P', 'G', 'U' ) 
#define FOURCC_MXPEGULTRA       MAKEFOURCC( 'X', 'P', 'G', 'U' )

#define FOURCC_MPEG4SOLO        MAKEFOURCC( 'M', 'P', '4', 'S' )
#define FOURCC_H264SOLO         MAKEFOURCC( '2', '6', '4', 'S' )


typedef	struct	{
	DWORD	Size;
	LPSTR	CodecName;		    // Read-Only
	DWORD	PixelFormat;	
	DWORD	biWidth; 
	DWORD  	biHeight; 
	WORD   	biBitCount;
	int 	QFactor;		    // Compress-Only
	int     gop;                // Compress-Only
	DWORD	nEncodeLevel;		// Compress-Only
	DWORD	nDeBlockLevel;		// Decompress-Only
	DWORD   dwCryptionKeyPublic;		// Encryption key, 0 if no encryption	
	DWORD   dwCryptionKeyPrivate;		// Encryption private key
	LPBYTE  pattern;			// Watermark pattern
	BYTE	wm_ratio;			// Check correct watermark ratio in one frame
	BYTE	unShieldKeyPublic;	// Shield public key
	BYTE	unShieldKeyPrivate;	// Shield private key
	BYTE	nReserve[1];		// Read-Only
} CODEC_PARAM;


typedef struct	{
	int					size;					// Structure size

	/**
	 version 1: decoder shield
	 version 2: remove decoder shield
	 version 3: multi-shield
	*/
	BYTE				version;				

	/**
	 version 1 & 2: 
		Shield width and Shield height
	*/
	unsigned __int16	shield_width;
	unsigned __int16	shield_height;

	/**
	 version 1 & 2: 
		Shield start point x and y
	 version 3:
		shield_startpoint_x: First two bytes of multi-shield array address
		shield_startpoint_y: Last two bytes of multi-shield array address

		shield_startpoint_x: Indicate I/P frame 0: P-frame, 1: I-frame
	*/
	unsigned __int16	shield_startpoint_x;
	unsigned __int16	shield_startpoint_y;


	BYTE				shield_key;				// shield Key

	/**
	 version 3:
		Element Numbers in a row and a column of MultiShield Array
	*/
	unsigned __int16	shield_array_width;
	unsigned __int16	shield_array_height;

	/**
	 version 4:
		Hardware bitstream watermark
	*/
	DWORD		HWBS_watermark;	// Hardware bitstream (4-Bytes)

	/**
	version 4:
		Flags:
		AVS_FIELDMERGE			0x00000001
	*/
	DWORD		flags;

	/**
	version 5:
		From this version, AP start to support HW watermark, multi shield
		in H264, JPEG and IPCam stream.
		otherwise, software encoder start to support remove shield (HWBS_watermark = 0)
	*/

} UltraHeader;


typedef struct {
	int			nSize;				// Structure size
	BYTE		Version;
	int			nMode;				// DownScale Mode: 0->Full, 1->1/2, 2->1/4, 3->AUTO
	int			nPreviewWidth;		// Width of tha AP preview rect
	int			nPreviewHeight;		// Height of tha AP preview rect
	int			nFrameWidth;		// Width of the actual frame
	int			nFrameHeight;		// Height of the actual frame
	DWORD		Reserve1;
} ipcd_downscale_info;


typedef	enum	{
	AVSCODEC_OK = 0,
	AVSCODEC_FAILED,
	AVSCODEC_OUT_OF_MEMORY,
	AVSCODEC_NOT_SUPPORTED,
	AVSCODEC_HARDWARE_NOT_FOUND,
	AVSCODEC_HARDWARE_INITIAL_ERROR,
	AVSCODEC_INVALID_HANDLE,
	AVSCODEC_INVALID_PARAMETER,
	AVSCODEC_INVALID_SERIAL_NUMBER,
	AVSCODEC_INPUT_OUT_OF_RANGE,
	AVSCODEC_CANCELED_BY_USER,
	AVSCODEC_FRAME_NOT_READY,
	AVSCODEC_FRAME_EXHAUSTED,
	AVSCODEC_BUFFER_OVERRUN,
	AVSCODEC_NO_SIGNAL,
	AVSCODEC_STREAMSTILLRUNNING,
	// AVI Module
	AVSCODEC_CANTOPENAVIFILE,
	AVSCODEC_CANTCREATESTREAM,
	AVSCODEC_CANTMAKECOMPRESSION,
	AVSCODEC_CANTSETFORMAT,
	AVSCODEC_FAILEDTOWRITEFRAME,
	// CODEC Module
	AVSCODEC_NO_CODEC_FOUND,
	AVSCODEC_BAD_FORMAT,
	AVSCODEC_DECRYPTION_OK,
	AVSCODEC_NEED_CRYPTION_KEY,
	AVSCODEC_WRONG_CRYPTION_KEY,
	AVSCODEC_END_OF_STREAM,
	AVSCODEC_DECODE_VOLHEADER,
	AVSCODEC_SHIELD_OK,
	AVSCODEC_NEED_SHIELD_KEY,
	AVSCODEC_WRONG_SHIELD_KEY,
	AVSCODEC_DECODE_NOT_RETURN_NOPICTURE,	// Ray add
	AVSCODEC_TOTAL
} AVSCODEC;


typedef bool	( WINAPI *AVS_ENUMCODEC)( LPSTR CodecName, LPVOID pData );

#ifdef	__cplusplus
extern	"C"	{
#endif	

AVSAPI	AVSCODEC	AVS_CodecInit( LPSTR RegKey = 0, LPSTR PluginFolder = 0 );
AVSAPI	AVSCODEC	AVS_CodecClose();

AVSAPI	DWORD		AVS_EnumCodec( AVS_ENUMCODEC pCallback, LPVOID pData );

AVSAPI	HCODEC		AVS_AcquireCodec4CC( DWORD FourCC, DWORD flags = AVS_COMPRESS );
AVSAPI	HCODEC		AVS_AcquireCodec( LPCSTR CodecName, DWORD flags = AVS_COMPRESS );
AVSAPI	AVSCODEC	AVS_ReleaseCodec( HCODEC );

AVSAPI	AVSCODEC	AVS_GetParam( HCODEC, CODEC_PARAM* );
AVSAPI	AVSCODEC	AVS_SetParam( HCODEC, CODEC_PARAM* );
AVSAPI	AVSCODEC	AVS_SetDownscaleStatus( HCODEC, void* ); // (handle,ipcd_downscale_info)

AVSAPI	AVSCODEC	AVS_EncodeStart( HCODEC );
AVSAPI	AVSCODEC	AVS_EncodeFrameEx( HCODEC, LPBYTE, LPBYTE, LPRECT, DWORD *size, DWORD* );
AVSAPI	AVSCODEC	AVS_EncodeFrame( HCODEC, LPBYTE, LPBYTE, DWORD *size, DWORD* );
AVSAPI	AVSCODEC	AVS_EncodeEnd( HCODEC );

AVSAPI	AVSCODEC	AVS_DecodeStart( HCODEC );
AVSAPI	AVSCODEC	AVS_DecodeFrame( HCODEC, LPBYTE, LPBYTE, DWORD *size, DWORD* );
AVSAPI	AVSCODEC	AVS_DecodeEnd( HCODEC );

AVSAPI	WORD		AVS_GetPixelFormats( HCODEC, LPDWORD, WORD );

AVSAPI	DWORD		AVS_GetFourCC( HCODEC );
AVSAPI	DWORD		AVS_GenCrypKey( const char * pszMessage, DWORD* pdwPublicKey); //2005.12.7

#ifdef	__cplusplus
}
#endif

#endif	//	AVSCODEC_H
