// PlayDemo_VCDlg.cpp : implementation file
//

#include "stdafx.h"
#include "PlayDemo_VC.h"
#include "PlayDemo_VCDlg.h"
#include <Shlwapi.h>

#define CHECK_NOT_IN_RET_VOID(src, minv, maxv)	if ((src) < (minv) || (src) >= (maxv)) {return;}
#define CHECK_EQUAL_RET_VOID(src, dst)			if ((src) == (dst) ) {return;}

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//---------------------------------------------------------------------------
//********出于便捷考虑，在CB代码直接移植过来的全局变量，暂时不应改动**********
FILE *g_pfDecA = NULL;
FILE *g_pfDecV = NULL;
int g_iPlayerID[MAX_WINDOWNUM] = {0};       //根据PanelID，得到PlayerID
FILE* g_pFileHandle[MAX_WINDOWNUM] = {0};
int g_iSpecialPlayerID[MAX_SPECIAL_PLAYER_NUM] = {0};       //根据PanelID，得到PlayerID
FILE* g_pSpecialFileHandle[MAX_SPECIAL_PLAYER_NUM] = {0};
int g_iMaxReadBufSize = 1024*1024*2;        //  每次从VOD文件中读取的块大小
FILE* g_pfPCM = NULL;
CPlayDemo_VCDlg* g_pEndFundlg = NULL;
CString cFileName;
CString cUserDataFileName;
bool iThreadFlag = false;
DemoUserData* tDemoUserData = NULL;

CLS_PlaySDK	g_PlaySDK_API;

static CPlayDemo_VCDlg* g_pDlgHandle = NULL;

#define USERDATA_FLAG_FRAMETIME			0
#define USERDATA_FLAG_VCA_SRC_SIZE		3
#define USERDATA_FLAG_LIFE_MONITOR		5
#define USERDATA_FLAG_DEMOGRAPHICS		6
#define USERDATA_FLAG_LPR				7
#define USERDATA_FLAG_OSD_EX			8
#define USERDATA_FLAG_LDC				9
#define USERDATA_FLAG_ZF				10
#define USERDATA_FLAG_TIMESTAMP			12
#define USERDATA_FLAG_TARGET_ATTR		13
#define USERDATA_FLAG_PTZ				15

#define USERDATA_FLAG_AVRESULT 				0xFED6
#define USERDATA_FLAG_VCA_VIDEOSIZE			0XFED7
#define USERDATA_FLAG_ENVIRONMENT_DATA		0XFEDB
#define USERDATA_FLAG_VCA_STATICLINE		0XFEE1
#define	USERDATA_FLAG_DEMOGRAPHICSEX		0xFEE4
#define USERDATA_FLAG_DEMOGRAPHICS_HISTORY	0xFEE5
#define USERDATA_FLAG_WATER_SPEED_BASE		0xFEE6
#define USERDATA_FLAG_WATER_SPEED_ALGINFO	0xFEE7
#define USERDATA_FLAG_VIRTUALGAUGE			0xFEE8
#define USERDATA_FLAG_ILLEGAL_AREA			0xFEE9
//---------------------------------------------------------------------------

//Cuda 测试 切换文件播放时间间隔 
#define BATCH_CUDA_TEST_CHANGE_INTERVAL		(20*1000)
#define BATCH_CAPTURE_BMP_INTERVAL			(5*1000)

//#define CUDA_FILEPLAYER_TEST

static void __cdecl DecodeAudioVideoNotify(int _iID, const DecAVInfo* _pDecAVInfo, void* _iUser)
{
	if (NULL == g_pDlgHandle || NULL == _pDecAVInfo || _iID < 0)
	{
		return;
	}

	g_pDlgHandle->Notify_DecodeAudioVideo(_iID, (DecAVInfo*)_pDecAVInfo);
	return;
}

int Nv12toYuyv(unsigned char* _pucSrc, int _iSrcPitch, int _iSrcHeight, unsigned char* _pucDst, int _iDstPitch, int _iWidth, int _iHeight)
{
	unsigned char* ucSrcY = _pucSrc;
	unsigned char* ucSrcUV = _pucSrc + _iSrcPitch *  _iSrcHeight;

	for (int h = 0; h < _iHeight; h++)
	{
		unsigned char* pucDst = _pucDst + _iDstPitch * h;
		unsigned char* pucY = ucSrcY + _iSrcPitch * h;
		unsigned char* pucUV = ucSrcUV + _iSrcPitch * (h/2);
		for (int w = 0; w <_iWidth/2; w++)
		{
			*pucDst = *pucY;
			pucDst++;
			pucY++;

			*pucDst = *pucUV;
			pucDst++;
			pucUV++;

			*pucDst = *pucY;
			pucDst++;
			pucY++;

			*pucDst = *pucUV;
			pucDst++;
			pucUV++;
		}
	}
	return 0;
}

// CPlayDemo_VCDlg dialog
CPlayDemo_VCDlg::CPlayDemo_VCDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPlayDemo_VCDlg::IDD, pParent)
	, m_iEdtTotalTime(0)
	, m_iEdtVSync(0)
	, m_iEdtAudio(0)
	, m_iEditFrame(0)
	,m_uiTimerGetPlayTime(0)
	,m_uiTimerInputStream(0)
	,m_uiTimerMain(0)
	,m_uiTimerBatchCudaTest(0)
	,m_uiTimerBatchCaptureTest(0)
	,m_edtCurSpeed(100)
	,m_fpSave(NULL)
	,m_bGetIFrame(false)
	,m_iBmpNum(0)
	,m_pfSaveUserDataFile(NULL)
	,m_hThreadHdl(NULL)
	,m_bIsUsrDataEnd(false)
	,m_iCurVedio_Count(0)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LOGO);
	//初始化变量
	m_blStatus = false;
	memset(m_iSpeed, 0, sizeof(m_iSpeed));
	m_iCurWinNum = 0;//默认播放窗口为第一个窗口
	m_bTotalTimeFocus = false;
	InitializeCriticalSection(&m_tLockLst);
	m_lstUsrData.clear();
}

void CPlayDemo_VCDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_GP_VEDIO, m_gpVedio);
	DDX_Text(pDX, IDC_EDT_SPEED, m_edtCurSpeed);
	//	DDV_MinMaxInt(pDX, m_edtCurSpeed, 20, MAX_STREAM_SPEED);
	DDX_Text(pDX, IDC_EDT_TOTALTIME, m_iEdtTotalTime);
	DDX_Text(pDX, IDC_EDT_VSYNC, m_iEdtVSync);
	DDX_Control(pDX, IDC_BTN_CAPTUREAUDIO, m_btnCaptureAudio);
	DDX_Control(pDX, IDC_BTN_AUDIO, m_btnAudio);
	DDX_Text(pDX, IDC_EDT_AUDIO, m_iEdtAudio);
	DDX_Text(pDX, IDC_EDT_SEEKTO, m_iEditFrame);
	DDX_Control(pDX, IDC_EDT_MESSAGE, m_edtMsg);
	DDX_Control(pDX, IDC_PRG_PLAY, m_prgPlay);
	DDX_Control(pDX, IDC_SLD_PROGRESS, m_sld_progress);
	DDX_Control(pDX, IDC_BTN_OPEN_FILE, m_btnOpenFile);
	DDX_Control(pDX, IDC_CHECK_DXVA_HW, m_chkDxvaHardDecode);
	DDX_Control(pDX, IDC_CHECK_PRIVATE_DECODER, m_chkPrivateSoftDecode);
	DDX_Control(pDX, IDC_CHECK_FFMPEG_DECODER, m_chkFfmpegSoftDecode);
	DDX_Control(pDX, IDC_CHECK_VIDEO_DISPLAY_422, m_chkVideoDispalyYuv422);
	DDX_Control(pDX, IDC_CHECK_VIDEO_DISPLAY_420, m_chkVideoDispalyYuv420);
	DDX_Control(pDX, IDC_CHECK_VIDEO_RENDER_DRAW, m_chkVideoRenderDraw);
	DDX_Control(pDX, IDC_CHECK_VIDEO_RENDER_D3D, m_chkVideoRenderD3D);
	DDX_Control(pDX, IDC_CHECK_SYNC, m_chkSync);
	DDX_Control(pDX, IDC_CHECK_UNIVERSAL, m_chkUniversalPlayer);
	DDX_Control(pDX, IDC_CHK_SAVEUSERDATA, m_chkSaveUserData);
	DDX_Control(pDX, IDC_CBO_RECFILETYPE, m_cboRecFileType);
}

BEGIN_MESSAGE_MAP(CPlayDemo_VCDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_1, &CPlayDemo_VCDlg::OnBnClickedBtn1)
	ON_BN_CLICKED(IDC_BTN_4, &CPlayDemo_VCDlg::OnBnClickedBtn4)
	ON_BN_CLICKED(IDC_BTN_9, &CPlayDemo_VCDlg::OnBnClickedBtn9)
	ON_BN_CLICKED(IDC_BTN_16, &CPlayDemo_VCDlg::OnBnClickedBtn16)
	ON_WM_CLOSE()
	ON_MESSAGE(WM_EVENT_MESSAGE, &CPlayDemo_VCDlg::OnEventMessage)
	ON_BN_CLICKED(IDC_BTN_OPEN_FILE, &CPlayDemo_VCDlg::OnBnClickedBtnOpenFile)
	ON_BN_CLICKED(IDC_BTN_OPEN_STREAM, &CPlayDemo_VCDlg::OnBnClickedBtnOpenStream)
	ON_BN_CLICKED(IDC_BTN_CLOSE, &CPlayDemo_VCDlg::OnBnClickedBtnClose)
	ON_BN_CLICKED(IDC_BTN_SET, &CPlayDemo_VCDlg::OnBnClickedBtnSet)
	ON_BN_CLICKED(IDC_BTN_GETDECDATA, &CPlayDemo_VCDlg::OnBnClickedBtnGetdecdata)
	ON_BN_CLICKED(IDC_BTN_STOP_GETDECDATA, &CPlayDemo_VCDlg::OnBnClickedBtnStopGetdecdata)
	ON_EN_SETFOCUS(IDC_EDT_TOTALTIME, &CPlayDemo_VCDlg::OnEnSetfocusDectotaltime)
	ON_EN_KILLFOCUS(IDC_EDT_TOTALTIME, &CPlayDemo_VCDlg::OnEnKillfocusDectotaltime)
	ON_BN_CLICKED(IDC_BTN_VSync, &CPlayDemo_VCDlg::OnBnClickedBtnVsync)
	ON_BN_CLICKED(IDC_BTN_RECORD, &CPlayDemo_VCDlg::OnBnClickedBtnRecord)
	ON_BN_CLICKED(IDC_BTN_STOPREC, &CPlayDemo_VCDlg::OnBnClickedBtnStoprec)
	ON_BN_CLICKED(IDC_BTN_FINDVCA, &CPlayDemo_VCDlg::OnBnClickedBtnFindvca)
	ON_BN_CLICKED(IDC_BTN_CAPTUREAUDIO, &CPlayDemo_VCDlg::OnBnClickedBtnCaptureaudio)
	ON_BN_CLICKED(IDC_CHK_DRAWMOTIONAREA, &CPlayDemo_VCDlg::OnBnClickedCheckDrawmotionarea)
	ON_BN_CLICKED(IDC_BTN_DRAWPOLYGON, &CPlayDemo_VCDlg::OnBnClickedBtnDrawpolygon)
	ON_BN_CLICKED(IDC_BTN_AUDIO, &CPlayDemo_VCDlg::OnBnClickedBtnAudio)
	ON_BN_CLICKED(IDC_BTN_CaptureYUV, &CPlayDemo_VCDlg::OnBnClickedBtnCaptureyuv)
	ON_BN_CLICKED(IDC_BTN_PLAY, &CPlayDemo_VCDlg::OnBnClickedBtnPlay)
	ON_BN_CLICKED(IDC_BTN_PAUSE, &CPlayDemo_VCDlg::OnBnClickedBtnPause)
	ON_BN_CLICKED(IDC_BTN_STEP, &CPlayDemo_VCDlg::OnBnClickedBtnStep)
	ON_BN_CLICKED(IDC_BTN_BACKSTEP, &CPlayDemo_VCDlg::OnBnClickedBtnBackstep)
	ON_BN_CLICKED(IDC_BTN_HOME, &CPlayDemo_VCDlg::OnBnClickedBtnHome)
	ON_BN_CLICKED(IDC_BTN_END, &CPlayDemo_VCDlg::OnBnClickedBtnEnd)
	ON_BN_CLICKED(IDC_BTN_FAST, &CPlayDemo_VCDlg::OnBnClickedBtnFast)
	ON_BN_CLICKED(IDC_BTN_SLOW, &CPlayDemo_VCDlg::OnBnClickedBtnSlow)
	ON_BN_CLICKED(IDC_BTN_SEARCH, &CPlayDemo_VCDlg::OnBnClickedBtnSearch)
	ON_BN_CLICKED(IDC_BTN_PLAY_VOD, &CPlayDemo_VCDlg::OnBnClickedBtnPlayVod)
	ON_BN_CLICKED(IDC_BTN_CLEAN_BUFFER, &CPlayDemo_VCDlg::OnBnClickedBtnCleanBuffer)
	ON_BN_CLICKED(IDC_BTN_CAPTUREBMP, &CPlayDemo_VCDlg::OnBnClickedBtnCapturebmp)
	ON_BN_CLICKED(IDC_BTN_SEEK, &CPlayDemo_VCDlg::OnBnClickedBtnSeek)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTN_SETEZOOM, &CPlayDemo_VCDlg::OnBnClickedBtnSetezoom)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_AUDIO, &CPlayDemo_VCDlg::OnDeltaposSpinAudio)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLD_PROGRESS, &CPlayDemo_VCDlg::OnNMCustomdrawSldProgress)
	ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SPEED, &CPlayDemo_VCDlg::OnDeltaposSpinSpeed)
	ON_BN_CLICKED(IDC_BUTTON_SET_FEC, &CPlayDemo_VCDlg::OnBnClickedButtonSetFec)
	ON_BN_CLICKED(IDC_BTN_REVERSE, &CPlayDemo_VCDlg::OnBnClickedBtnReverse)
	ON_BN_CLICKED(IDC_BTN_OPEN_STREAM_CUDA, &CPlayDemo_VCDlg::OnBnClickedBtnOpenStreamCuda)
	ON_BN_CLICKED(IDC_CHK_CUDA_TEST, &CPlayDemo_VCDlg::OnBnClickedChkCudaTest)
	ON_BN_CLICKED(IDC_BTN_START_DRAWRECT, &CPlayDemo_VCDlg::OnBnClickedBtnStartDrawrect)
	ON_BN_CLICKED(IDC_BTN_STOP_DRAWRECT, &CPlayDemo_VCDlg::OnBnClickedBtnStopDrawrect)
	ON_BN_CLICKED(IDC_CHECK_DXVA_HW, &CPlayDemo_VCDlg::OnBnClickedCheckDxvaHw)
	ON_BN_CLICKED(IDC_CHECK_PRIVATE_DECODER, &CPlayDemo_VCDlg::OnBnClickedCheckPrivateDecoder)
	ON_BN_CLICKED(IDC_CHECK_FFMPEG_DECODER, &CPlayDemo_VCDlg::OnBnClickedCheckFfmpegDecoder)
	ON_BN_CLICKED(IDC_CHECK_VIDEO_DISPLAY_422, &CPlayDemo_VCDlg::OnBnClickedCheckVideoDisplay422)
	ON_BN_CLICKED(IDC_CHECK_VIDEO_DISPLAY_420, &CPlayDemo_VCDlg::OnBnClickedCheckVideoDisplay420)
	ON_BN_CLICKED(IDC_CHECK_VIDEO_RENDER_DRAW, &CPlayDemo_VCDlg::OnBnClickedCheckVideoRenderDraw)
	ON_BN_CLICKED(IDC_CHECK_VIDEO_RENDER_D3D, &CPlayDemo_VCDlg::OnBnClickedCheckVideoRenderD3d)
	ON_BN_CLICKED(IDC_CHECK_SYNC, &CPlayDemo_VCDlg::OnBnClickedCheckSync)
	ON_BN_CLICKED(IDC_BTN_REVERSE_STEP, &CPlayDemo_VCDlg::OnBnClickedBtnReverseStep)
	ON_BN_CLICKED(IDC_CHK_SAVEUSERDATA, &CPlayDemo_VCDlg::OnBnClickedCheckSaveUserData)
END_MESSAGE_MAP()


// CPlayDemo_VCDlg message handlers

