/**
 * @file IDVP2420EncSDK.h DVP2420 Encoding SDK header file
 *
 * @author Ellis Huang
 *
 */

#pragma once

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the DVP2420ENCSDK_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// DVP2420ENCSDK_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef DVP2420ENCSDK_EXPORTS
#define DVP2420ENCSDK_API __declspec(dllexport)
#else
#define DVP2420ENCSDK_API __declspec(dllimport)
#endif

typedef enum
{
	ENC_SUCCEEDED		= 1,
	ENC_FAILED			= 0,
	ENC_SDKINITFAILED	= -1,
	ENC_DEVINITFAILED	= -2,
	ENC_PARAMERROR		= -3,
	ENC_CHNUMERROR		= -4
} EncRes;

/**
 * The Stream Read Callback function structure
 */
typedef struct
{
	void (*PSTREAMREADOPEN)(int nChNum);	///< The pointer of the Stream Read Open Callback function. This callback function is called when the stream read process starts.
	void (*PSTREAMREADPROC)(int nChNum, BYTE *pStreamBuf, UINT32 nBytesToTransfer, BOOL bIFrame, UINT32 nIFrameOffset);	///< The pointer of the Stream Read Process Callback function. This callback function is called when the stream is read.
	void (*PSTREAMREADCLOSE)(int nChNum);	///< The pointer of the Stream Read Close Callback function. This callback function is called when the stream read process finishes.
}STREAMREAD_STRUCT;

typedef void (*PMOTIONDETECTPROC)(int nChNum, int nRegionNum, unsigned short mbCount);	///< The Motion Detect Process Callback function. This callback function is called when there are the motions being detected in the specified video region.
typedef void (*PENCFAILPROC)(int nChNum);	///< The Encoding Failed Process Callback function. This callback function is called when encoding process fails.

/**
 * The region structure of the motion detect.
 */
typedef struct {
	int enable;	///< Used to enable/disable motion detection.
	int left;	///< Define the left most macroblock number of the horizontal coordinates of the region.
	int right;	///< Define the right most macroblock number of the horizontal coordinates of the region.
	int top;	///< Define the top most macroblock number of the horizontal coordinates of the region.
	int bottom;	///< Define the bottom most macroblock number of the horizontal coordinates of the region.
}MDRegion;

/**
 * @brief IDVP2420EncSDK declaration
 *
 * IDVP2420EncSDK : About the implement, please refelence DVP2420EncSDK.cpp.
 *
 */
class DVP2420ENCSDK_API IDVP2420EncSDK {
public:

	/**
	* @brief This function creates SDK instance.
	*
	* @param pp A pointer to the SDK instance.
	*
	* @return If function succeeded, function returns ENC_SUCCEEDED.
	*/
	virtual int DVP2420_CreateEncSDKInstence(void **pp);

	/**
	 * @brief This function initializes the SDK. This function must be called before other functions of the SDK.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_InitSDK() PURE;

	/**
	 * @brief This function closes up the SDK.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_CloseSDK() PURE;

	/**
	 * @brief This function initializes the chip on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_InitChips(int nChNum) PURE;

	/**
	 * @brief This function releases the chip on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_ReleaseChips(int nChNum) PURE;

	/**
	 * @brief This function gets the number of the chips. Two firmware files boot.sre and pscodec.sre will be used 
	 *		  by the library. Notes: Don't download the firmware into the chip when the decoding process is running in the chip.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_DownloadFW(int nChNum) PURE;

	/**
	 * @brief This function gets the number of the chips.
	 *
	 * @param pChipCnt An integer pointer to store the returned number of the chips.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int	DVP2420_GetChipCount(int *pChipCnt) PURE;

	/**
	 * @brief This function gets the version of the SDK.
	 *
	 * @return If function succeeded, funtion returns the version of the SDK. Otherwise, function returns -1.
     */
	virtual float DVP2420_GetSDKVersion() PURE;