BOOL CPlayDemo_VCDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	ShowWindow(SW_SHOWNORMAL);
	// TODO: Add extra initialization here

	m_chkDxvaHardDecode.SetCheck(BST_UNCHECKED);
	m_chkPrivateSoftDecode.SetCheck(BST_CHECKED);
	m_chkFfmpegSoftDecode.SetCheck(BST_UNCHECKED);
	m_chkVideoRenderD3D.SetCheck(BST_CHECKED);
	m_chkVideoRenderDraw.SetCheck(BST_UNCHECKED);
	m_chkVideoDispalyYuv422.SetCheck(BST_CHECKED);
	m_chkVideoDispalyYuv420.SetCheck(BST_UNCHECKED);
	m_cboRecFileType.SetItemData(m_cboRecFileType.AddString("SDV"),REC_FILE_TYPE_NORMAL);
	m_cboRecFileType.SetItemData(m_cboRecFileType.AddString("MP4"),REC_FILE_TYPE_ZFMP4);
	m_cboRecFileType.SetCurSel(0);

	g_pEndFundlg = this;
	Init();//初始化视频窗口和动态库

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CPlayDemo_VCDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CPlayDemo_VCDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CPlayDemo_VCDlg::Init()
{

	g_pDlgHandle = this;
	//初始化变量
	m_mapInfo.insert(std::pair<int, CString>(RET_BUFFER_FULL, "Buffer is full"));
	m_mapInfo.insert(std::pair<int, CString>(RET_BUFFER_WILL_BE_FULL, "Buffer will be full"));
	m_mapInfo.insert(std::pair<int, CString>(RET_BUFFER_WILL_BE_EMPTY, "Buffer will be empty"));
	m_mapInfo.insert(std::pair<int, CString>(RET_BUFFER_IS_OK, "Buffer status is ok"));
	for(int i=0; i != MAX_WINDOWNUM; ++i)
	{
		g_iPlayerID[i] = -1;
		m_iAudio[i] = 0;
	}

	for(int i=0; i != MAX_SPECIAL_PLAYER_NUM; ++i)
	{
		g_iSpecialPlayerID[i] = -1;
		g_pSpecialFileHandle[i] = NULL;
	}

	for(int i=0; i < MAX_WINDOWNUM + MAX_SPECIAL_PLAYER_NUM; ++i)
	{
		m_iSputRetValue[i] = 0;
		m_cFileDataBuf[i] = 0;
	}

	//初始化窗口
	for (int i = 0; i != MAX_WINDOWNUM; ++i)
	{
		m_pDlgVedio[i] = new CLS_DlgVedio();
		m_pDlgVedio[i]->Create(IDD_DLG_VIDEO,GetDlgItem(IDC_GP_VEDIO));
		m_pDlgVedio[i]->ShowWindow(FALSE);
	}
	OnBnClickedBtn4();
	//初始化动态库
	CLS_CudaDecApi::Instance()->LoadLib();
	CLS_CudaDecApi::Instance()->CudaCoreStartup();

	m_PlaySDK.LoadDll();
	int iRet = -1;
	if ((iRet = m_PlaySDK.CreateSystem(NULL)) != 0)
	{
		return;
	}

	g_PlaySDK_API = m_PlaySDK;
	m_PlaySDK.RegisterNotifyPlayToEnd((void*)PlayEndFun);
	m_PlaySDK.RegisterCommonEventCallBackEx(CommonEventNotify, (void*)this);
	m_PlaySDK.StartMonitorCPU();
	m_PlaySDK.GetVersion(&m_Version);
	m_cstrVersionString = CString("PlayDemo (SDK ") + m_Version.m_cVerInfo + ")";
	AfxGetMainWnd()->SetWindowText(m_cstrVersionString);

	CSpinButtonCtrl* pCSpin = (CSpinButtonCtrl*)GetDlgItem(IDC_SPIN_SPEED);
	pCSpin->SetRange(MIN_SPEED, MAX_STREAM_SPEED);//设置控件变化的上下界
	pCSpin->SetBuddy(GetDlgItem(IDC_EDT_SPEED));//关联伙伴控件
	m_mnPopMenu.CreatePopupMenu();
	m_mnPopMenu.InsertMenu(0,MF_BYPOSITION,IDR_MNU_NORMAL,"Normal");
	m_mnPopMenu.InsertMenu(1,MF_BYPOSITION,IDR_MNU_VOD,"Vod");
	m_mnPopMenu.InsertMenu(2,MF_BYPOSITION,IDR_MNU_ALL,"All");
}

void CPlayDemo_VCDlg::DisplayFrame()
{
	RECT rect = {0};	
	m_gpVedio.GetClientRect(&rect);
	m_iWidth = (rect.right - rect.left) / m_iCurVedio_Count;
	m_iHeight = (rect.bottom - rect.top) / m_iCurVedio_Count;

	for (int i = 0;i < m_iCurVedio_Count;i++)//显示前面_rows*_rows个视频窗口
	{
		for (int j = 0;j < m_iCurVedio_Count;j++)
		{	
			int iLeft = rect.left + j*m_iWidth;
			int iTop = rect.top + i*m_iHeight;
			int iFrameID = i*m_iCurVedio_Count+j;
			m_pDlgVedio[iFrameID]->MoveWindow(iLeft, iTop, m_iWidth, m_iHeight);
			m_pDlgVedio[iFrameID]->ShowWindow(SW_SHOW);
		}
	}
}

void CPlayDemo_VCDlg::ShutWindow()
{
	for (int i = 0; i != MAX_WINDOWNUM; ++i)
	{
		m_pDlgVedio[i]->ShowWindow(FALSE);
	}
}

void CPlayDemo_VCDlg::OnBnClickedBtn1()
{
	// TODO: Add your control notification handler code here
	if (m_iCurVedio_Count == 1)
	{
		return;
	}
	m_iCurVedio_Count = 1;
	ShutWindow();
	DisplayFrame();
}

void CPlayDemo_VCDlg::OnBnClickedBtn4()
{
	// TODO: Add your control notification handler code here
	if (m_iCurVedio_Count == 2)
	{
		return;
	}
	m_iCurVedio_Count = 2;
	ShutWindow();
	DisplayFrame();
}

void CPlayDemo_VCDlg::OnBnClickedBtn9()
{
	// TODO: Add your control notification handler code here
	if (m_iCurVedio_Count == 3)
	{
		return;
	}
	m_iCurVedio_Count = 3;
	ShutWindow();
	DisplayFrame();
}

void CPlayDemo_VCDlg::OnBnClickedBtn16()
{
	// TODO: Add your control notification handler code here
	if (m_iCurVedio_Count == 4)
	{
		return;
	}
	m_iCurVedio_Count = 4;
	ShutWindow();
	DisplayFrame();
}

BOOL CPlayDemo_VCDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class
	if (pMsg->message == WM_KEYDOWN)
	{
		switch (pMsg->wParam)
		{
		case VK_RETURN:
			return TRUE;
		case VK_ESCAPE:
			return TRUE;
		default:
			break;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CPlayDemo_VCDlg::OnClose()
{
	// TODO: Add your message handler code here and/or call default
	if(MessageBox(_T("确认退出？"),_T("提示框"),MB_YESNO) == IDNO)
		return;
	OnBnClickedBtnClose();
	m_PlaySDK.StopMonitorCPU();
	m_PlaySDK.DeleteSystem();

	for (int i = 0; i < MAX_WINDOWNUM; ++i)
	{
		if (NULL != m_pDlgVedio[i])
		{
			delete m_pDlgVedio[i];
			m_pDlgVedio[i] = NULL;
		}
	}

	for (int i = 0; i < MAX_WINDOWNUM + MAX_SPECIAL_PLAYER_NUM; ++i)
	{
		if (NULL != m_cFileDataBuf[i])
		{
			delete m_cFileDataBuf[i];
			m_cFileDataBuf[i] = NULL;
		}
	}
	KillTimer(m_uiTimerGetPlayTime);//erxing
	CDialog::OnClose();
}

LRESULT CPlayDemo_VCDlg::OnEventMessage(WPARAM wParam, LPARAM lParam)
{
	if (wParam == MSG_FILE_PLAY_END || wParam == MSG_VOD_STREAM_END)
	{
		int iPlayerID = (int)lParam;
		m_PlaySDK.Stop(iPlayerID);
		m_PlaySDK.DeletePlayer(iPlayerID);

		for (int i = 0; i < MAX_WINDOWNUM; ++i)    
		{
			if (g_iPlayerID[i] == iPlayerID)
			{
				g_iPlayerID[i] = -1;
				m_pDlgVedio[i]->Invalidate(TRUE);
				m_pDlgVedio[i]->m_blIsPlay = false;
			}
		}

		if (m_pfSaveUserDataFile)
		{
			fclose(m_pfSaveUserDataFile);
			m_pfSaveUserDataFile = NULL;
			MessageBox("用户数据保存完成","用户数据",0);
		}

		CString cstrPrompt;
		CString cstrMsg;

		UpdateData(TRUE);
		m_edtMsg.GetWindowText(cstrMsg);
		cstrPrompt.Format("Player(%d) Play to end", iPlayerID);
		cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
		m_edtMsg.SetWindowText(cstrMsg);
		m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
		UpdateData(FALSE);
		m_prgPlay.SetPos(0);
		trace_d(" =============================================  PlayEndFun Notify, PlayerID:%d\n", iPlayerID);
	}

	if (wParam == MSG_FILE_SEARCH_END)
	{
		int iPlayerID = (int)lParam;
		CString cstrPrompt;
		CString cstrMsg;

		UpdateData(TRUE);
		m_edtMsg.GetWindowText(cstrMsg);
		cstrPrompt.Format("File search end! Player(%d)", iPlayerID);
		cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
		m_edtMsg.SetWindowText(cstrMsg);
		m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
		UpdateData(FALSE);
	}
	else if (wParam == MSG_NEED_DECRYPT_KEY)
	{
		trace_d(" ====================== Need Decrypt Key, PlayerID(%d)\n", lParam);

		CString cstrPrompt;
		CString cstrMsg;

		UpdateData(TRUE);
		m_edtMsg.GetWindowText(cstrMsg);
		cstrPrompt.Format("Player(%d) need decrypt key, please input first", (int)lParam);
		cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
		m_edtMsg.SetWindowText(cstrMsg);
		m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
		UpdateData(FALSE);
	}
	else if (wParam == MSG_DECRYPT_KEY_FAILED)
	{
		trace_d(" ====================== Decrypt Key is Wrong, PlayerID(%d)\n", lParam);
		CString cstrPrompt;
		CString cstrMsg;

		UpdateData(TRUE);
		m_edtMsg.GetWindowText(cstrMsg);
		cstrPrompt.Format("Player(%d), decrypt key is wrong", (int)lParam);
		cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
		m_edtMsg.SetWindowText(cstrMsg);
		m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
		UpdateData(FALSE);
	}
	else if (wParam == MSG_DECRYPT_SUCCESS)
	{
		trace_d(" ====================== Decrypt Key is Right, PlayerID(%d)\n", lParam);
		CString cstrPrompt;
		CString cstrMsg;

		UpdateData(TRUE);
		m_edtMsg.GetWindowText(cstrMsg);
		cstrPrompt.Format("Player(%d), decrypt key is Right", (int)lParam);
		cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
		m_edtMsg.SetWindowText(cstrMsg);
		m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
		UpdateData(FALSE);
	}
	else if(wParam == MSG_STREAM_SEARCH_END)
	{
		int iPlayerID = (int)lParam;
		CString cstrPrompt;
		CString cstrMsg;
		for (int i = 0; i < MAX_WINDOWNUM; ++i) 
		{
			if (g_iPlayerID[i] == iPlayerID && NULL == g_pFileHandle[i])
			{
				int iPlayingFrameNum = m_PlaySDK.GetPlayingFrameNum(iPlayerID);
				if(iPlayingFrameNum > 1)
				{
					m_PlaySDK.Stop(iPlayerID);
					m_PlaySDK.DeletePlayer(iPlayerID);
					g_iPlayerID[i] = -1;

					UpdateData(TRUE);
					m_edtMsg.GetWindowText(cstrMsg);
					cstrPrompt.Format("Stream search end! Player(%d)", iPlayerID);
					cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
					m_edtMsg.SetWindowText(cstrMsg);
					m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
					UpdateData(FALSE);
				}
			}
		}
	}
	return S_OK;
}

bool CPlayDemo_VCDlg::IsPlayOnCurWin( int _iWinNum )
{
	return m_pDlgVedio[_iWinNum]->m_blIsPlay;
}

void CPlayDemo_VCDlg::openFileFFmpegSoftDecode(CString& cstrPath)
{
	int iBufferSize = 0; 
	UniversalFilePlayer playerPara = {0};
	strcpy_s(playerPara.cFileName, MAX_FILENAME_LEN, cstrPath.GetBuffer());
	playerPara.iSize = sizeof(playerPara);
	playerPara.hWnd = m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd();

	int iRet = m_PlaySDK.CreatePlayer(E_UNIVERSAL_FILEPLAYER, &playerPara, sizeof(playerPara), NULL);
	if(iRet < 0)
	{
		MessageBox("Incorrect file format!", "Error", MB_OK);
		return;
	}
	int iID = iRet;
	g_iPlayerID[m_iCurWinNum] = iID;
	RECT rcDraw = {0};
	memset(&rcDraw, 0, sizeof(rcDraw));
	m_PlaySDK.SetPlayRect(iID,&rcDraw);//设置播放位置和大小 

	m_PlaySDK.Play(iID);//播放

	m_PlaySDK.PlayAudio(iID);//打开音频
	UpdateUI_ShowAudioVolume(iID);
	GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
	m_iAudio[m_iCurWinNum] = 1;
	m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;
	m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器,功能：获取播放时间
}

void CPlayDemo_VCDlg::openFile(CString& cstrPath)
{
	RECT rcDraw = {0};
	int iCheckResult = CheckFileSize(cstrPath.GetBuffer());//检查文件
	if (-1 == iCheckResult)
	{
		MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
		return;
	}
	else if (-2 == iCheckResult)
	{
		MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		return;
	}

	int iBufferSize = 0;                  //创建一个播放实例，以文件方式播放
	g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayerFromFile(m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd(), cstrPath.GetBuffer(), iBufferSize);
	if(g_iPlayerID[m_iCurWinNum] < 0)
	{
		MessageBox("Incorrect file format!", "Error", MB_OK);
		return;
	}

	UserDataNotify tUserDataNotify = {0};
	tUserDataNotify.pNotifyFun = DevUserDataNotify;
	tUserDataNotify.iSize = sizeof(tUserDataNotify);
	tUserDataNotify.pvUdata = this;
	m_PlaySDK.PlayBackControl(g_iPlayerID[m_iCurWinNum],CTRL_REGIST_USERDATA_NOTIFY,&tUserDataNotify,tUserDataNotify.iSize,NULL);
	OnBnClickedCheckSaveUserData();

	memset(&rcDraw, 0, sizeof(rcDraw));
	m_PlaySDK.SetPlayRect(g_iPlayerID[m_iCurWinNum],&rcDraw);//设置播放位置和大小 

	int iBegin;
	int iEnd;   //获得第一帧和最后一帧的帧序号 
	if(m_PlaySDK.GetBeginEnd(g_iPlayerID[m_iCurWinNum],&iBegin,&iEnd) == 0)
	{
		CString cstr;
		cstr.Format("%d",iBegin);
		GetDlgItem(IDC_EDT_BEGIN)->SetWindowText(cstr);
		cstr.Format("%d",iEnd);
		GetDlgItem(IDC_EDT_END)->SetWindowText(cstr);
	}

	m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);//播放

	m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);//打开音频
	UpdateUI_ShowAudioVolume(g_iPlayerID[m_iCurWinNum]);
	GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
	m_iAudio[m_iCurWinNum] = 1;
	m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;
	m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器,功能：获取播放时间
}
//OpenFile控件功能实现 cheyueyong 2014-02-13
void CPlayDemo_VCDlg::OnBnClickedBtnOpenFile()
{
	// TODO: Add your control notification handler code here
	RECT rcDraw = {0};
	CString cstrPath = _T("");

	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("All Files (*.*)|*.*||"), NULL);
	if (dlgFile.DoModal() == IDOK)
	{
		cstrPath = dlgFile.GetPathName();
		cFileName = dlgFile.GetFileName();
		CString cTemp;
		for (int iCount = 0; iCount < cFileName.GetLength(); iCount++)
		{
			if ('.' == cFileName[iCount])
			{
				break;
			}
			cTemp += cFileName[iCount];
		}
		cUserDataFileName.Format("sei_%s.txt",cTemp);

		if(IsPlayOnCurWin(m_iCurWinNum) == false)//判断当前窗口是否在播放视频
		{
			for(int i = 0; i < 16; ++i)
			{
				m_iSpeed[i] = 0;
			}

			if (BST_CHECKED == m_chkUniversalPlayer.GetCheck())
			{
				openFileFFmpegSoftDecode(cstrPath);
			}
			else
			{
				openFile(cstrPath);
			}
		}
		else
		{
			MessageBox(_T("当前窗口正在播放视频"), _T("Hint"));
		}
	}
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);//打开定时器,功能：操作视频
}

//OpenStream控件功能实现 cheyueyong 2014-02-13
void CPlayDemo_VCDlg::OnBnClickedBtnOpenStream()
{
	// TODO: Add your control notification handler code here
	CString cstrPath = _T("");
	RECT rcDraw = {0};
	char cHeadInfo[88] = {0};

	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("All Files (*.*)|*.*||"), NULL);
	if (dlgFile.DoModal() == IDOK)
	{
		for(int i = 0; i < 16; ++i)
		{
			m_iSpeed[i] = 0;
		}

		if(g_iPlayerID[m_iCurWinNum]!= -1)
		{
			m_iSpeed[m_iCurWinNum] = 0;

			m_PlaySDK.DeletePlayer(g_iPlayerID[m_iCurWinNum]);
			if(g_pFileHandle[m_iCurWinNum])
			{
				fclose(g_pFileHandle[m_iCurWinNum]);
				g_pFileHandle[m_iCurWinNum] = NULL;
			}
			g_iPlayerID[m_iCurWinNum]=-1;

			m_pDlgVedio[m_iCurWinNum]->Invalidate();
			m_prgPlay.SetPos(0);
		}

		cstrPath = dlgFile.GetPathName();
		int iCheckResult = CheckFileSize(cstrPath.GetBuffer());
		if (-1 == iCheckResult)
		{
			MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
			return;
		}
		else if (-2 == iCheckResult)
		{
			MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
			return;
		}

		g_pFileHandle[m_iCurWinNum] = _fsopen(cstrPath.GetBuffer(), "rb", _SH_DENYNO);
		if (g_pFileHandle[m_iCurWinNum]== NULL)
		{
			MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		}

		fseek(g_pFileHandle[m_iCurWinNum], 0, SEEK_SET);
		if (BST_CHECKED == m_chkUniversalPlayer.GetCheck())
		{
			UniversalStreamPlayer tPara = {0};
			tPara.iSize = sizeof(UniversalStreamPlayer);
			tPara.hWnd = m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd();
			g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayer(E_UNIVERSAL_STREAMPLAYER, &tPara, sizeof(UniversalStreamPlayer), this);
		}
		else
		{
			fread(cHeadInfo, sizeof(char), 88, g_pFileHandle[m_iCurWinNum]);
			g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayerFromStream(m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd(), (unsigned char *)cHeadInfo, 88);
		}
		m_PlaySDK.SetStreamBufferSize(g_iPlayerID[m_iCurWinNum], 4*1024*1024);
		m_PlaySDK.SetFrameListBufferSize(g_iPlayerID[m_iCurWinNum], 10*1024*1024);
		m_PlaySDK.SetModeRule(g_iPlayerID[m_iCurWinNum], MODERULE_AUTO_ADJUST_STREAM_PLAY_SPEED_NO);
		m_PlaySDK.SetModeRule(g_iPlayerID[m_iCurWinNum], MODERULE_AUTO_ADJUST_DRAW_YES);

		OnBnClickedBtnStartDrawrect();

#ifdef _USE_PSPACK_NOTIFY_
		m_PlaySDK.RegisterPsPackCallBack(PsPackNotify, this);
#endif

		memset(&rcDraw, 0, sizeof(rcDraw));
		m_PlaySDK.SetPlayRect(g_iPlayerID[m_iCurWinNum],&rcDraw);
		m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
		UpdateUI_ShowAudioVolume(g_iPlayerID[m_iCurWinNum]);
		GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
		m_iAudio[m_iCurWinNum] = 1;
		m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;
		m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);
		//GetData(0);
	}
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);
}

void CPlayDemo_VCDlg::OnBnClickedBtnOpenStreamCuda()
{
	CString cstrPath = _T("");
	RECT rcDraw = {0};
	char cHeadInfo[88] = {0};

	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("All Files (*.*)|*.*||"), NULL);
	if (dlgFile.DoModal() == IDOK)
	{
		for(int i = 0; i < 16; ++i)
		{
			m_iSpeed[i] = 0;
		}

		if(g_iPlayerID[m_iCurWinNum]!= -1)
		{
			m_iSpeed[m_iCurWinNum] = 0;

			m_PlaySDK.DeletePlayer(g_iPlayerID[m_iCurWinNum]);
			if(g_pFileHandle[m_iCurWinNum])
			{
				fclose(g_pFileHandle[m_iCurWinNum]);
				g_pFileHandle[m_iCurWinNum] = NULL;
			}
			g_iPlayerID[m_iCurWinNum]=-1;

			m_pDlgVedio[m_iCurWinNum]->Invalidate();
			m_prgPlay.SetPos(0);
		}

		cstrPath = dlgFile.GetPathName();
		int iCheckResult = CheckFileSize(cstrPath.GetBuffer());
		if (-1 == iCheckResult)
		{
			MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
			return;
		}
		else if (-2 == iCheckResult)
		{
			MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
			return;
		}

		g_pFileHandle[m_iCurWinNum] = _fsopen(cstrPath.GetBuffer(), "rb", _SH_DENYNO);
		if (g_pFileHandle[m_iCurWinNum]== NULL)
		{
			MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		}
		fseek(g_pFileHandle[m_iCurWinNum], 0, SEEK_SET);
		fread(cHeadInfo, sizeof(char), 88, g_pFileHandle[m_iCurWinNum]);

		CudaPlayer tPlayerInfo = {0};
		tPlayerInfo.iSize = sizeof(CudaPlayer);
		tPlayerInfo.hWnd = m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd();
		tPlayerInfo.iGpuID = -1;//负载均衡
		memcpy(tPlayerInfo.ucVideoHeadBuf, cHeadInfo, min(PLAY_VIDEO_HEADER_LEN, 88));
		g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayer(E_CUDA_STREAMPLAYER, &tPlayerInfo, tPlayerInfo.iSize, this);
		if (g_iPlayerID[m_iCurWinNum] < 0)
		{
			return;
		}

		m_PlaySDK.SetStreamBufferSize(g_iPlayerID[m_iCurWinNum], 4*1024*1024);
		m_PlaySDK.SetFrameListBufferSize(g_iPlayerID[m_iCurWinNum], 10*1024*1024);
		m_PlaySDK.SetModeRule(g_iPlayerID[m_iCurWinNum], MODERULE_AUTO_ADJUST_STREAM_PLAY_SPEED_NO);
		m_PlaySDK.SetModeRule(g_iPlayerID[m_iCurWinNum], MODERULE_AUTO_ADJUST_DRAW_YES);

		memset(&rcDraw, 0, sizeof(rcDraw));
		m_PlaySDK.SetPlayRect(g_iPlayerID[m_iCurWinNum],&rcDraw);
		m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
		GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
		UpdateUI_ShowAudioVolume(g_iPlayerID[m_iCurWinNum]);
		m_iAudio[m_iCurWinNum] = 1;
		m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;
		m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);
		//GetData(0);
	}
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);

}

void CPlayDemo_VCDlg::OnBnClickedBtnClose()
{
	// TODO: Add your control notification handler code here

	m_iSpeed[m_iCurWinNum] = 0;
	m_prgPlay.SetPos(0);
	m_PlaySDK.StopAudio(g_iPlayerID[m_iCurWinNum]);
	GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioOpen");
	m_iAudio[m_iCurWinNum] = 0;

	m_PlaySDK.Stop(g_iPlayerID[m_iCurWinNum]);
	m_PlaySDK.DeletePlayer(g_iPlayerID[m_iCurWinNum]);
	KillTimer(m_uiTimerGetPlayTime);
	if(g_pFileHandle[m_iCurWinNum])
	{
		fclose(g_pFileHandle[m_iCurWinNum]);
		g_pFileHandle[m_iCurWinNum] = 0;
	}

	g_iPlayerID[m_iCurWinNum]=-1;
	m_iAudio[m_iCurWinNum] = 0;

	m_pDlgVedio[m_iCurWinNum]->Invalidate();
	m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = false;
	m_pDlgVedio[m_iCurWinNum]->SetPlaySync(FALSE);
	for (int i = 0; i < MAX_WINDOWNUM; ++i)
	{
		if (g_iPlayerID[i] != -1)
		{
			return;
		}
	}
	KillTimer(m_uiTimerInputStream);
	if (iThreadFlag == true)
	{
		iThreadFlag = false;
		m_hThreadHdl = NULL;
	}
	if (m_pfSaveUserDataFile)
	{
		fclose(m_pfSaveUserDataFile);
		m_pfSaveUserDataFile = NULL;
		MessageBox("用户数据保存完成","用户数据",0);
	}
}

void CPlayDemo_VCDlg::OnBnClickedBtnSet()
{
	// TODO: Add your control notification handler code here
	CString cstrDecryptKey;
	GetDlgItem(IDC_EDT_KEY)->GetWindowText(cstrDecryptKey);
	if (cstrDecryptKey.GetLength() > 16)
	{
		MessageBox("Decrypt Key is too long", "Error", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
		return;
	}
	int iLen =  cstrDecryptKey.GetLength();
	m_PlaySDK.SetVideoDecryptKey(g_iPlayerID[m_iCurWinNum], cstrDecryptKey.GetBuffer(), cstrDecryptKey.GetLength());
	m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);
}


void __cdecl CPlayDemo_VCDlg::PlayEndFun(int _iID)
{
	for(int i=0;i != MAX_WINDOWNUM; ++i)
	{
		if(g_iPlayerID[i] == _iID)
		{
			::PostMessage(g_pEndFundlg->GetSafeHwnd(), WM_EVENT_MESSAGE, MSG_FILE_PLAY_END, _iID);
			//			::PostMessage(::FindWindowEx( NULL, NULL, "CPlayDemo_VCDlg", NULL ), WM_EVENT_MESSAGE, MSG_FILE_PLAY_END, _iID);
		}
	}
}

int __cdecl CPlayDemo_VCDlg::CommonEventNotify( int _iPlayerID, int _iEventMessage, void* _lpUserData ) // afx_msg LRESULT OnEventMessage(MSG* pMsg)
{
	CPlayDemo_VCDlg *pDlg = (CPlayDemo_VCDlg *)_lpUserData;
	WPARAM dwMsg = 0;
	if (_iEventMessage == LPARAM_NEED_DECRYPT_KEY)
		dwMsg = MSG_NEED_DECRYPT_KEY;
	else if (_iEventMessage == LPARAM_DECRYPT_KEY_FAILED)
		dwMsg = MSG_DECRYPT_KEY_FAILED;
	else if (_iEventMessage == LPARAM_DECRYPT_SUCCESS)
		dwMsg = MSG_DECRYPT_SUCCESS;
	else if (_iEventMessage == LPARAM_FILE_SEARCH_END)
		dwMsg = MSG_FILE_SEARCH_END;
	else if (_iEventMessage == LPARAM_STREAM_SEARCH_END)
		dwMsg = MSG_STREAM_SEARCH_END;
	else if (_iEventMessage == LPARAM_VOD_STREAM_END)
		dwMsg = MSG_VOD_STREAM_END;
	else
		return 0;

	for (int i = 0; i < MAX_WINDOWNUM; i++)
	{
		if(g_iPlayerID[i]==_iPlayerID)
			::PostMessage(pDlg->GetSafeHwnd(), WM_EVENT_MESSAGE, dwMsg, _iPlayerID);
	}

	return 0;
}

void __cdecl CPlayDemo_VCDlg::GetDecAVCbk( int _iID, const DecAVInfo *_pDecAVInfo )
{
	if (_pDecAVInfo->iType == 0)  //Video
	{
		if (g_pfDecV == NULL)
		{
			g_pfDecV = _fsopen("C:\\DecV.yuv", "wb", _SH_DENYNO);
		}

		if (NULL != g_pfDecV)
		{
			fwrite(_pDecAVInfo->pucData, sizeof(char), _pDecAVInfo->iDataLen, g_pfDecV);
		}	
	}

	if (_pDecAVInfo->iType == 1)  //Audio
	{
		if (g_pfDecA == NULL)
		{
			g_pfDecA = _fsopen("C:\\DecA.pcm", "wb", _SH_DENYNO);
		}

		if (NULL != g_pfDecA)
		{
			fwrite(_pDecAVInfo->pucData, sizeof(char), _pDecAVInfo->iDataLen, g_pfDecA);
		}		
	}
}

int __cdecl CPlayDemo_VCDlg::PsPackNotify( int _iPlayerID, unsigned char* _ucData, int _iSize, PSPACK_INFO* _pPsPackInfo, void* _pContext )
{
#ifdef _USE_PSPACK_NOTIFY_
	int iType = _pPsPackInfo->nType;
	PsPack_InputData(_ucData, _iSize, iType);
#endif
	return 0;
}

void __cdecl CPlayDemo_VCDlg::OutPutAudio(unsigned char* _pucData, int _iLen, void* _pvUserData)
{
	if(g_pfPCM)
		fwrite(_pucData, _iLen, 1, g_pfPCM);
}

void __cdecl CPlayDemo_VCDlg::ShowMotionArea(long _iPlayFd, HDC _hDc, int _iUsr)
{
	RECT rect = {0};
	BYTE byMotionAlarmArea[MAX_MOTION_DETECTION_ROW][MAX_MOTION_DETECTION_COL] = {0};
	memset(&byMotionAlarmArea,1,MAX_MOTION_DETECTION_ROW*MAX_MOTION_DETECTION_COL);

	HPEN DrawPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	::SelectObject(_hDc, GetStockObject(NULL_BRUSH));
	::SelectObject(_hDc, DrawPen);
	for(int i = 0; i < MAX_MOTION_DETECTION_ROW; ++i)
	{
		for(int j = 0; j < MAX_MOTION_DETECTION_COL; ++j)
		{
			if(byMotionAlarmArea[i][j] == 1)
			{
				rect.left = j*16;//j*15;
				rect.top = i*16;//i*13;
				rect.right = j*16 + 16;//j*15 + 15;
				rect.bottom = i*16 + 16;//i*13 + 13;
				//::DrawEdge(_hDc, &rect, BDR_SUNKENOUTER, BF_RECT);
				::Rectangle(_hDc, rect.left, rect.top, rect.right, rect.bottom);
			}
		}
	}
	::SetBkMode(_hDc, TRANSPARENT);
	::DeleteObject(DrawPen);
}
void CPlayDemo_VCDlg::GetData(int _iID)
{
	int iReadCount = 0;
	const int iMaxReadSize = g_iMaxReadBufSize;
	CString cstrPrompt;
	CString cstrMsg;
	for (int i = 0; i < MAX_WINDOWNUM + MAX_SPECIAL_PLAYER_NUM; ++i)
	{
		FILE** ppFileHandle = NULL;
		char** ppDataBuf = NULL;
		int iPlayerId = -1;

		if (i >= MAX_WINDOWNUM)
		{
			iPlayerId = g_iSpecialPlayerID[i - MAX_WINDOWNUM];
			ppFileHandle = &g_pSpecialFileHandle[i - MAX_WINDOWNUM];

		}
		else
		{
			iPlayerId = g_iPlayerID[i];
			ppFileHandle = &g_pFileHandle[i];
		}
		ppDataBuf = &m_cFileDataBuf[i];

		if ((iPlayerId < 0) || (NULL == *ppFileHandle))
		{
			continue;
		}

		unsigned int ulCurPos = ftell(*ppFileHandle);
		if (NULL == (*ppDataBuf))
			(*ppDataBuf) = new char [iMaxReadSize];

		iReadCount = (int)fread((*ppDataBuf), 1, iMaxReadSize, *ppFileHandle);
		if (iReadCount == 0)
		{
			UpdateData(TRUE);
			m_edtMsg.GetWindowText(cstrMsg);
			cstrPrompt.Format("file has reach end! Player(%d)", iPlayerId);
			cstrMsg = cstrMsg + "\r\n" + cstrPrompt;
			m_edtMsg.SetWindowText(cstrMsg);
			m_edtMsg.LineScroll(m_edtMsg.GetLineCount());
			UpdateData(FALSE);

			//Form1->mmoMsg->Lines->Add(cstrPrompt);
			fclose(*ppFileHandle);
			*ppFileHandle = NULL;
			m_PlaySDK.SetVoDPlayerOver(iPlayerId);
			break;
		}

		int iPutRet = m_PlaySDK.PutStreamToPlayer(iPlayerId, (unsigned char *)(*ppDataBuf), iReadCount);
		if(iPutRet == RET_BUFFER_WILL_BE_FULL)
		{
			//缓冲满了，减速且这次不送
			if(m_edtCurSpeed != MAX_STREAM_SPEED)
			{
				ChangePutSpeed(SPEED_DEC);
			}
		}
		else if (iPutRet == RET_BUFFER_WILL_BE_EMPTY)
		{
			//缓冲太少，加速
			if(m_edtCurSpeed != 0)
			{
				ChangePutSpeed(SPEED_ADD);
			}
		}
		else if (iPutRet == RET_BUFFER_FULL)
		{
			fseek(*ppFileHandle, ulCurPos, SEEK_SET);
		}
		else if (iPutRet != RET_BUFFER_IS_OK)
		{
			if (iPutRet != 0)
			{
				trace_d("%d -- RetCode(%d)\n", i, iPutRet);
			}
		}
	}
}

void CPlayDemo_VCDlg::ChangePutSpeed(int _iSpeedType )
{
	int iRet = ((CButton*)GetDlgItem(IDC_CHK_AUTO_CHANGE))->GetCheck();
	if(iRet == 0)
		return; //判断是否勾选Auto-Change按钮

	if(SPEED_DEC == _iSpeedType)
	{	
		m_edtCurSpeed += 50;//减速，让定时器延长
	}
	else if(SPEED_ADD == _iSpeedType)
	{
		m_edtCurSpeed -= 100;//加速
	}

	if(m_edtCurSpeed <= 0)
	{
		m_edtCurSpeed = 20;
	}
	else if (m_edtCurSpeed > MAX_STREAM_SPEED)
	{
		m_edtCurSpeed = MAX_STREAM_SPEED;
	}

	KillTimer(m_uiTimerInputStream);
	SetTimer(CONST_INPUT_STREAM,m_edtCurSpeed,NULL);
	CString cstr;
	cstr.Format("%d",m_edtCurSpeed);
	GetDlgItem(IDC_EDT_SPEED)->SetWindowText(cstr);
}

int CPlayDemo_VCDlg::PsPack_StopRecord()
{
	if (m_fpSave != NULL)
	{
		fclose(m_fpSave);
		m_fpSave = NULL;
	}
	m_bGetIFrame = false;
	return 0;
}