	/**
	 * @brief This function starts to encode the video on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StartEncode(int nChNum) PURE;

	/**
	 * @brief This function stops to encode the video on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StopEncode(int nChNum) PURE;

	/**
	 * @brief This function starts to preview the video on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param hWnd A windows handle for display area.
	 * @param nFrameRate A value to set display frame rate of specified channel.
	 * @param bDisableAudio Specifies if to preview without the audio.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StartPreview(int nChNum, HWND hWnd, int nFrameRate, BOOL bDisableAudio = FALSE) PURE;

	/**
	 * @brief This function stops to preview the video on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StopPreview(int nChNum) PURE;

	/**
	 * @brief This function starts the motion detection on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StartMotionDetect(int nChNum) PURE;

	/**
	 * @brief This function stops the motion detection on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_StopMotionDetect(int nChNum) PURE;

	/**
	 * @brief This function sends the storage video file name to SDK to generate corresponding log file.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pFileName A NULL-terminated string for the video file name.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_SetFileName(int nChNum, char *pFileName) PURE;

	/**
	 * @brief This function sets the video signal type for encoding.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nSignalType A value to set the video signal type. (1: PAL, 2: NTSC)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_SetSignalType(int nChNum, int nSignalType) PURE;

	/**
	 * @brief  This function sets the video MPEG standard for encoding.
	 *		   The sopported resolution are listed in the manual.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nMPEGType A value to set the video MPEG standard. (1: MPEG1, 2: MPEG2, 4: MPEG4)
	 * @param nVideoSize A value to set the video resolution.
	 *			  0 --  D1		1 -- VGA	2 -- QVGA	3 -- SIF	4 -- QCIF
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_SetMPEGType(int nChNum, int nMPEGType, int nVideoSize) PURE;

	/**
	 * @brief This function sets the video brightness on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nBrightness A value to set the video brightness of a specified channel. The range is 0~255. (Default value is 128)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetBrightness(int nChNum, int nBrightness) PURE;

	/**
	 * @brief This function gets the video brightness on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pBrightness An integer pointer to store the returned video brightness of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetBrightness(int nChNum, int *pBrightness) PURE;

	/**
	 * @brief This function sets the video contrast on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nContrast A value to set the video contrast of a specified channel. The range is 0~127. (Default value is 68)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetContrast(int nChNum, int nContrast) PURE;

	/**
	 * @brief This function gets the video contrast on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pContrast An integer pointer to store the returned video contrast of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetContrast(int nChNum, int *pContrast) PURE;

	/**
	 * @brief This function sets the video color saturation on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nSaturation A value to set the video color saturation of a specified channel. The range is 0~127. (Default value is 64)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetSaturation(int nChNum, int nSaturation) PURE;

	/**
	 * @brief This function gets the video color saturation on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pSaturation An integer pointer to store the returned video color saturation of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetSaturation(int nChNum, int *pSaturation) PURE;

	/**
	 * @brief This function sets the video hue value on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nHue A value to set the video hue value of a specified channel. The range is -128~127. (Default value is 0)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetHue(int nChNum, int nHue) PURE;

	/**
	 * @brief This function gets the video hue value on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pHue An integer pointer to store the returned video hue value of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetHue(int nChNum, int *pHue) PURE;

	/**
	 * @brief This function sets the number of frames in a GOP and the frame distance between the reference frames on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nKeyFrameIntervals  A value to set the number of frames in a GOP. The range is 1~256. (Default value is 15)
	 * @param nRefFramesDistance A value to set the frame distance between the reference frames. The range is 0~3. (Default value is 3 for MPEG1 and MPEG2, is 1 for MPEG4) (MPEG4 does not support B-Frame)
	 *								0 -- The GOP structure is I (encoder will generate I frames only).
	 *								1 -- The GOP structure is IP.
	 *								2 -- The GOP structure is IBP.
	 *								3 -- The GOP structure is IBBP.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetGOPType(int nChNum, int nKeyFrameIntervals, int nRefFramesDistance) PURE;

	/**
	 * @brief This function gets the number of frames in GOP and  the frame distance between the reference frames on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pKeyFrameIntervals  An integer pointer to store the returned number of frames in a GOP.
	 * @param pRefFramesDistance An integer pointer to store the returned frame distance.
	 *								0 -- The GOP structure is I (encoder will generate I frames only).
	 *								1 -- The GOP structure is IP.
	 *								2 -- The GOP structure is IBP.
	 *								3 -- The GOP structure is IBBP.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetGOPType(int nChNum, int *pKeyFrameIntervals, int *pRefFramesDistance) PURE;

	/**
	 * @brief This function sets the frame rate and the minimum number of frames to skip on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nFrameRate A value to set the frame rate field in the sequence header. The range is 1~8. (Default value is 4)
	 *								1 -- 24,000/1001 23.976 fps
	 *								2 -- 24 Film
	 *								3 -- 25 PAL
	 *								4 -- 30,000/1001 29.97 fps NTSC
	 *								5 -- 30 NTSC drop frame
	 *								6 -- 50 Double frame rate PAL
	 *								7 -- 60,000/1001 Double frame rate NTSC
	 *								8 -- 60 Double frame rate drop frame NTSC
	 * @param nSkipFrameNum An value to set the minimum number of frames to skip. The range is 0~15. (Default value is 0)
	 *					   If the frame rate is 30 and the minimum to skip is 1 (one frame is displayed, the next one is not),
	 *					   then the effective frame rate becomes 15 (only half of the frames are displayed). Similarly,
	 *					   If skip = 2, the effective frame rate = 30/3 = 10 fps (one out of three frames is displayed)
	 *					   If skip = 3, the effective frame rate = 30/4 = 7.5 fps (one out of four frames is displayed)
	 *					   etc.
	 *					   The corresponding frame rates for a 25 fps system are:
	 *					   skip = 1 --> effective frame rate = 25/2 = 12.5 fps
	 *					   skip = 2 --> effective frame rate = 25/3 = 8.33 fps
	 *					   skip = 3 --> effective frame rate = 25/4 = 6.25 fps
	 *					   etc.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_SetFrameRate(int nChNum, int nFrameRate, int nSkipFrameNum) PURE;

	/**
	 * @brief This function gets the frame rate and the minimum number of frames to skip on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pFrameRate An integer pointer to store the returned frame rate field in the sequence header.
	 *								1 -- 24,000/1001 23.976 fps
	 *								2 -- 24 Film
	 *								3 -- 25 PAL
	 *								4 -- 30,000/1001 29.97 fps NTSC
	 *								5 -- 30 NTSC drop frame
	 *								6 -- 50 Double frame rate PAL
	 *								7 -- 60,000/1001 Double frame rate NTSC
	 *								8 -- 60 Double frame rate drop frame NTSC
	 * @param pSkipFrameNum An integer pointer to store the returned minimum number of frames to skip.
	 *					   If the frame rate is 30 and the minimum to skip is 1 (one frame is displayed, the next one is not),
	 *					   then the effective frame rate becomes 15 (only half of the frames are displayed). Similarly,
	 *					   If skip = 2, the effective frame rate = 30/3 = 10 fps (one out of three frames is displayed)
	 *					   If skip = 3, the effective frame rate = 30/4 = 7.5 fps (one out of four frames is displayed)
	 *					   etc.
	 *					   The corresponding frame rates for a 25 fps system are:
	 *					   skip = 1 --> effective frame rate = 25/2 = 12.5 fps
	 *					   skip = 2 --> effective frame rate = 25/3 = 8.33 fps
	 *					   skip = 3 --> effective frame rate = 25/4 = 6.25 fps
	 *					   etc.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
	 */
	virtual int DVP2420_GetFrameRate(int nChNum, int *pFrameRate, int *pSkipFrameNum) PURE;