int CPlayDemo_VCDlg::PsPack_StartRecord()
{
	PsPack_StopRecord();

	char cFilePath[MAX_PATH] = {0};
	GetModuleFileName(NULL, cFilePath, sizeof(cFilePath));

	for (int i = (int)strlen(cFilePath)-1; i >= 0; i--)
	{
		if (cFilePath[i] == '\\')
		{
			// 			strcpy(cFilePath+i+1, "PsPack_Record");
			strcpy_s(cFilePath+i+1, MAX_PATH, "PsPack_Record");
			break;
		}
	}
	CreateDirectory(cFilePath, NULL);
	SYSTEMTIME st;
	::GetLocalTime(&st);
	CString astrFile;
	astrFile.Format("%s\\PsPack_%02d%02d_%02d%02d%02d.mp4", cFilePath, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
	//m_fpSave = fopen(astrFile.GetBuffer(), "wb");
	m_fpSave = _fsopen(astrFile.GetBuffer(), "wb", _SH_DENYNO);
	// 	errno_t err;
	// 	if( (err  = fopen_s( &m_fpSave, astrFile.GetBuffer(), "wb")) != 0 )
	// 	{
	// 		MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
	// 	}
	return 0;
}

int CPlayDemo_VCDlg::PsPack_InputData( unsigned char* _ucData, int _iSize, int _iType )
{
	if (m_fpSave == NULL)
		PsPack_StartRecord();

	if (m_fpSave != NULL)
	{
		if (_iType == 1)
			m_bGetIFrame = true;

		if (m_bGetIFrame)
		{
			const int iMaxFileSize = 100*1024*1024;     //   10*1024*1024
			if (ftell(m_fpSave) > iMaxFileSize)
			{
				if (_iType == 1)
				{
					PsPack_StopRecord();
					PsPack_StartRecord();
					m_bGetIFrame = true;
				}
				fwrite(_ucData, 1, _iSize, m_fpSave);
			}
			else
				fwrite(_ucData, 1, _iSize, m_fpSave);
		}
	}

	return 0;
}

//PlayVod控件功能实现  杨二星
void CPlayDemo_VCDlg::OnBnClickedBtnPlayVod()
{
	RECT rcDraw = {0};
	CString cstrPathName = _T("");
	char cHeadInfo[88] = "";

	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, _T("All Files (*.*)|*.*||"), NULL);
	if(IDOK == dlgFile.DoModal())
	{
		cstrPathName = dlgFile.GetPathName();

		for(int i = 0; i < 16; ++i)
		{
			m_iSpeed[i] = 0;
		}

		if(g_iPlayerID[m_iCurWinNum]!=-1)
		{
			m_iSpeed[m_iCurWinNum] = 0;
			m_PlaySDK.DeletePlayer(g_iPlayerID[m_iCurWinNum]);
			if(g_pFileHandle[m_iCurWinNum])
			{
				fclose(g_pFileHandle[m_iCurWinNum]);
				g_pFileHandle[m_iCurWinNum] = NULL;
			}
			g_iPlayerID[m_iCurWinNum] = -1;
			m_pDlgVedio[m_iCurWinNum]->Invalidate();
			m_prgPlay.SetPos(0);
		}

		int iCheckResult = CheckFileSize(cstrPathName.GetBuffer());
		if (-1 == iCheckResult)
		{
			MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
			return;
		}
		else if (-2 == iCheckResult)
		{
			MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
			return;
		}

		//g_fp[m_iCurWinNum] = fopen(cstrPathName.GetBuffer(), "rb");
		g_pFileHandle[m_iCurWinNum] = _fsopen(cstrPathName.GetBuffer(), "rb", _SH_DENYNO);

		if (g_pFileHandle[m_iCurWinNum] == NULL)
		{
			MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		}

		fseek(g_pFileHandle[m_iCurWinNum], 0, SEEK_SET);
		fread(cHeadInfo, sizeof(char), 88, g_pFileHandle[m_iCurWinNum]);

		g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayerFromVOD(m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd(), (unsigned char *)cHeadInfo, 88);

		memset(&rcDraw, 0, sizeof(rcDraw));
		m_PlaySDK.SetPlayRect(g_iPlayerID[m_iCurWinNum],&rcDraw);
		m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
		UpdateUI_ShowAudioVolume(g_iPlayerID[m_iCurWinNum]);
		m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;//yangerxing 2014-02-13
		GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
		m_iAudio[m_iCurWinNum] = 1;

		ChangePutSpeed(SPEED_SET);

		m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器
		m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);	  //打开定时器
	}
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);
}

//Clean Buffer控件功能实现  杨二星
void CPlayDemo_VCDlg::OnBnClickedBtnCleanBuffer()
{
	KillTimer(m_uiTimerInputStream);                                     //关闭定时器
	m_PlaySDK.StopAudio(g_iPlayerID[m_iCurWinNum]);
	m_PlaySDK.SetCleanVoDBuffer(g_iPlayerID[m_iCurWinNum]);
	if (1 ==  m_iAudio[m_iCurWinNum])
	{
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
	}
	m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);     //打开定时器
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnGetdecdata()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	if (NULL != g_pfDecV)
	{
		fclose(g_pfDecV);
		g_pfDecV = NULL;
	}

	if (NULL != g_pfDecA)
	{
		fclose(g_pfDecA);
		g_pfDecA = NULL;
	}
	m_PlaySDK.RegisterNotifyGetDecAV(g_iPlayerID[iIndex], (void*)GetDecAVCbk, true);
}

void CPlayDemo_VCDlg::OnBnClickedBtnStopGetdecdata()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	m_PlaySDK.RegisterNotifyGetDecAV(g_iPlayerID[iIndex], (void*)NULL, true);

	if (NULL != g_pfDecV)
	{
		fclose(g_pfDecV);
		g_pfDecV = NULL;
	}

	if (NULL != g_pfDecA)
	{
		fclose(g_pfDecA);
		g_pfDecA = NULL;
	}
}

void CPlayDemo_VCDlg::OnEnSetfocusDectotaltime()
{
	// TODO: Add your control notification handler code here
	if (false == m_bTotalTimeFocus)
	{	
		m_bTotalTimeFocus = true;
		int iIndex = m_iCurWinNum;
		if(g_iPlayerID[iIndex] < 0 || iIndex < 0 || iIndex > MAX_WINDOWNUM)
			return ;

		unsigned int uiBegin = 0, uiEnd = 0;
		m_PlaySDK.GetBeginEndTimeStamp(g_iPlayerID[iIndex], &uiBegin, &uiEnd);
		if(uiEnd-uiBegin < 1000)
		{
			m_iEdtTotalTime = uiEnd - uiBegin;
		}
		else
		{
			m_iEdtTotalTime = (uiEnd - uiBegin) / 1000;
		}
		UpdateData(FALSE);
	}
}

void CPlayDemo_VCDlg::OnEnKillfocusDectotaltime()
{
	// TODO: Add your control notification handler code here
	m_bTotalTimeFocus = false;
}



void CPlayDemo_VCDlg::OnBnClickedBtnVsync()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
	{
		m_iEdtVSync = 0;
		return;
	}
	int iFlag = m_iEdtVSync;
	if(m_PlaySDK.SetVerticalSync(g_iPlayerID[iIndex], iFlag) < 0)
	{
		m_iEdtVSync = 0;
	}
	UpdateData(FALSE);
}

void CPlayDemo_VCDlg::OnBnClickedBtnRecord()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
		return ;
	char cName[40] = {0};
	int i = m_cboRecFileType.GetCurSel();
	int iRecFileType = m_cboRecFileType.GetItemData(m_cboRecFileType.GetCurSel());
	if (REC_FILE_TYPE_NORMAL == iRecFileType)
	{
		sprintf(cName, "c:\\PlayDemo%d.sdv", GetTickCount());
	}
	else if (REC_FILE_TYPE_ZFMP4 == iRecFileType)
	{
		sprintf(cName, "c:\\PlayDemoZF%d.mp4", GetTickCount());
	}
	m_PlaySDK.StartCaptureFile(g_iPlayerID[iIndex], cName, iRecFileType);
}

void CPlayDemo_VCDlg::OnBnClickedBtnStoprec()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
		return ;
	m_PlaySDK.StopCaptureFile(g_iPlayerID[iIndex]);
}

void CPlayDemo_VCDlg::OnBnClickedBtnFindvca()
{
	// TODO: Add your control notification handler code here
	//int iIndex = m_iCurWinNum;
	//if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
	//	return ;

	//int iFrameNo = m_iEditFrame;		//等待王建鹏创建完成后加入
	////    vca_TTripwire tripWire;
	////    memset(&tripWire, 0, sizeof(vca_TTripwire));
	////    tripWire.stLine.stStart.iX = 0;
	////    tripWire.stLine.stStart.iY = 0;
	////    tripWire.stLine.stEnd.iX = 250;
	////    tripWire.stLine.stEnd.iY = 120;
	////    tripWire.iTargetTypeCheck = 1;
	////    tripWire.iDirection = 45;
	////    m_PlaySDK.SearchVCAInfo(iIndex, 2, iFrameNo, &tripWire, sizeof(vca_TTripwire));

	//vca_TPerimeter perimeter;
	//memset(&perimeter, 0, sizeof(vca_TPerimeter));
	//perimeter.stRegion.stPoints[0].iX = 64;
	//perimeter.stRegion.stPoints[0].iY = 44;
	//perimeter.stRegion.stPoints[1].iX = 695;
	//perimeter.stRegion.stPoints[1].iY = 46;
	//perimeter.stRegion.stPoints[2].iX = 595;
	//perimeter.stRegion.stPoints[2].iY = 488;
	//perimeter.stRegion.stPoints[3].iX = 9;
	//perimeter.stRegion.stPoints[3].iY = 462;
	//perimeter.stRegion.iPointNum = 4;
	//perimeter.iMode = 0;
	//unsigned int iFrame = 0;
	//m_PlaySDK.SearchVCAInfo(iIndex, 1, iFrameNo, &perimeter, sizeof(vca_TPerimeter), 1, iFrame);

}

void CPlayDemo_VCDlg::OnBnClickedBtnCaptureaudio()
{
	// TODO: Add your control notification handler code here
	CString strBtnCapture;
	m_btnCaptureAudio.GetWindowText(strBtnCapture);
	if(strBtnCapture == "CaptureAudio")
	{
		m_PlaySDK.RegisterNotifyAudioCapture(OutPutAudio, NULL);
		int iRet = m_PlaySDK.StartAudioCapture(0, 1, 0);
		if(iRet >= 0)
		{
			strBtnCapture = "StopAudioCap";
			m_btnCaptureAudio.SetWindowText(strBtnCapture);
			if(!g_pfPCM)
				//g_pfPCM = fopen("D:\\AudioCap.pcm", "wb");
				g_pfPCM = _fsopen("D:\\AudioCap.pcm", "wb", _SH_DENYNO);
		}
	}
	else if(strBtnCapture == "StopAudioCap")
	{
		m_PlaySDK.RegisterNotifyAudioCapture(NULL, NULL);
		int iRet = m_PlaySDK.StopAudioCapture(0);
		if(iRet >= 0)
		{
			strBtnCapture = "CaptureAudio";
			m_btnCaptureAudio.SetWindowText(strBtnCapture);
			if(g_pfPCM)
			{
				fclose(g_pfPCM);
				g_pfPCM = NULL;
			}
		}
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckDrawmotionarea()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
		return;

	if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHK_DRAWMOTIONAREA))->GetCheck())
	{
		m_PlaySDK.RegisterDrawFun(g_iPlayerID[iIndex], ShowMotionArea, 0);
		m_pDlgVedio[iIndex]->m_bIsCheckArea = true;
	}
	else
	{
		m_PlaySDK.RegisterDrawFun(g_iPlayerID[iIndex], NULL, 0);  
		m_pDlgVedio[iIndex]->m_bIsCheckArea = false;
	}
}

void CPlayDemo_VCDlg::UpdateUI_ShowAudioVolume(const int _iPlayerID)
{
	if (_iPlayerID < 0 && false == m_pDlgVedio[m_iCurWinNum]->m_bIsCheckArea )
	{
		((CButton*)GetDlgItem(IDC_CHK_DRAWMOTIONAREA))->SetCheck(0);
	}
	else if(true == m_pDlgVedio[m_iCurWinNum]->m_bIsCheckArea)
	{
		((CButton*)GetDlgItem(IDC_CHK_DRAWMOTIONAREA))->SetCheck(1);
	}
	UpdateData(true);

	unsigned short usAudioVolume = 0;

	int iRet = m_PlaySDK.GetAudioVolumeEx(_iPlayerID, usAudioVolume);	//得到播放的音量
	m_iEdtAudio = usAudioVolume;
	UpdateData(false);
}
void CPlayDemo_VCDlg::OnBnClickedBtnDrawpolygon()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || g_iPlayerID[iIndex] < 0)
		return;

	m_iCurPlayNum = g_iPlayerID[iIndex];
	m_DlgDrawPolygon.DoModal();	

	POINT pt[2] = {0};
	m_PlaySDK.DrawPolygonOnLocalVideo(g_iPlayerID[iIndex], pt, sizeof(pt)/sizeof(POINT), 0);
	m_PlaySDK.ResetPlayWnd(g_iPlayerID[iIndex], m_pDlgVedio[iIndex]->GetSafeHwnd());

}


void CPlayDemo_VCDlg::OnBnClickedBtnAudio()
{
	// TODO: Add your control notification handler code here
	CString cstrBtnAudio;

	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_btnAudio.GetWindowText(cstrBtnAudio);
	if (cstrBtnAudio == "AudioOpen")
	{
		int iRec = m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
		if (iRec >= 0)
		{
			m_iAudio[m_iCurWinNum] = 1;
			cstrBtnAudio = "AudioStop";
			m_btnAudio.SetWindowText(cstrBtnAudio);
			UpdateUI_ShowAudioVolume(g_iPlayerID[m_iCurWinNum]);
		}

	}
	else if (cstrBtnAudio == "AudioStop")
	{
		int iRec = m_PlaySDK.StopAudio(g_iPlayerID[m_iCurWinNum]);
		if (iRec >= 0)
		{
			m_iAudio[m_iCurWinNum] = 0;
			cstrBtnAudio = "AudioOpen";
			m_btnAudio.SetWindowText(cstrBtnAudio);
		}
	}


}


void CPlayDemo_VCDlg::OnBnClickedBtnCaptureyuv()
{
	// TODO: Add your control notification handler code here
	CString strFileName;
	FILE *fp = NULL;
	int iSize = 0;
	CString cstrPath = _T("");
	CFileDialog dlgFile(FALSE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("yuv420 file|*.yuv||"), NULL);

	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	unsigned char* pData = NULL;
	int iWidth = 0;
	int iHeight = 0;

	if (m_PlaySDK.GetVideoParam(g_iPlayerID[m_iCurWinNum], &iWidth, &iHeight, NULL) < 0 )
	{
		MessageBox("Can't capture for no playing!", "Error",MB_OK );
		return;
	}

	if (iWidth/iHeight >= 2)
	{
		iHeight *= 2;
	} 
	else if(iHeight/iWidth >= 2)
	{
		iWidth *= 2;
	}

	unsigned char* buf = new unsigned char[iWidth*iHeight*2];

	if (buf == NULL)
	{
		MessageBox("new failed", "Error",MB_OK);
		return;
	}
	iSize = m_PlaySDK.CapturePic(g_iPlayerID[m_iCurWinNum], &pData);
	memcpy(buf, pData, iSize);

	time_t timer = time(NULL);
	struct tm *tblock = localtime(&timer);
	int iYear = tblock->tm_year+1900;
	int iMonth = tblock->tm_mon+1;
	int iDay = tblock->tm_mday;
	int iHour = tblock->tm_hour;
	int iMin = tblock->tm_min;
	int iSec = tblock->tm_sec;

	char cFilePath[64] = {0};
	char cFileName[64] = {0};
	sprintf(cFilePath, "C:\\PlayDemo_Capture");
	sprintf(cFileName, "C:\\PlayDemo_Capture\\%d%d%d%d%d%d_%d.yuv",iYear, iMonth, iDay, iHour, iMin, iSec, m_iBmpNum);
	if (!PathIsDirectory(cFilePath))
	{
		CreateDirectory(cFilePath, NULL);
	}

	fp = _fsopen(cFileName, "wb", _SH_DENYNO);
	fwrite(buf, sizeof(char), iSize, fp);
	fclose(fp);


	/*
	if (dlgFile.DoModal() == IDOK)
	{
	cstrPath = dlgFile.GetPathName();
	strFileName = cstrPath + ".yuv";
	fp = _fsopen(strFileName, "wb", _SH_DENYNO);
	fwrite(buf, sizeof(char), iSize, fp);
	fclose(fp);
	}*/
	delete []buf;
}

void CPlayDemo_VCDlg::OnBnClickedBtnCapturebmp()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || g_iPlayerID[m_iCurWinNum]<0)
	{
		MessageBox("Can't capture for no playing!", "Error",MB_OK );
		return;
	}

	time_t timer = time(NULL);
	struct tm *tblock = localtime(&timer);
	int iYear = tblock->tm_year+1900;
	int iMonth = tblock->tm_mon+1;
	int iDay = tblock->tm_mday;
	int iHour = tblock->tm_hour;
	int iMin = tblock->tm_min;
	int iSec = tblock->tm_sec;

	char cFilePath[64] = {0};
	char cFileName[64] = {0};
	sprintf(cFilePath, "C:\\PlayDemo_Capture");
	sprintf(cFileName, "C:\\PlayDemo_Capture\\%d%d%d%d%d%d_%d.bmp",iYear, iMonth, iDay, iHour, iMin, iSec, m_iBmpNum);
	//_mkdir(FileName);
	if (!PathIsDirectory(cFilePath))
	{
		CreateDirectory(cFilePath, NULL);
	}

	m_PlaySDK.CaptureBmpPic(g_iPlayerID[m_iCurWinNum], cFileName);
	m_iBmpNum++;
}

void CPlayDemo_VCDlg::OnBnClickedBtnSearch()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.FastBackward(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}


void CPlayDemo_VCDlg::OnBnClickedBtnPlay()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnPause()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.Pause(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnStep()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.StepForward(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnBackstep()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.StepBackward(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnHome()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.GoBegin(g_iPlayerID[m_iCurWinNum]);
	Sleep(10);
	m_PlaySDK.GoBegin(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnEnd()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.GoEnd(g_iPlayerID[m_iCurWinNum]);
	m_iSpeed[m_iCurWinNum] = 0;
}

void CPlayDemo_VCDlg::OnBnClickedBtnFast()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_iSpeed[m_iCurWinNum]++;

	if (m_iSpeed[m_iCurWinNum] <= 0)
	{
		m_iSpeed[m_iCurWinNum] = 1;
	} 
	else if(m_iSpeed[m_iCurWinNum] >= 4)
	{
		m_iSpeed[m_iCurWinNum] = 4;
	}

	trace_d("Speed: %d --- %d\n", m_iCurWinNum, m_iSpeed[m_iCurWinNum]);
	m_PlaySDK.FastForward(g_iPlayerID[m_iCurWinNum], m_iSpeed[m_iCurWinNum]);
}

void CPlayDemo_VCDlg::OnBnClickedBtnSlow()
{
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_iSpeed[m_iCurWinNum]--;

	if (m_iSpeed[m_iCurWinNum] >= 0)
	{
		m_iSpeed[m_iCurWinNum] = -1;
	} 
	else if(m_iSpeed[m_iCurWinNum] <= -4)
	{
		m_iSpeed[m_iCurWinNum] = -4;
	}

	trace_d("Speed: %d --- %d\n", m_iCurWinNum, m_iSpeed[m_iCurWinNum]);
	m_PlaySDK.SlowForward(g_iPlayerID[m_iCurWinNum], abs(m_iSpeed[m_iCurWinNum]));
}



void CPlayDemo_VCDlg::OnBnClickedBtnSeek()
{
	// TODO: Add your control notification handler code here

	UpdateData(TRUE);
	int iBeginFrame;
	int iEndFrame;
	int iEditFrame = m_iEditFrame;

	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	if (m_PlaySDK.GetBeginEnd(g_iPlayerID[m_iCurWinNum],&iBeginFrame,&iEndFrame) == 0)
	{
		if (iEditFrame<iBeginFrame || iEditFrame>iEndFrame)
		{
			MessageBox("Input value out of range!", "Error", MB_OK);
			return;
		}

		m_PlaySDK.StopAudio(g_iPlayerID[m_iCurWinNum]);
		m_PlaySDK.SeekEx(g_iPlayerID[m_iCurWinNum], iEditFrame);

		if (1 == m_iAudio[m_iCurWinNum])
		{
			m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
		}
		m_iSpeed[m_iCurWinNum] = 0;
	}
	UpdateData(FALSE);	
}

void CPlayDemo_VCDlg::OnBnClickedBtnSetezoom()
{
	// TODO: Add your control notification handler code here
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || g_iPlayerID[iIndex] < 0 || iIndex > MAX_WINDOWNUM)
		return;

	m_iCurPlayNum = g_iPlayerID[iIndex];
	m_DlgEZoom.DoModal();			//显示电子放大窗口
	m_PlaySDK.ResetPlayWnd(g_iPlayerID[iIndex], m_pDlgVedio[iIndex]->GetSafeHwnd());		//重新播放

}

void CPlayDemo_VCDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	switch(nIDEvent)
	{
	case CONST_TIMER_GET_PLAYTIME:
		{
			int iTime = m_PlaySDK.GetPlayTime(g_iPlayerID[m_iCurWinNum]);
			if (iTime == -1)
			{
				return;
			}
			CString cstr;
			cstr.Format("%d",iTime);
			GetDlgItem(IDC_EDT_MSEC)->SetWindowText(cstr);
			cstr.Format("%d",iTime/1000);
			GetDlgItem(IDC_EDT_SEC)->SetWindowText(cstr);
			break;
		}
	case CONST_INPUT_STREAM:
		{
			GetData(0);
		}
		break;
	case CONST_MAIN_TIMER:
		{

			int iNum, iSum;
			if (-1 == g_iPlayerID[m_iCurWinNum])
			{
				m_prgPlay.SetPos(0);
				return;
			}

			iNum = m_PlaySDK.GetPlayingFrameNum(g_iPlayerID[m_iCurWinNum]);
			if(iNum <= 0)
			{
				trace_d("[TForm1::Timer1Timer] ID(%d, %d),PlayingFrameNum(%d)\n", m_iCurWinNum, g_iPlayerID[m_iCurWinNum], iNum);
				m_prgPlay.SetPos(0);
				return;
			}
			iSum = m_PlaySDK.GetFrameCount(g_iPlayerID[m_iCurWinNum]);

			m_prgPlay.SetRange(0, iSum);
			if (iSum > 0)  //进度条刷新   建鹏添加
				m_prgPlay.SetPos(iNum);
			else
				m_prgPlay.SetPos(0);

			if (iSum > 0)
			{
				CString cstriNum , cstriSum;
				cstriNum.Format("%d", iNum);
				cstriSum.Format("%d", iSum);
				AfxGetMainWnd()->SetWindowText(cstriNum + "/" + cstriSum);				
			}
			else
			{
				m_PlaySDK.GetVersion(&m_Version);
				m_cstrVersionString = CString("PlayDemo (SDK ") + m_Version.m_cVerInfo + ")";
				AfxGetMainWnd()->SetWindowText(m_cstrVersionString);
			}
			//音频状态
			if (m_iAudio[m_iCurWinNum] == 0)
				GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioOpen");
			else
				GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");

			//视频跟随
			RECT rcDraw[4];
			for(int i = 0;i<4;i++)
			{
				if(g_iPlayerID[i]!=-1)
				{	
					memset(&rcDraw, 0, sizeof(rcDraw));
					m_PlaySDK.SetPlayRect(g_iPlayerID[i],&rcDraw[i]);
				}
			}
			int iBegin, iEnd;
			if (m_PlaySDK.GetBeginEnd(g_iPlayerID[m_iCurWinNum], &iBegin, &iEnd) == 0)
			{
				CString cstr;
				cstr.Format("%d",iBegin);
				GetDlgItem(IDC_EDT_BEGIN)->SetWindowText(cstr);
				cstr.Format("%d",iEnd);
				GetDlgItem(IDC_EDT_END)->SetWindowText(cstr);
			}
		}
		break;
	case CONST_BATCH_CUDA_TEST:
		{
			OnTimerBatchCudaTest();
		}
		break;
	case CONST_BATCH_CAPTURE_BMP:
		{
			OnTimerBatchCaptureBmp();
		}
		break;
	default:
		break;
	}

	CDialog::OnTimer(nIDEvent);
}

void CPlayDemo_VCDlg::OnDeltaposSpinAudio(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
	// TODO: Add your control notification handler code here
	UpdateData(true);
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex > MAX_WINDOWNUM)
		return;

	if(pNMUpDown->iDelta == -1) // 如果此值为-1 , 说明点击了Spin的往下的箭头
	{		
		m_iEdtAudio = (int)(m_iEdtAudio + 65535*0.02);	
		if ( 65535 < m_iEdtAudio )
		{
			m_iEdtAudio = 65535;
		}
	}
	else if(pNMUpDown->iDelta == 1) // 如果此值为1, 说明点击了Spin的往上的箭头
	{		
		m_iEdtAudio = (int)(m_iEdtAudio - 65535*0.02);	
		if ( 0 > m_iEdtAudio )
		{
			m_iEdtAudio = 0;
		}
	}

	if (g_iPlayerID[iIndex] < 0)
		return;

	int iRet = m_PlaySDK.SetAudioVolumeEx(g_iPlayerID[iIndex], m_iEdtAudio);		//设置播放的音量
	UpdateData(false);
	*pResult = 0;
}

void CPlayDemo_VCDlg::OnNMCustomdrawSldProgress(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.StopAudio(g_iPlayerID[m_iCurWinNum]);
	int iSeekFrameNo = m_sld_progress.GetPos()*m_PlaySDK.GetFrameCount(g_iPlayerID[m_iCurWinNum])/100;
	m_PlaySDK.Seek(g_iPlayerID[m_iCurWinNum], iSeekFrameNo);

	if (1 == m_iAudio[m_iCurWinNum])
	{
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);
	}

	*pResult = 0;
}

//add by yangerxing date:2014-02-12
void CPlayDemo_VCDlg::OnDeltaposSpinSpeed(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
	// TODO: Add your control notification handler code here
	CString cstrSpeed;
	GetDlgItem(IDC_EDT_SPEED)->GetWindowText(cstrSpeed);
	int iCurSpeed = StrToInt(cstrSpeed);

	if(pNMUpDown->iDelta > 0)//点击了向上的箭头
	{	
		iCurSpeed += 20;
		if(iCurSpeed > MAX_STREAM_SPEED)
		{
			SetDlgItemInt(IDC_EDT_SPEED, MAX_STREAM_SPEED);
		}
		else
		{
			SetDlgItemInt(IDC_EDT_SPEED, iCurSpeed);
		}
	}
	else if (pNMUpDown->iDelta < 0) //点击了向下的箭头
	{
		iCurSpeed -= 20;
		if (iCurSpeed < MIN_SPEED)
		{
			SetDlgItemInt(IDC_EDT_SPEED, MIN_SPEED);
		}
		else
		{
			SetDlgItemInt(IDC_EDT_SPEED, iCurSpeed);
		}
	}

	*pResult = 0;
}
BOOL CPlayDemo_VCDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class

	int menuID = LOWORD(wParam);
	switch(menuID)
	{
	case IDR_MNU_NORMAL://登录主机
		OnBnClickedBtnOpenFile();
		break;
	case IDR_MNU_VOD:
		OnBnClickedBtnPlayVod();
		break;
	case IDR_MNU_ALL:
		OnBnClickedBtnOpenAll();
		break;
	default:
		break;
	}
	return CDialog::OnCommand(wParam, lParam);
}

void CPlayDemo_VCDlg::WinHelp(DWORD dwData, UINT nCmd)
{
	// TODO: Add your specialized code here and/or call the base class

	return;

	CDialog::WinHelp(dwData, nCmd);
}

void CPlayDemo_VCDlg::OnBnClickedBtnOpenAll()
{
	CString cstrPath;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("All Files (*.*)|*.*||"), NULL);
	if (dlgFile.DoModal() == IDOK)
	{
		cstrPath = dlgFile.GetPathName();

		if (cstrPath.IsEmpty() || !PathFileExists(cstrPath.GetBuffer()))
		{
			MessageBox( "File not exists", "Error", MB_OK + MB_TOPMOST);
			return;
		}

		for(int i=0; i < MAX_WINDOWNUM; i++)
		{
			if(g_iPlayerID[i] != -1)
			{
				m_iSpeed[i] = 0;
				m_PlaySDK.Stop(g_iPlayerID[i]);
				m_PlaySDK.DeletePlayer(g_iPlayerID[i]);
				if(g_pFileHandle[i])
				{
					fclose(g_pFileHandle[i]);
					g_pFileHandle[i] = NULL;
				}

				g_iPlayerID[i] = -1;
				m_pDlgVedio[i]->Invalidate();
				//m_pDlgVedio[i]->RedrawWindow();
				m_prgPlay.SetPos(0);
			}
		}

		int iCheckResult = CheckFileSize(cstrPath.GetBuffer());
		if (-1 == iCheckResult)
		{
			MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
			return;
		}
		else if (-2 == iCheckResult)
		{
			MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
			return;
		}

		int iBufferSize = 0;
		for(int i=0; i < MAX_WINDOWNUM; i++)
		{
			g_iPlayerID[i] = m_PlaySDK.CreatePlayerFromFile(m_pDlgVedio[i]->GetSafeHwnd(), cstrPath.GetBuffer(), iBufferSize);
			if(g_iPlayerID[i] < 0)
			{
				MessageBox("Incorrect file format!", "Error", MB_OK);
				return;
			}
		}

		int iBegin, iEnd;   //获得第一帧和最后一帧的帧序号 
		for(int i=0;i < MAX_WINDOWNUM; i++)
		{
			if(m_PlaySDK.GetBeginEnd(g_iPlayerID[i],&iBegin,&iEnd) == 0)
			{
				CString cstr;
				cstr.Format("%d",iBegin);
				GetDlgItem(IDC_EDT_BEGIN)->SetWindowText(cstr);
				cstr.Format("%d",iEnd);
				GetDlgItem(IDC_EDT_END)->SetWindowText(cstr);
			}
			m_PlaySDK.Play(g_iPlayerID[i]);
			m_PlaySDK.PlayAudio(g_iPlayerID[i]);
			GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
			m_iAudio[i] = 1;
			m_pDlgVedio[i]->m_blIsPlay = true;
			m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器,功能：获取播放时间
		}
	}

	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);//打开定时器,功能：操作视频
}

void CPlayDemo_VCDlg::OnBnClickedButtonSetFec()
{
	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || g_iPlayerID[iIndex] < 0 || iIndex > MAX_WINDOWNUM)
		return;

	m_iCurPlayNum = g_iPlayerID[iIndex];
	m_FECDlg.DoModal();	

	m_PlaySDK.ResetPlayWnd(g_iPlayerID[iIndex], m_pDlgVedio[iIndex]->GetSafeHwnd());		//重新播放
}

void CPlayDemo_VCDlg::OnBnClickedBtnReverse()
{
	// TODO: Add your control notification handler code here
	// TODO: Add your control notification handler code here
	if (m_iCurWinNum<0 || m_iCurWinNum>15)
	{
		return;
	}

	m_PlaySDK.PlayBackControl(g_iPlayerID[m_iCurWinNum], CTRL_RESVERSE_PLAY, 0, 0, 0);
	//m_iSpeed[m_iCurWinNum] = 0;
}


void CPlayDemo_VCDlg::StartPlayFileWithCuda(int _iPlayWindowIndex, CString _cstrFileName)
{

	if (_iPlayWindowIndex < 0 || _iPlayWindowIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
	{
		return;
	}

	int iCheckResult = CheckFileSize(_cstrFileName.GetBuffer());
	if (-1 == iCheckResult)
	{
		//MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
		return;
	}
	else if (-2 == iCheckResult)
	{
		//MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		return;
	}

	for(int i = 0; i < 16; ++i)
	{
		m_iSpeed[i] = 0;
	}

	//如果当前正在播放，先停止播放
	StopPlayFile(_iPlayWindowIndex);

	g_pFileHandle[_iPlayWindowIndex] = _fsopen(_cstrFileName.GetBuffer(), "rb", _SH_DENYNO);
	if (NULL == g_pFileHandle[_iPlayWindowIndex])
	{
		//MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		return;
	}
	fseek(g_pFileHandle[_iPlayWindowIndex], 0, SEEK_SET);
	char cHeadInfo[88] = {0};
	fread(cHeadInfo, sizeof(char), 88, g_pFileHandle[_iPlayWindowIndex]);

	CudaPlayer tPlayerInfo = {0};
	tPlayerInfo.iSize = sizeof(CudaPlayer);
	tPlayerInfo.hWnd = m_pDlgVedio[_iPlayWindowIndex]->GetSafeHwnd();
	tPlayerInfo.iGpuID = -1;//负载均衡
	memcpy(tPlayerInfo.ucVideoHeadBuf, cHeadInfo, min(PLAY_VIDEO_HEADER_LEN, 88));
	g_iPlayerID[_iPlayWindowIndex] = m_PlaySDK.CreatePlayer(E_CUDA_STREAMPLAYER, &tPlayerInfo, tPlayerInfo.iSize, this);
	if (g_iPlayerID[_iPlayWindowIndex] < 0)
	{
		return;
	}

	m_PlaySDK.SetStreamBufferSize(g_iPlayerID[_iPlayWindowIndex], 4*1024*1024);
	m_PlaySDK.SetFrameListBufferSize(g_iPlayerID[_iPlayWindowIndex], 10*1024*1024);
	m_PlaySDK.SetModeRule(g_iPlayerID[_iPlayWindowIndex], MODERULE_AUTO_ADJUST_STREAM_PLAY_SPEED_NO);
	m_PlaySDK.SetModeRule(g_iPlayerID[_iPlayWindowIndex], MODERULE_AUTO_ADJUST_DRAW_YES);

	RECT rcDraw = {0};
	memset(&rcDraw, 0, sizeof(rcDraw));
	m_PlaySDK.SetPlayRect(g_iPlayerID[_iPlayWindowIndex],&rcDraw);
	m_PlaySDK.Play(g_iPlayerID[_iPlayWindowIndex]);
	m_PlaySDK.PlayAudio(g_iPlayerID[_iPlayWindowIndex]);
	GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
	m_iAudio[_iPlayWindowIndex] = 1;
	m_pDlgVedio[_iPlayWindowIndex]->m_blIsPlay = true;
	m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);
}