	/**
	 * @brief This function sets the motion detect regions and the thresholds on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param md_regions A value to set the regions of the motion detection of a specified channel.
	 * @param nThresholds A value to set the motion vector thresholds of corresponding regions of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_InsertMotionDetectMask(int nChNum, MDRegion md_regions[], int nThresholds[]) PURE;

	/**
	 * @brief This function gets the motion detect regions and thresholds on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param md_regions A structure pointer to store the returned regions of the motion detection of a specified channel.
	 * @param nThresholds A structure pointer to store the returned motion vector thresholds of corresponding regions of a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GetMotionDetectMask(int nChNum, MDRegion md_regions[], int nThresholds[]) PURE;

	/**
	 * @brief This function sets the bit rate of the video stream on a specified channel.
	 *		  The constant bit rate is used when nBitRate equals nAvgBitRate.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nBitRate A value to set maximum bit rate of specified channel. The range is 128 kbps~15 Mbps. (Default value is 4 Mbps)
	 *				  The suggested video bit rate is from 1.5 Mbps to 15 Mbps for 1/2 D1 and above.
	 *				  The suggested video bit rate is from 512 kbps to 15 Mbps for SIF.
	 *				  The suggested video bit rate is from 128 kbps to 15 Mbps for QCIF.
	 * @param nAvgBitRate A value to set average bit rate of specified channel. The range is 128 kbps~9 Mbps. (Default value is 3.5 Mbps for PS, 3Mbps for TS)
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_SetVideoBitrate(int nChNum, int nBitRate, int nAvgBitRate) PURE;

	/**
	 * @brief This function gets the bit rate of the video stream on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pBitRate An integer pointer to store the returned maximum bit rate of specified channel.
	 * @param pAvgBitRate An integer pointer to store the returned average bit rate of specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GetVideoBitrate(int nChNum, int *pBitRate, int *pAvgBitRate) PURE;

	/**
	 * @brief This function sets the bit rate of the audio stream on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param nBitRate A value to set bit rate of the audio stream on a specified channel. The range is 0 ~ 13. (Default value is 7 (128 kbps))
	 *					  0 --  32 kbps		1  -- 48 kbps	2  -- 56 kbps	3  -- 64 kbps
	 *					  4 --  80 kbps		5  -- 96 kbps	6  -- 112 kbps	7  -- 128 kbps
	 *					  8 --  160 kbps	9  -- 192 kbps	10 -- 224 kbps	11 -- 256 kbps
	 *					  12 -- 320 kbps	13 -- 384 kbps
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_SetAudioBitrate(int nChNum, int nBitRate) PURE;

	/**
	 * @brief This function gets the bit rate of the audio stream on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param pBitRate An integer pointer to store the returned bit rate of the audio stream on a specified channel.
	 *					  0 --  32 kbps		1  -- 48 kbps	2  -- 56 kbps	3  -- 64 kbps
	 *					  4 --  80 kbps		5  -- 96 kbps	6  -- 112 kbps	7  -- 128 kbps
	 *					  8 --  160 kbps	9  -- 192 kbps	10 -- 224 kbps	11 -- 256 kbps
	 *					  12 -- 320 kbps	13 -- 384 kbps
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GetAudioBitrate(int nChNum, int *pBitRate) PURE;

	/**
	 * @brief This function sets the value of the specified digital output. The first chip controls the GPIO, 
	 *		  thus must to initialize the chip and download the firmware into the chip before controlling GIPO.
	 *
	 * @param nDONum Specifies the digital output number.
	 * @param bValue A value to set the value of the specified digital output.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GPIOSetData(int nDONum, BOOL bValue) PURE;

	/**
	 * @brief This function gets the value of the specified digital input. The first chip controls the GPIO, 
	 *		  thus must to initialize the chip and download the firmware into the chip before controlling GIPO.
	 *
	 * @param nDINum Specifies the digital input number.
	 * @param pValue A point to get the value of the specified digital input.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GPIOGetData(int nDINum, BOOL* pValue) PURE;

	/**
	 * @brief This function registers the StreamRead callback functions.
	 *
	 * @param pStreamRead A STREAMREAD_STRUCT structure pointer to set the StreamRead callback functions.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_RegStreamReadCB(STREAMREAD_STRUCT *pStreamRead) PURE;

	/**
	 * @brief This function registers the MotionDetect callback function.
	 *
	 * @param pMotionDetect A function pointer of the MotionDetect callback function.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_RegMotionDetectCB(PMOTIONDETECTPROC pMotionDetect) PURE;

	/**
	 * @brief This function registers the EncFail callback function.
	 *
	 * @param pEncFail A function pointer of the EncFail callback function.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_RegEncFailCB(PENCFAILPROC pEncFail) PURE;

	/**
	 * @brief This function gets current rendered image on a specified channel.
	 *
	 * @param nChNum Specifies the channel ID number.
	 * @param lpImageBuf A long pointer to store the returned image data on a specified channel.
	 * @param lpBufSize A long pointer to store the returned size of the image on a specified channel.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_GetCurImage(int nChNum, long *lpImageBuf, long *lpBufSize) PURE;

	/**
	 * @brief This function converts the MPEG4 video file to the divx format video file.
	 *
	 * @param src_filename A string for the MPEG4 video file name.
	 * @param des_filename A string for the divx format file name.
	 *
	 * @return If function succeeded, function returns ENC_SUCCEEDED.
     */
	virtual int DVP2420_PSMPEG4ToDivx(char *src_filename, char *des_filename) PURE;

	/**
	 * @brief This function detects if the specified video file is MPEG4 video type.
	 *
	 * @param mpegfilename A NULL-terminated string for the MPEG video file name.
	 *
	 * @return If the specified video file is MPEG4 video type, the function returns TRUE. Otherwise. it returns FALSE.
     */
	virtual BOOL DVP2420_IsPSMPEG4Type(char *mpegfilename) PURE;
};