void CPlayDemo_VCDlg::StartPlayFileNormal(int _iPlayWindowIndex, CString _cstrFileName)
{
	if (_iPlayWindowIndex < 0 || _iPlayWindowIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
	{
		return;
	}

	int iCheckResult = CheckFileSize(_cstrFileName.GetBuffer());
	if (iCheckResult < 0)
	{
		return;
	}

	for(int i = 0; i < 16; ++i)
	{
		m_iSpeed[i] = 0;
	}

	//如果当前正在播放，先停止播放
	StopPlayFile(_iPlayWindowIndex);	
	FilePlayer tFilePlayInfo = {0};
	tFilePlayInfo.iSize = sizeof(tFilePlayInfo);
	int iLen = min(MAX_FILENAME_LEN, _cstrFileName.GetLength());
	strcpy(tFilePlayInfo.cFileName, _cstrFileName.GetBuffer());
	_cstrFileName.ReleaseBuffer();
	tFilePlayInfo.hWnd = m_pDlgVedio[_iPlayWindowIndex]->GetSafeHwnd();
	g_iPlayerID[_iPlayWindowIndex] = m_PlaySDK.CreatePlayer(E_NORMAL_FILEPLAYER, &tFilePlayInfo, tFilePlayInfo.iSize, this);
	if(g_iPlayerID[_iPlayWindowIndex] < 0)
	{
		out_put_log_info("CreatePlayer Player Failed ! Index = %d", _iPlayWindowIndex);
		return;
	}

	RECT rcDraw = {0};
	memset(&rcDraw, 0, sizeof(rcDraw));
	m_PlaySDK.SetPlayRect(g_iPlayerID[_iPlayWindowIndex],&rcDraw);//设置播放位置和大小 
	int iBegin = 0;
	int iEnd = 0;				//获得第一帧和最后一帧的帧序号 
	if(m_PlaySDK.GetBeginEnd(g_iPlayerID[_iPlayWindowIndex],&iBegin,&iEnd) == 0)
	{
		CString cstr;
		cstr.Format("%d",iBegin);
		GetDlgItem(IDC_EDT_BEGIN)->SetWindowText(cstr);
		cstr.Format("%d",iEnd);
		GetDlgItem(IDC_EDT_END)->SetWindowText(cstr);
	}

	m_PlaySDK.Play(g_iPlayerID[_iPlayWindowIndex]);//播放
	m_PlaySDK.PlayAudio(g_iPlayerID[_iPlayWindowIndex]);//打开音频
	GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
	m_iAudio[_iPlayWindowIndex] = 1;
	m_pDlgVedio[_iPlayWindowIndex]->m_blIsPlay = true;
	m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器,功能：获取播放时间
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);
}

void CPlayDemo_VCDlg::StopPlayFile(int _iPlayWindowIndex)
{
	if (_iPlayWindowIndex < 0 || _iPlayWindowIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
	{
		return;
	}

	if(-1 == g_iPlayerID[_iPlayWindowIndex])
	{
		return;
	}

	m_iSpeed[_iPlayWindowIndex] = 0;

	m_PlaySDK.DeletePlayer(g_iPlayerID[_iPlayWindowIndex]);
	if(g_pFileHandle[_iPlayWindowIndex])
	{
		fclose(g_pFileHandle[_iPlayWindowIndex]);
		g_pFileHandle[_iPlayWindowIndex] = NULL;
	}
	g_iPlayerID[_iPlayWindowIndex]=-1;
	m_pDlgVedio[_iPlayWindowIndex]->Invalidate();
	return;
}

void CPlayDemo_VCDlg::StopPlaySpecial( int _iSpecialPlayIndex)
{
	if (_iSpecialPlayIndex < 0 || _iSpecialPlayIndex >= sizeof(g_iSpecialPlayerID)/sizeof(g_iSpecialPlayerID[0]))
	{
		return;
	}

	if(-1 == g_iSpecialPlayerID[_iSpecialPlayIndex])
	{
		return;
	}

	m_PlaySDK.DeletePlayer(g_iSpecialPlayerID[_iSpecialPlayIndex]);
	if(g_pSpecialFileHandle[_iSpecialPlayIndex])
	{
		fclose(g_pSpecialFileHandle[_iSpecialPlayIndex]);
		g_pSpecialFileHandle[_iSpecialPlayIndex] = NULL;
	}
	g_iSpecialPlayerID[_iSpecialPlayIndex]=-1;
	return;
}

void CPlayDemo_VCDlg::StartBatchCudaTest()
{
	SetDlgItemText(IDC_CHK_CUDA_TEST, "Stop Test");
	EnableWindowNumSelect(false);

	//批量视频切换
	m_uiTimerBatchCudaTest = (unsigned int)SetTimer(CONST_BATCH_CUDA_TEST, BATCH_CUDA_TEST_CHANGE_INTERVAL, NULL);
	PostMessage(WM_TIMER, CONST_BATCH_CUDA_TEST, NULL);
	//批量抓拍
	// 	m_uiTimerBatchCaptureTest = (unsigned int)SetTimer(CONST_BATCH_CAPTURE_BMP, BATCH_CAPTURE_BMP_INTERVAL, NULL);
	// 	PostMessage(WM_TIMER, CONST_BATCH_CAPTURE_BMP, NULL);
}

void CPlayDemo_VCDlg::StopBatchCudaTest()
{
	SetDlgItemText(IDC_CHK_CUDA_TEST, "Cuda Test");
	EnableWindowNumSelect(true);
	int iCurWindowCount = m_iCurVedio_Count * m_iCurVedio_Count;	
	KillTimer(m_uiTimerBatchCaptureTest);
	KillTimer(m_uiTimerBatchCudaTest);
	for (int i = 0; i < iCurWindowCount; i++)
	{
		StopPlayFile(i);
	}

	for (int i = 0; i < MAX_SPECIAL_PLAYER_NUM; i++)
	{
		StopPlaySpecial(i);
	}
}

void CPlayDemo_VCDlg::OnTimerBatchCudaTest()
{
	int iCurWindowCount = m_iCurVedio_Count * m_iCurVedio_Count;

	//Dxva文件播放显示老化
	// 	for (int i = 0; i < iCurWindowCount; i++)
	// 	{
	// 		CString cstrFileName = _T("C:\\CudaTest.sdv");
	// 		StartPlayFileNormal(i, cstrFileName);
	// 	}

	//Cuda解码显示测试
	for (int i = 0; i < iCurWindowCount; i++)
	{
		CString cstrFileName = _T("C:\\CudaTest.sdv");
		StartPlayFileWithCuda(i, cstrFileName);
	}

	//Cuda回调测试
	for (int i = 0; i < MAX_SPECIAL_PLAYER_NUM; i++)
	{
		CString cstrFileName = _T("C:\\CudaTest.sdv");
		StartPlayGetNotifyDataWithCuda(i, cstrFileName);
	}
}

void CPlayDemo_VCDlg::OnTimerBatchCaptureBmp()
{
	int iCurWindowCount = m_iCurVedio_Count * m_iCurVedio_Count;

	for (int i = 0; i < iCurWindowCount; i++)
	{
		CaptureBmp(i);
	}
}

void CPlayDemo_VCDlg::OnBnClickedChkCudaTest()
{
#ifdef CUDA_FILEPLAYER_TEST
	return CudaFilePlayerTest();
#else
	(BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHK_CUDA_TEST))->GetCheck()) ? StartBatchCudaTest() : StopBatchCudaTest();
#endif
}

void CPlayDemo_VCDlg::CudaFilePlayerTest()
{
	CString cstrPath = _T("");
	RECT rcDraw = {0};

	int iIndex = m_iCurWinNum;
	if (iIndex < 0 || iIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
		return;

	CFileDialog dlgFile(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,_T("All Files (*.*)|*.*||"), NULL);
	if (dlgFile.DoModal() == IDOK)
	{
		for(int i = 0; i < 16; ++i)
		{
			m_iSpeed[i] = 0;
		}

		if(g_iPlayerID[m_iCurWinNum]!= -1)
		{
			m_iSpeed[m_iCurWinNum] = 0;

			m_PlaySDK.DeletePlayer(g_iPlayerID[m_iCurWinNum]);
			if(g_pFileHandle[m_iCurWinNum])
			{
				fclose(g_pFileHandle[m_iCurWinNum]);
				g_pFileHandle[m_iCurWinNum] = NULL;
			}
			g_iPlayerID[m_iCurWinNum]=-1;

			m_pDlgVedio[m_iCurWinNum]->Invalidate();
			m_prgPlay.SetPos(0);
		}

		cstrPath = dlgFile.GetPathName();
		int iCheckResult = CheckFileSize(cstrPath.GetBuffer());
		if (-1 == iCheckResult)
		{
			MessageBox("Open File Failed", "Error", MB_OK + MB_TOPMOST);
			return;
		}
		else if (-2 == iCheckResult)
		{
			MessageBox("Big file (>2G) is not supported", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
			return;
		}

		g_pFileHandle[m_iCurWinNum] = _fsopen(cstrPath.GetBuffer(), "rb", _SH_DENYNO);
		if (g_pFileHandle[m_iCurWinNum]== NULL)
		{
			MessageBox("The file was not opened", "Prompt", MB_OK + MB_TOPMOST + MB_ICONINFORMATION);
		}

		CudaFilePlayer tPlayerInfo = {0};
		tPlayerInfo.iSize = sizeof(CudaFilePlayer);
		tPlayerInfo.hWnd = m_pDlgVedio[m_iCurWinNum]->GetSafeHwnd();
		tPlayerInfo.iGpuID = -1;//负载均衡
		memcpy(tPlayerInfo.cFileName, cstrPath.GetBuffer(), min(MAX_FILENAME_LEN, cstrPath.GetLength()));
		g_iPlayerID[m_iCurWinNum] = m_PlaySDK.CreatePlayer(E_CUDA_FILE_ONLYDECODE, &tPlayerInfo, tPlayerInfo.iSize, this);
		if (g_iPlayerID[m_iCurWinNum] < 0)
		{
			return;
		}

		m_PlaySDK.RegisterNotifyGetDecAV(g_iPlayerID[m_iCurWinNum], DecodeAudioVideoNotify, false);

		memset(&rcDraw, 0, sizeof(rcDraw));
		m_PlaySDK.SetPlayRect(g_iPlayerID[m_iCurWinNum],&rcDraw);//设置播放位置和大小 
		int iBegin;
		int iEnd;   //获得第一帧和最后一帧的帧序号 
		if(m_PlaySDK.GetBeginEnd(g_iPlayerID[m_iCurWinNum],&iBegin,&iEnd) == 0)
		{
			CString cstr;
			cstr.Format("%d",iBegin);
			GetDlgItem(IDC_EDT_BEGIN)->SetWindowText(cstr);
			cstr.Format("%d",iEnd);
			GetDlgItem(IDC_EDT_END)->SetWindowText(cstr);
		}

		m_PlaySDK.Play(g_iPlayerID[m_iCurWinNum]);//播放
		m_PlaySDK.PlayAudio(g_iPlayerID[m_iCurWinNum]);//打开音频
		GetDlgItem(IDC_BTN_AUDIO)->SetWindowText("AudioStop");
		m_iAudio[m_iCurWinNum] = 1;
		m_pDlgVedio[m_iCurWinNum]->m_blIsPlay = true;
		m_uiTimerGetPlayTime = (unsigned int)SetTimer(CONST_TIMER_GET_PLAYTIME, 1000, NULL);//打开定时器,功能：获取播放时间
	}
	m_uiTimerMain = (unsigned int)SetTimer(CONST_MAIN_TIMER, 400, NULL);
}

void CPlayDemo_VCDlg::EnableWindowNumSelect( bool _blEnable )
{
	GetDlgItem(IDC_BTN_1)->EnableWindow(_blEnable);
	GetDlgItem(IDC_BTN_4)->EnableWindow(_blEnable);
	GetDlgItem(IDC_BTN_9)->EnableWindow(_blEnable);
	GetDlgItem(IDC_BTN_16)->EnableWindow(_blEnable);
}

void CPlayDemo_VCDlg::CaptureBmp(int _iPlayWindowIndex)
{
	if (_iPlayWindowIndex < 0 || _iPlayWindowIndex >= sizeof(g_iPlayerID)/sizeof(g_iPlayerID[0]))
	{
		return;
	}

	if(-1 == g_iPlayerID[_iPlayWindowIndex])
	{
		return;
	}

	time_t timerCurTime = time(NULL);
	struct tm *ptBlock = localtime(&timerCurTime);
	int iYear = ptBlock->tm_year+1900;
	int iMonth = ptBlock->tm_mon+1;
	int iDay = ptBlock->tm_mday;
	int iHour = ptBlock->tm_hour;
	int iMin = ptBlock->tm_min;
	int iSec = ptBlock->tm_sec;

	char cFilePath[64] = {0};
	char cFileName[64] = {0};
	sprintf(cFilePath, "C:\\PlayDemo_Capture");
	sprintf(cFileName, "C:\\PlayDemo_Capture\\Player%d_%d%d%d%d%d%d_%d.bmp",_iPlayWindowIndex, iYear, iMonth, iDay, iHour, iMin, iSec, m_iBmpNum);
	if (!PathIsDirectory(cFilePath))
	{
		CreateDirectory(cFilePath, NULL);
	}

	int iRet = m_PlaySDK.CaptureBmpPic(g_iPlayerID[_iPlayWindowIndex], cFileName);
	if (iRet < 0)
	{
		int i = 0;
	}
	m_iBmpNum++;
}

void CPlayDemo_VCDlg::StartPlayGetNotifyDataWithCuda( int _iSpecialPlayIndex, CString _cstrFileName )
{
	if (_iSpecialPlayIndex < 0 || _iSpecialPlayIndex >= MAX_SPECIAL_PLAYER_NUM)
	{
		return;
	}

	int iCheckResult = CheckFileSize(_cstrFileName.GetBuffer());
	if (-1 == iCheckResult)
	{
		return;
	}
	else if (-2 == iCheckResult)
	{
		return;
	}

	for(int i = 0; i < 16; ++i)
	{
		m_iSpeed[i] = 0;
	}

	//如果当前正在播放，先停止播放
	StopPlaySpecial(_iSpecialPlayIndex);

	g_pSpecialFileHandle[_iSpecialPlayIndex] = _fsopen(_cstrFileName.GetBuffer(), "rb", _SH_DENYNO);
	if (NULL == g_pSpecialFileHandle[_iSpecialPlayIndex])
	{
		return;
	}
	fseek(g_pSpecialFileHandle[_iSpecialPlayIndex], 0, SEEK_SET);
	char cHeadInfo[88] = {0};
	fread(cHeadInfo, sizeof(char), 88, g_pSpecialFileHandle[_iSpecialPlayIndex]);

	CudaPlayer tPlayerInfo = {0};
	tPlayerInfo.iSize = sizeof(CudaPlayer);
	tPlayerInfo.hWnd = NULL;
	tPlayerInfo.iGpuID = (_iSpecialPlayIndex % 2);	//测试双显卡
	memcpy(tPlayerInfo.ucVideoHeadBuf, cHeadInfo, min(PLAY_VIDEO_HEADER_LEN, 88));
	g_iSpecialPlayerID[_iSpecialPlayIndex] = m_PlaySDK.CreatePlayer(E_CUDA_STREAMPLAYER, &tPlayerInfo, tPlayerInfo.iSize, this);
	if (g_iSpecialPlayerID[_iSpecialPlayIndex] < 0)
	{
		out_put_log_info("[StartPlayGetNotifyDataWithCuda] failed! GuiId = %d", tPlayerInfo.iGpuID);
		return;
	}

	m_PlaySDK.RegisterNotifyGetDecAV(g_iSpecialPlayerID[_iSpecialPlayIndex], DecodeAudioVideoNotify, false);

	m_PlaySDK.SetStreamBufferSize(g_iSpecialPlayerID[_iSpecialPlayIndex], 4*1024*1024);
	m_PlaySDK.SetFrameListBufferSize(g_iSpecialPlayerID[_iSpecialPlayIndex], 10*1024*1024);
	m_PlaySDK.SetModeRule(g_iSpecialPlayerID[_iSpecialPlayIndex], MODERULE_AUTO_ADJUST_STREAM_PLAY_SPEED_NO);
	m_PlaySDK.SetModeRule(g_iSpecialPlayerID[_iSpecialPlayIndex], MODERULE_AUTO_ADJUST_DRAW_YES);

	m_PlaySDK.Play(g_iSpecialPlayerID[_iSpecialPlayIndex]);
	m_PlaySDK.PlayAudio(g_iSpecialPlayerID[_iSpecialPlayIndex]);
	m_uiTimerInputStream = (unsigned int)SetTimer(CONST_INPUT_STREAM, 1000, NULL);
}

void CPlayDemo_VCDlg::Notify_DecodeAudioVideo(int _iPlayerId, DecAVInfo* _pAVInfo)
{
	if (NULL == _pAVInfo || _iPlayerId < 0)
	{
		return;
	}

	DecAVInfoEx tInfo = {0};
	memcpy(&tInfo, _pAVInfo, sizeof(DecAVInfoEx));

	if (AV_CBK_TYPE_VIDEO_CUDA != tInfo.m_pInfo.iType)		//只处理Cuda数据
	{
		return;
	}

	if (tInfo.m_iOtherInfoSize < 0)
	{
		return;
	}

	DecVideoOtherInfo tCudaInfo = {0};
	int iCpyOtherInfoSize = min(tInfo.m_iOtherInfoSize, (int)sizeof(DecVideoOtherInfo));
	memcpy(&tCudaInfo, tInfo.m_pvOtherInfo, iCpyOtherInfoSize);

	if (tCudaInfo.iPitch < 0 || NULL == tCudaInfo.pvCudaContext || NULL == tInfo.m_pInfo.pucData)
	{
		return;
	}

	//按照时间戳每个Player定时抓拍一张
	if (0 != (tCudaInfo.uiTimeStamp / 1000) % 3)
	{
		return;
	}

	CudaCoreMem2D tTempMemcpyInfo = {0};
	unsigned char* pTempNv12DataBuf = NULL;
	LPBYTE pCaptureBuf = NULL;
	FILE* pFile = NULL;
	int iYuv422CpySize = tInfo.m_pInfo.iWidth * tInfo.m_pInfo.iHeight * 2;		//YUV422数据
	int iYuv420MallocSize = tInfo.m_pInfo.iWidth * tInfo.m_pInfo.iHeight * 3 / 2;	

	time_t timer = time(NULL);
	struct tm *tblock = localtime(&timer);
	int iYear = tblock->tm_year+1900;
	int iMonth = tblock->tm_mon+1;
	int iDay = tblock->tm_mday;
	int iHour = tblock->tm_hour;
	int iMin = tblock->tm_min;
	int iSec = tblock->tm_sec;

	char cFilePath[64] = {0};
	char cFileName[64] = {0};


	pTempNv12DataBuf = (unsigned char*)malloc(iYuv420MallocSize);
	if (NULL == pTempNv12DataBuf)
	{
		//TODO ADDLOG
		goto EXIT_FUNC;
	}

	memset(pTempNv12DataBuf, 0, iYuv420MallocSize);
	tTempMemcpyInfo.iSize = (int)sizeof(CudaCoreMem2D);
	tTempMemcpyInfo.iSrcMemoryType = CUDACORE_MEMORYTYPE_DEVICE;
	tTempMemcpyInfo.pvSrc = (void*)tInfo.m_pInfo.pucData;
	tTempMemcpyInfo.iSrcPitch = tCudaInfo.iPitch;
	tTempMemcpyInfo.iDstMemoryType = CUDACORE_MEMORYTYPE_HOST;
	tTempMemcpyInfo.pvDst = pTempNv12DataBuf;
	tTempMemcpyInfo.iDstPitch = tInfo.m_pInfo.iWidth; 
	tTempMemcpyInfo.iWidth = tInfo.m_pInfo.iWidth;
	tTempMemcpyInfo.iHeight = tInfo.m_pInfo.iHeight * 3 / 2;		//矩阵拷贝

	int iRet = CLS_CudaDecApi::Instance()->CudaCoreMemcpy2D(tCudaInfo.pvCudaContext, &tTempMemcpyInfo);
	if (iRet < 0)
	{
		//TODO ADDLOG
		goto EXIT_FUNC;
	}


	pCaptureBuf = (LPBYTE)malloc(iYuv422CpySize);
	if (NULL == pCaptureBuf)
	{
		//TODO ADDLOG
		goto EXIT_FUNC;
	}
	memset(pCaptureBuf, 0, iYuv422CpySize);
	Nv12toYuyv((unsigned char*)pTempNv12DataBuf, tInfo.m_pInfo.iWidth, tInfo.m_pInfo.iHeight, pCaptureBuf, tInfo.m_pInfo.iWidth * 2, tInfo.m_pInfo.iWidth, tInfo.m_pInfo.iHeight);

	int iGpuId = CLS_CudaDecApi::Instance()->CudaCoreGetGpuID(tCudaInfo.pvCudaContext);
	sprintf(cFilePath, "C:\\PlayDemo_Capture");
	sprintf(cFileName, "C:\\PlayDemo_Capture\\Player%d(Gpu%d)_%d%d%d%d%d%d_%d.yuv", _iPlayerId, iGpuId, iYear, iMonth, iDay, iHour, iMin, iSec, m_iBmpNum);
	if (!PathIsDirectory(cFilePath))
	{
		CreateDirectory(cFilePath, NULL);
	}

	pFile = _fsopen(cFileName, "wb", _SH_DENYNO);
	if (NULL == pFile)
	{
		//TODO ADDLOG
		goto EXIT_FUNC;
	}
	fwrite(pCaptureBuf, sizeof(char), iYuv422CpySize, pFile);

EXIT_FUNC:
	if (NULL != pFile)
	{
		fclose(pFile);
		pFile = NULL;
	}

	if (NULL != pTempNv12DataBuf)
	{
		free(pTempNv12DataBuf);
		pTempNv12DataBuf = NULL;
	}

	if (NULL != pCaptureBuf)
	{
		free(pCaptureBuf);
		pCaptureBuf = NULL;
	}

	return;
}




void CPlayDemo_VCDlg::OnBnClickedBtnStartDrawrect()
{
	if (m_iCurWinNum < 0 || m_iCurWinNum > 15)
	{
		return;
	}

	DrawFaceInfo tInfo = {sizeof(tInfo), DRAW_FACE_TYPE_RECT, 1};//开启画线

	m_PlaySDK.PlayBackControl(g_iPlayerID[m_iCurWinNum], CTRL_DRAW_FACE_PARAM, &tInfo, sizeof(DrawFaceInfo),NULL);	
}

void CPlayDemo_VCDlg::OnBnClickedBtnStopDrawrect()
{
	if (m_iCurWinNum < 0 || m_iCurWinNum > 15)
	{
		return;
	}

	DrawFaceInfo tInfo = {sizeof(tInfo), DRAW_FACE_TYPE_RECT, 0};//关闭画线

	m_PlaySDK.PlayBackControl(g_iPlayerID[m_iCurWinNum], CTRL_DRAW_FACE_PARAM, &tInfo, sizeof(DrawFaceInfo),NULL);	
}

void CPlayDemo_VCDlg::OnBnClickedCheckDxvaHw()
{
	if (BST_CHECKED == m_chkDxvaHardDecode.GetCheck())
	{
		//设置dxva硬解
		HwDecodeParam tHwDecInfo = {0};
		tHwDecInfo.iSize = sizeof(HwDecodeParam);
		tHwDecInfo.iLimitType = HWDEC_LIMIT_LOCAL;
		tHwDecInfo.iMaxCount = 100;
		tHwDecInfo.iEnableFlag = HWDEC_ENABLE_STREAM | HWDEC_ENABLE_VOD | HWDEC_ENABLE_FILE;
		m_PlaySDK.SetAVMode(CMD_AV_DEC_HWDECODE_PARAM, &tHwDecInfo, sizeof(HwDecodeParam));
		m_chkPrivateSoftDecode.SetCheck(BST_UNCHECKED);
		m_chkFfmpegSoftDecode.SetCheck(BST_UNCHECKED);
	}
	else
	{
		HwDecodeParam tHwDecInfo = {0};	//参数清零即可
		tHwDecInfo.iSize = sizeof(HwDecodeParam);
		m_PlaySDK.SetAVMode(CMD_AV_DEC_HWDECODE_PARAM, &tHwDecInfo, sizeof(HwDecodeParam));
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckPrivateDecoder()
{
	if (BST_CHECKED == m_chkPrivateSoftDecode.GetCheck())
	{
		//先取消硬解功能
		HwDecodeParam tHwDecInfo = {0};	
		tHwDecInfo.iSize = sizeof(HwDecodeParam);
		m_PlaySDK.SetAVMode(CMD_AV_DEC_HWDECODE_PARAM, &tHwDecInfo, sizeof(HwDecodeParam));

		int iVideoDecLib = VIDEO_DLIB_HISI;
		m_PlaySDK.SetAVMode(CMD_AVMODE_VIDEO_DECLIB, &iVideoDecLib, sizeof(int));
		m_chkFfmpegSoftDecode.SetCheck(BST_UNCHECKED);
		m_chkDxvaHardDecode.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckFfmpegDecoder()
{
	if (BST_CHECKED == m_chkFfmpegSoftDecode.GetCheck())
	{
		//先取消硬解功能
		HwDecodeParam tHwDecInfo = {0};	//参数清零即可
		tHwDecInfo.iSize = sizeof(HwDecodeParam);
		m_PlaySDK.SetAVMode(CMD_AV_DEC_HWDECODE_PARAM, &tHwDecInfo, sizeof(HwDecodeParam));

		int iVideoDecLib = VIDEO_DLIB_FFMPEG;
		m_PlaySDK.SetAVMode(CMD_AVMODE_VIDEO_DECLIB, &iVideoDecLib, sizeof(int));
		m_chkPrivateSoftDecode.SetCheck(BST_UNCHECKED);
		m_chkDxvaHardDecode.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckVideoRenderD3d()
{
	if (BST_CHECKED == m_chkVideoRenderD3D.GetCheck())
	{
		int iRenderType = SHOW_MAIN_MODE_D3D;
		m_PlaySDK.SetAVMode(CMD_VIDEO_SHOW_MAIN_MODE, &iRenderType, sizeof(int));
		m_chkVideoRenderDraw.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckVideoRenderDraw()
{
	if (BST_CHECKED == m_chkVideoRenderDraw.GetCheck())
	{
		int iRenderType = SHOW_MAIN_MODE_DRAW;
		m_PlaySDK.SetAVMode(CMD_VIDEO_SHOW_MAIN_MODE, &iRenderType, sizeof(int));
		m_chkVideoRenderD3D.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckVideoDisplay422()
{
	if (BST_CHECKED == m_chkVideoDispalyYuv422.GetCheck())
	{
		int iDisplayMode = SHOW_SUB_MODE_YUV422;
		m_PlaySDK.SetAVMode(CMD_VIDEO_SHOW_SUB_MODE, &iDisplayMode, sizeof(int));
		m_chkVideoDispalyYuv420.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckVideoDisplay420()
{
	if (BST_CHECKED == m_chkVideoDispalyYuv420.GetCheck())
	{
		int iDisplayMode = SHOW_SUB_MODE_YUV420;
		m_PlaySDK.SetAVMode(CMD_VIDEO_SHOW_SUB_MODE, &iDisplayMode, sizeof(int));
		m_chkVideoDispalyYuv422.SetCheck(BST_UNCHECKED);
	}
}

void CPlayDemo_VCDlg::OnBnClickedCheckSync()
{
	if (m_iCurWinNum < 0 || m_iCurWinNum >= MAX_WINDOWNUM)
	{
		return;
	}

	if (NULL == m_pDlgVedio[m_iCurWinNum] || g_iPlayerID[m_iCurWinNum] < 0)
	{
		return;
	}

	int iCheck = m_chkSync.GetCheck();
	int iRet = -1;
	if (iCheck)
	{
		iRet = m_PlaySDK.SycAddPlayer(SYNC_PLAY_FIRSR_GROUP, g_iPlayerID[m_iCurWinNum]);
	}
	else
	{
		iRet = m_PlaySDK.SycDelPlayer(SYNC_PLAY_FIRSR_GROUP, g_iPlayerID[m_iCurWinNum]);
	}

	if (iRet >= 0)
	{
		m_pDlgVedio[m_iCurWinNum]->SetPlaySync(iCheck);
	}
}

void CPlayDemo_VCDlg::OnBnClickedBtnReverseStep()
{
	CHECK_NOT_IN_RET_VOID(m_iCurWinNum, 0, MAX_WINDOWNUM);
	m_PlaySDK.StepForward(g_iPlayerID[m_iCurWinNum]);
}
void CPlayDemo_VCDlg::OnBnClickedCheckSaveUserData()
{
	// TODO: 在此添加控件通知处理程序代码
	if (BST_CHECKED == m_chkSaveUserData.GetCheck())
	{
		if (m_pfSaveUserDataFile)
		{
			fclose(m_pfSaveUserDataFile);
		}
		m_pfSaveUserDataFile = fopen(cUserDataFileName.GetBuffer(),"w+");

		if (m_hThreadHdl)
		{
			m_hThreadHdl = NULL;
			iThreadFlag = false;
		}
		iThreadFlag = true;
		m_hThreadHdl = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SaveUserDataThread, this, 0, NULL);
		CloseHandle(m_hThreadHdl);
		if (NULL == m_hThreadHdl)
		{
			iThreadFlag = false;
			MessageBox("Create SaveUserDataThread Error", "Error", MB_OK);
			return ;
		}
	}
	else
	{
		if (m_pfSaveUserDataFile)
		{
			fclose(m_pfSaveUserDataFile);
			m_pfSaveUserDataFile = NULL;
		}

		if (m_hThreadHdl)
		{
			m_hThreadHdl = NULL;
			iThreadFlag = false;
		}
	}
}

void __stdcall CPlayDemo_VCDlg::DevUserDataNotify(unsigned int _uiID, int _iType, void* _pvData, int _iDataLen, CurrentFrameInfo* _ptInfo, void* _pvUdata)
{
	if (NULL != _pvUdata)
	{
		//CPlayDemo_VCDlg* pThis = (CPlayDemo_VCDlg*)_pvUdata;
		//if (BST_CHECKED == pThis->m_chkSaveUserData.GetCheck())
		//{
		//	DemoUserData* tTemp = (DemoUserData*)malloc(sizeof(DemoUserData));
		//	char* cTemp = (char*)malloc(_iDataLen);
		//	tTemp->uiFrameNo = _ptInfo->uiFrameNO;
		//	tTemp->uiTimeStamp = _ptInfo->uiTimeStamp;
		//	tTemp->iUserDataType = _iType;
		//	memcpy(cTemp, _pvData, _iDataLen);
		//	tTemp->pvUserData = cTemp;
		//	tTemp->iUserDataSize = _iDataLen;
		//	EnterCriticalSection(&pThis->m_tLockLst);
		//	pThis->m_lstUsrData.push_back(tTemp);
		//	LeaveCriticalSection(&pThis->m_tLockLst);
		//}
	}
}

unsigned int WINAPI CPlayDemo_VCDlg::SaveUserDataThread(LPVOID _Param)
{
	CPlayDemo_VCDlg* pThis = (CPlayDemo_VCDlg*)_Param;
	if (NULL == pThis)
	{
		return RET_FAILED;
	}

	DemoUserData* block = NULL;
	while (iThreadFlag)
	{
		::EnterCriticalSection(&pThis->m_tLockLst);
		if (!pThis->m_lstUsrData.empty())
		{
			block = pThis->m_lstUsrData.front();
			pThis->SaveUserDataToLocalFile(block);
			pThis->m_lstUsrData.pop_front();	
			free(block->pvUserData);
			block->pvUserData = NULL;
			free(block);
			block = NULL;
		}
		::LeaveCriticalSection(&pThis->m_tLockLst);

		if (pThis->m_lstUsrData.empty())
		{
			Sleep(100);
		}
	}
	return RET_SUCCESS;
}

void CPlayDemo_VCDlg::SaveUserDataToLocalFile(DemoUserData* _pDemoUserData)
{
	if (m_pfSaveUserDataFile)
	{ 
		switch (_pDemoUserData->iUserDataType)
		{
		case USERDATA_FLAG_FRAMETIME:	//绝对时间	
			{
				NVS_FILE_TIME tTime = {0};
				seconds_to_file_time(&tTime,*(int*)_pDemoUserData->pvUserData);
				fprintf(m_pfSaveUserDataFile,"0XFED3 绝对时间 frameno: %d TimeStamp: %d 本地时间: %d-%d-%d %d:%d:%d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,tTime.iYear
					,tTime.iMonth
					,tTime.iDay
					,tTime.iHour
					,tTime.iMinute
					,tTime.iSecond);
			}
		break;
		case USERDATA_FLAG_VCA_SRC_SIZE:	//行为分析数据	
			{
				vca_TTargetSet temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFED2 行为分析数据 frameno: %d TimeStamp: %d 目标个数: %d\n\r"
				,_pDemoUserData->uiFrameNo
				,_pDemoUserData->uiTimeStamp
				,temp.usCount);
				for (int iCount = 0; iCount < temp.usCount; iCount++)
				{
					fprintf(m_pfSaveUserDataFile,"  type%d: 算法类型 %d: 坐标(left=%d,Top=%d,Right=%d,Bottom=%d) 速度，人脸时表示场景高16位: %d 方向，人脸时表示场景低16位: %d 目标ID: %d\n\r"
						,iCount
						,temp.targets[iCount].usType
						,temp.targets[iCount].rect.usLeft
						,temp.targets[iCount].rect.usTop
						,temp.targets[iCount].rect.usRight
						,temp.targets[iCount].rect.usBottom
						,temp.targets[iCount].usVelocity
						,temp.targets[iCount].usDirection
						,temp.targets[iCount].id);
				}
			}
		break;
		case USERDATA_FLAG_LPR:	//车牌识别结果	
			{
				Tvca_LPRInfo temp ={0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize - sizeof(int));
				fprintf(m_pfSaveUserDataFile,"0xFED5 车牌识别结果 frameno: %d TimeStamp: %d 车身颜色(R=%d,G=%d,B=%d) 车牌颜色: %d 车辆类型: %d 车牌类型: %d 车标类型: %d 违法类型: %d 车牌位置矩形(Top=%d,Bottom=%d,Left=%d,Right=%d) 人脸坐标矩形(Top=%d,Bottom=%d,Left=%d,Right=%d) 车标坐标矩形(Top=%d,Bottom=%d,Left=%d,Right=%d) 车牌号: %s 车头还是车尾: %d 副驾驶人脸坐标矩形(Top=%d,Bottom=%d,Left=%d,Right=%d) 车辆轮廓(Top=%d,Bottom=%d,Left=%d,Right=%d)\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.stCarColor.ucR
					,temp.stCarColor.ucG
					,temp.stCarColor.ucB
					,temp.iPlateColor
					,temp.iCarType
					,temp.iPlateType
					,temp.iBrandType
					,temp.iIllgalType
					,temp.stRectPlate.iTop
					,temp.stRectPlate.iBottom
					,temp.stRectPlate.iLeft
					,temp.stRectPlate.iRight
					,temp.stRectFace.iTop
					,temp.stRectFace.iBottom
					,temp.stRectFace.iLeft
					,temp.stRectFace.iRight
					,temp.stRectLogo.iTop
					,temp.stRectLogo.iBottom
					,temp.stRectLogo.iLeft
					,temp.stRectLogo.iRight
					,temp.cPlateRec
					,temp.iHeadTail
					,temp.stRectCopilotFace.iTop
					,temp.stRectCopilotFace.iBottom
					,temp.stRectCopilotFace.iLeft
					,temp.stRectCopilotFace.iRight
					,temp.stCarRegion.iTop
					,temp.stCarRegion.iBottom
					,temp.stCarRegion.iLeft
					,temp.stCarRegion.iRight);
			}
		break;
		case USERDATA_FLAG_AVRESULT:	//音视频诊断结果	
			{
				TVcaAVanalysEx temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFED6 音视频诊断结果 frameno: %d TimeStamp: %d 输出结果的数目: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.iNumOutputs);
				for (int iCount = 0; iCount < temp.iNumOutputs; iCount++)
				{
					fprintf(m_pfSaveUserDataFile,"  iCount%d: 诊断类型(0-255为视频诊断结果，256-512为音频诊断结果): %d 诊断值(0-100): %d\n\r"
						,iCount
						,temp.m_analysInfo[iCount].m_type
						,temp.m_analysInfo[iCount].m_value);
				}
			}
		break;
		case USERDATA_FLAG_VCA_VIDEOSIZE:	//智能分析输入视频大小	
			{
				TAnalysSize temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFED7 智能分析输入视频大小 frameno: %d TimeStamp: %d 视频宽: %d 视频高: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.m_width
					,temp.m_height);
			}
		break;
		case USERDATA_FLAG_DEMOGRAPHICS:	//人数统计结果	
			{
				Tvca_CpcDate temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFED9 人数统计结果 frameno: %d TimeStamp: %d 入人数: %d 出人数 %d 差值 %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.m_cpcInfo.sCountIn
					,temp.m_cpcInfo.sCountOut
					,temp.VCATarget.usCount);
				for (int iCount = 0; iCount < temp.VCATarget.usCount; iCount++)
				{
					fprintf(m_pfSaveUserDataFile,"  iCount%d: 算法类型 %d 坐标(left=%d,Top=%d,Right=%d,Bottom=%d)  速度，人脸时表示场景高16位 %d 方向，人脸时表示场景低16位: %d 目标ID: %d\n\r"
						,iCount
						,temp.VCATarget.targets[iCount].usType
						,temp.VCATarget.targets[iCount].rect.usLeft
						,temp.VCATarget.targets[iCount].rect.usTop
						,temp.VCATarget.targets[iCount].rect.usRight
						,temp.VCATarget.targets[iCount].rect.usBottom
						,temp.VCATarget.targets[iCount].usVelocity
						,temp.VCATarget.targets[iCount].usDirection
						,temp.VCATarget.targets[iCount].id);
				}
			}
		break;
		case USERDATA_FLAG_LIFE_MONITOR:	//生命体征数据	
			{
				VitalSignData temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEDA 生命体征数据 frameno: %d TimeStamp: %d 协议版本 %d 生命体征采集类型 %d 状态 %d OscilloGramSeqID %d 体征实时值(%d,%d,%d,%d) GramRate %d SizeType %d XPosition %d YPosition %d PointLen %d PointValue %s\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.cVersion
					,temp.cType
					,temp.cMonFlg
					,temp.iOscilloGramSeqID
					,temp.iMonVal[0]
					,temp.iMonVal[1]
					,temp.iMonVal[2]
					,temp.iMonVal[3]
					,temp.iGramRate
					,temp.iSizeType
					,temp.iXPosition
					,temp.iYPosition
					,temp.iPointLen
					,temp.cPointValue);
			}
		break;
		case USERDATA_FLAG_ENVIRONMENT_DATA:	//环境数据	
			{
				TEnvironment temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEDB 环境数据 frameno: %d TimeStamp: %d 输出结果的数目 %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.iCount);
				for (int iCount = 0; iCount < temp.iCount; iCount++)
				{
					fprintf(m_pfSaveUserDataFile,"  iCount%d: 数据类型 %d 数值 %d\n\r"
						,iCount
						,temp.m_strData[iCount].m_iType
						,temp.m_strData[iCount].m_iValue);
				}
			}
		break;
		case USERDATA_FLAG_OSD_EX:	//字符叠加数据	
			{
				osd_TOSDSet temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0xFEDC 字符叠加数据 frameno: %d TimeStamp: %d 字符叠加类型 %d 背景颜色 %d 要叠加文本的颜色 %d OSDSize %d 透明度 %d 横坐标或位置编号 %d OSDPostionY %d 长度 %d 字符叠加内容 %s\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.uiOSDType
					,temp.uiOSDBGColor
					,temp.uiOSDColor
					,temp.uiOSDSize
					,temp.uiOSDDiaphaneity
					,temp.uiOSDPostionX
					,temp.uiOSDPostionY
					,temp.ilength
					,temp.cText);
			}
		break;
		case USERDATA_FLAG_LDC:	//畸变矫正数据	
			{
				osd_TLDCSet temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0xFEDD 畸变矫正数据 frameno: %d TimeStamp: %d 畸变矫正类型 %d 长度 %d 64Fx %ld 64Fy %ld 64Cx %ld 64Cy %ld\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.iType
					,temp.ilength
					,temp.tUdtCameraPara.f64Fx
					,temp.tUdtCameraPara.f64Fy
					,temp.tUdtCameraPara.f64Cx
					,temp.tUdtCameraPara.f64Cy);
				for (int iCount = 0; iCount < 12; iCount++)
				{
					fprintf(m_pfSaveUserDataFile,"  64K[%d] %ld ",iCount,temp.tUdtCameraPara.af64K[iCount]);
				}
				fprintf(m_pfSaveUserDataFile,"\r\n");		
			}
		break;
		case USERDATA_FLAG_ZF:	//政法重点标记数据	
			{
				TUserSignPara temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0xFEDE 政法重点标记数据 frameno: %d TimeStamp: %d 用户数据类型 %d 视频通道 %d 有无音频 %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.m_iUserSignType
					,temp.m_iChn
					,temp.m_iAudioTagStat);
			}
		break;
		case USERDATA_FLAG_TIMESTAMP:	//时间戳	
			{
				int iTimeStamp = 0;
				memcpy(&iTimeStamp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0xFEDF 时间戳 frameno: %d TimeStamp: %d 时间戳 %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,iTimeStamp);
			}
		break;
		case USERDATA_FLAG_VCA_STATICLINE:	//智能分析静态线	
			{
				TRuleData temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, sizeof(temp));
				TLineInfo tInfo = {0};
				fprintf(m_pfSaveUserDataFile,"0XFEE1 智能分析静态线 frameno: %d TimeStamp: %d 场景: %d 算法类型: %d 规则号: %d 是否显示报警规则: %d 单个静态线信息大小: %d 静态线个数: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.uiScene
					,temp.ucType
					,temp.ucRule
					,temp.ucOsd
					,temp.ucLen
					,temp.ucLine_num);
				for (int iCount = 0; iCount < temp.ucLine_num; iCount++)
				{
					memset(&tInfo, 0, sizeof(tInfo));
					memcpy(&tInfo, (char*)_pDemoUserData->pvUserData + sizeof(temp) + iCount * temp.ucLen, temp.ucLen);
					fprintf(m_pfSaveUserDataFile,"  iCount%d: 是否封闭: %d 顶点个数: %d "
						,iCount
						,tInfo.close
						,tInfo.point_num);
					for (int iPoint = 0; iPoint < tInfo.point_num; iPoint++)
					{
						fprintf(m_pfSaveUserDataFile,"坐标%d(x=%d, y=%d) "
							,iPoint
							,tInfo.points[iPoint].x
							,tInfo.points[iPoint].y);
					}
					fprintf(m_pfSaveUserDataFile,"\r\n");
				}
			}	
		break;
		case USERDATA_FLAG_PTZ:					//PTZ信息
			{
				TPtzInfo temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0xFEE2 PTZ信息 frameno: %d TimeStamp: %d 当前水平坐标 0~36000  对应0-360度: %d 当前垂直坐标 1000~19000  对应-90-90度: %d 当前倍率 0~100000 对应0-1000倍: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.iPanPosition
					,temp.iTiltPosition
					,temp.iZoomPosition);
			}
		break;
		case USERDATA_FLAG_TARGET_ATTR:			//行为分析目标属性
			{
				TTargetAttr tAttr = {0};
				memcpy(&tAttr, _pDemoUserData->pvUserData, sizeof(tAttr));
				CHECK_NOT_IN_RET_VOID(tAttr.m_sTarget_num, 0, MAX_SAVE_TARGET_NUM); 

				unsigned short usAttrInfoSize = 0;
				memcpy(&usAttrInfoSize, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize, sizeof(short));
				//m_sAttrNumEx字段不一定有
				unsigned short usAttrNumEx = 0;
				if (usAttrInfoSize == 8)
				{
					memcpy(&usAttrNumEx, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize+6, sizeof(short));
				}
				unsigned short usAttrParaSize = 0;
				memcpy(&usAttrParaSize, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize+usAttrInfoSize, sizeof(short));
				unsigned short usAttrNum = 0;
				int i = 0;
				fprintf(m_pfSaveUserDataFile,"0XFEE0 行为分析目标属性 FrameNo: %d TimeStamp: %d 目标个数: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,tAttr.m_sTarget_num);
				for (i=0; i < tAttr.m_sTarget_num; i++)
				{
					TTargetAttrInfo tAttrInfo = {0};
					memcpy(&tAttrInfo, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize+usAttrInfoSize*i+sizeof(int)*usAttrNum*i+sizeof(TTargetAttrParaEx)*usAttrNumEx*i, usAttrInfoSize);
					if (tAttrInfo.m_sAttrNum <= 0)
					{
						return;
					}

					usAttrNum = tAttrInfo.m_sAttrNum;
					usAttrNumEx = tAttrInfo.m_sAttrNumEx;
					int j = 0;
					for (j=0; j < tAttrInfo.m_sAttrNum; j++)
					{
						TTargetAttrPara tPara = {0};
						memcpy(&tPara, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize+usAttrInfoSize*(i+1)+sizeof(TTargetAttrPara)*usAttrNum*i+sizeof(TTargetAttrParaEx)*usAttrNumEx*i+sizeof(TTargetAttrPara)*j, sizeof(TTargetAttrPara));
						fprintf(m_pfSaveUserDataFile,"  目标%d:  目标ID: %d 目标属性[%d]: %08x\n\r"
							,i
							,tAttrInfo.m_sId
							,j
							,tPara.m_iAttrPara);
					}

					if (usAttrNumEx > 0)
					{
						int k = 0;
						for (k=0; k < usAttrNumEx; k++)
						{
							TTargetAttrParaEx tParaEx = {0};
							memcpy(&tParaEx, (char*)_pDemoUserData->pvUserData+tAttr.m_sSize+usAttrInfoSize*(i+1)+sizeof(int)*usAttrNum*(i+1)+sizeof(TTargetAttrParaEx)*usAttrNumEx*i+sizeof(TTargetAttrParaEx)*k, sizeof(TTargetAttrParaEx));
							fprintf(m_pfSaveUserDataFile,"  TargetNo: %d Id: %d cAttrParaEx[%d]: %s\n\r"
								,i
								,tAttrInfo.m_sId
								,k
								,tParaEx.m_cAttrPara);
						}
					}
				}

			}
		break;
		case USERDATA_FLAG_DEMOGRAPHICSEX:			//人数统计增量扩展数据
			{
				Tvca_cpcInfoV1 temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEE4 人数统计增量扩展数据 FrameNo: %d TimeStamp: %d 不跨线人员的增量数据: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.m_AddPass);
			}	
		break;
		case USERDATA_FLAG_DEMOGRAPHICS_HISTORY:		//人数统计历史数据
			{
				Tvca_cpcInfoV3 temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEE5 人数统计历史数据 FrameNo: %d TimeStamp: %d 按位表示数据有效类型(bit0-in，bit1-out，bit2-pass): %d 入人数: %d 出人数: %d 差值: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.m_value
					,temp.m_countIn
					,temp.m_countOut
					,temp.m_countPass);
			}	
		break;
		case USERDATA_FLAG_WATER_SPEED_BASE:			//水利流速基础信息
			{
				TWaterSpeedBase temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEE6 水利流速基础信息 FrameNo: %d TimeStamp: %d 当前水平坐标(p*10000，p：[0,360]): %d 当前垂直坐标(t*10000, t：[-90,90]): %d 变倍对应电机的实际步数: %d 设备vi宽度: %d 设备vi高度: %d 相机高程，单位mm: %d 水位高度，单位mm: %d 相机水平中线对应的实际场景宽度，单位mm * 10000: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.ptz.m_PanPosition
					,temp.ptz.m_TiltPosition
					,temp.ptz.m_ZoomPosition
					,temp.video.Width
					,temp.video.Height
					,temp.scene.altitude
					,temp.scene.waterlevel
					,temp.scene.width);
			}	
		break;
		case USERDATA_FLAG_WATER_SPEED_ALGINFO:			//水利流速算法原始数据
			{
				UserDataTWSPointInfo temp[WATER_SPEED_POINT_NUM] = {0};
				memcpy(temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEE7 水利流速算法原始数据 FrameNo: %d TimeStamp: %d Count[0]: (x: %d y: %d time: %d)  Count[1]: (x: %d y: %d time: %d)\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp[0].x
					,temp[0].y
					,temp[0].time
					,temp[1].x
					,temp[1].y
					,temp[1].time);
			}	
		break;
		case USERDATA_FLAG_VIRTUALGAUGE:		//虚拟水尺数据
			{
				TUserData_Gauge temp = {0};
				memcpy(&temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				fprintf(m_pfSaveUserDataFile,"0XFEE8 虚拟水尺数据  FrameNo: %d TimeStamp: %d 刻度线长度(万分比): %d 刻度线宽度(万分比): %d 相对刻度单位(0-m，1-dm，2-cm，3-mm): %d 绝对刻度单位(0-m，1-dm 2-cm，3-mm: %d 水尺横坐标位置(万分比): %d 绝对刻度线坐标(万分比): %d 相对刻度点个数: %d 绝对刻度值: %d 水尺颜色(rgb): %d 水尺纵坐标(万分比): %d 水尺相对刻度: %d\n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,temp.base.lineLength
					,temp.base.lineWidth
					,temp.base.relativeUnit
					,temp.base.absoluteUnit
					,temp.base.x
					,temp.base.y
					,temp.base.relativeNum
					,temp.base.absolute
					,temp.base.color
					,temp.gauge.y
					,temp.gauge.high);
			}	
		break;
		case USERDATA_FLAG_ILLEGAL_AREA:		//违停球违停区域坐标数据
			{
				TIllegalParkInfo temp[MAX_AREA_NUM_EX] = {0};
				memcpy(temp, _pDemoUserData->pvUserData, _pDemoUserData->iUserDataSize);
				int i = 0;
				int j = 0;
				int iTIllegalParkInfoNum = _pDemoUserData->iUserDataSize / sizeof(TIllegalParkInfo);
				fprintf(m_pfSaveUserDataFile,"0XFEE9 违停球违停区域坐标数据 FrameNo: %d TimeStamp: %d 区域数量 %d \n\r"
					,_pDemoUserData->uiFrameNo
					,_pDemoUserData->uiTimeStamp
					,iTIllegalParkInfoNum);

				for (i=0; i < iTIllegalParkInfoNum; i++)
				{
					fprintf(m_pfSaveUserDataFile,"  Count%d: 区域编号 %d 违停区域点数 %d" ,i, temp[i].m_usRIllegalParkNo, temp[i].m_usIllegalParkAreaCounts);
					for (j=0; j < temp[i].m_usIllegalParkAreaCounts; j++)
					{
						fprintf(m_pfSaveUserDataFile," Point%d (x=%d, y=%d)"
							,j
							,temp[i].m_structAreaEx[j].m_usX
							,temp[i].m_structAreaEx[j].m_usY);
					}
					fprintf(m_pfSaveUserDataFile,"\r\n");
				}
			}	
		break;
		}
	}
}

int CPlayDemo_VCDlg::seconds_to_file_time(NVS_FILE_TIME* filetime, long seconds)
{
	if (NULL == filetime)
	{
		return PAP_FAIL;
	}

	struct tm  tm_time;
#ifdef WIN32
	__int64 ltime = seconds;
	_gmtime64_s(&tm_time,&ltime);
#else
	tm_time = *gmtime(&seconds);
#endif

	filetime->iYear   = tm_time.tm_year + 1900;
	filetime->iMonth  = tm_time.tm_mon + 1;
	filetime->iDay    = tm_time.tm_mday;
	filetime->iHour   = tm_time.tm_hour;
	filetime->iMinute = tm_time.tm_min;
	filetime->iSecond = tm_time.tm_sec;

	return PAP_SUCC;
}