// 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
// (“Fluent UI”)。该示例仅供参考，
// 用以补充《Microsoft 基础类参考》和
// MFC C++ 库软件随附的相关电子文档。
// 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
// 若要了解有关 Fluent UI 许可计划的详细信息，请访问
// https://go.microsoft.com/fwlink/?LinkId=238214.
//
// 版权所有(C) Microsoft Corporation
// 保留所有权利。

// VideoCaptureView.cpp: CVideoCaptureView 类的实现
//

#include "stdafx.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "VideoCapture.h"
#endif

#include "VideoCaptureDoc.h"
#include "VideoCaptureView.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CMemoryClient g_ub530;
static CMainFrame* g_pMainFrame = NULL;

VOID Dbg(CHAR* pszStr, ...)
{
	char szData[MAX_PATH] = "[SC] ";
	va_list args;
	va_start(args, pszStr);
	_vsnprintf_s(szData + 5, MAX_PATH - 5, MAX_PATH - 6, pszStr, args);
	va_end(args);
	strcat_s(szData, "\n");
	OutputDebugStringA(szData);
}

//  FORMAT CHANGED CALLBACK FUNCTION
//
QRETURN on_process_format_changed(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, ULONG nVideoWidth, ULONG nVideoHeight, BOOL bVideoIsInterleaved, double dVideoFrameRate, ULONG nAudioChannels, ULONG nAudioBitsPerSample, ULONG nAudioSampleFrequency, PVOID pUserData)
{
	//Dbg("format changed Detected  \n");
	CVideoCaptureView* pView = (CVideoCaptureView*)pUserData;
	if (pView == NULL) { return QCAP_RT_OK; }
	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }

	pView->m_nVideoWidth = nVideoWidth;
	pView->m_nVideoHeight = nVideoHeight;
	pView->m_bVideoIsInterleaved = bVideoIsInterleaved;
	pView->m_dVideoFrameRate = dVideoFrameRate;
	pView->m_nAudioChannels = nAudioChannels;
	pView->m_nAudioBitsPerSample = nAudioBitsPerSample;
	pView->m_nAudioSampleFrequency = nAudioSampleFrequency;
	// OUTPUT FORMAT CHANGED MESSAGE
	//
	CHAR strVideoInput[MAX_PATH] = { 0 };
	CHAR strAudioInput[MAX_PATH] = { 0 };
	CHAR strFrameType[MAX_PATH] = { 0 };
	UINT nVH = 0;

	if (nVideoInput == 0) { sprintf_s(strVideoInput, "COMPOSITE"); }
	if (nVideoInput == 1) { sprintf_s(strVideoInput, "SVIDEO"); }
	if (nVideoInput == 2) { sprintf_s(strVideoInput, "HDMI"); }
	if (nVideoInput == 3) { sprintf_s(strVideoInput, "DVI_D"); }
	if (nVideoInput == 4) { sprintf_s(strVideoInput, "COMPONENTS (YCBCR)"); }
	if (nVideoInput == 5) { sprintf_s(strVideoInput, "DVI_A (RGB / VGA)"); }
	if (nVideoInput == 6) { sprintf_s(strVideoInput, "SDI"); }
	if (nVideoInput == 7) { sprintf_s(strVideoInput, "AUTO"); }
	if (nAudioInput == 0) { sprintf_s(strAudioInput, "EMBEDDED_AUDIO"); }
	if (nAudioInput == 1) { sprintf_s(strAudioInput, "LINE_IN"); }

	if (bVideoIsInterleaved == TRUE) { nVH = nVideoHeight / 2; }
	else { nVH = nVideoHeight; }

	if (bVideoIsInterleaved == TRUE) { sprintf_s(strFrameType, " I "); }
	else { sprintf_s(strFrameType, " P "); }

	pView->m_strFormatChangedOutput.Format(
		_T("INFO : %d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ ,  VIDEO INPUT : %s ,  AUDIO INPUT : %s"),
		nVideoWidth,
		nVH,
		strFrameType,
		dVideoFrameRate,
		nAudioChannels,
		nAudioBitsPerSample,
		nAudioSampleFrequency,
		strVideoInput,
		strAudioInput
	);
	Global::WriteTextLog(_T("采集卡格式变更：%d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ ,  视频输入源 : %s ,  音频输入源 : %s"),
		nVideoWidth,
		nVH,
		strFrameType,
		dVideoFrameRate,
		nAudioChannels,
		nAudioBitsPerSample,
		nAudioSampleFrequency,
		strVideoInput,
		strAudioInput);

	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)& pView->m_strFormatChangedOutput, ID_STATUSBAR_PANE1);

	// NO SOURCE
	//
	if (nVideoWidth == 0 &&
		nVideoHeight == 0 &&
		dVideoFrameRate == 0.0 &&
		nAudioChannels == 0 &&
		nAudioBitsPerSample == 0 &&
		nAudioSampleFrequency == 0)
	{
		pView->m_bNoSignal = TRUE;
	}
	else
	{
		pView->m_bNoSignal = FALSE;
	}

	pView->SetTimer(0x00000000, 1, NULL);

	return QCAP_RT_OK;
}

// NO SIGNAL DETEACTED CALLBACK FUNCTION
//
QRETURN on_process_no_signal_detected(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CVideoCaptureView* pView = (CVideoCaptureView*)pUserData;

	//Dbg("No Signal Detected  \n");
	if (pView == NULL) { return QCAP_RT_OK; }
	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }

	//pView->SetRibbonStatusBarText("当前采集卡无信号。", ID_STATUSBAR_PANE1);
	Global::WriteTextLog(_T("当前采集卡无信号"));
	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)& CString("当前采集卡无信号"), ID_STATUSBAR_PANE1);

	pView->m_bNoSignal = TRUE;
	pView->SetTimer(0x00000000, 1, NULL);

	return QCAP_RT_OK;
}

// SIGNAL REMOVED CALLBACK FUNCTION
//
QRETURN on_process_signal_removed(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	CVideoCaptureView* pView = (CVideoCaptureView*)pUserData;
	if (pView == NULL) { return QCAP_RT_OK; }
	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }

	//pView->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
	Global::WriteTextLog(_T("当前采集卡信号被移除"));
	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)& CString("当前采集卡信号被移除"), ID_STATUSBAR_PANE1);

	pView->m_bNoSignal = TRUE;
	pView->SetTimer(0x00000000, 1, NULL);

	return QCAP_RT_OK;
}

// PREVIEW VIDEO CALLBACK FUNCTION
//
QRETURN on_process_preview_video_buffer(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
{
	CVideoCaptureView* pView = (CVideoCaptureView*)pUserData;
	if (pView)
	{
		// 尝试加锁;
		if (!pView->m_mut_cpature.try_lock())
		{
#ifdef DEBUG
			OutputDebugStringA("!pView->m_mut_cpature.try_lock()\n");
#endif
			return QCAP_RT_OK;
		}

		// 是否触发截图;
		if (pView->m_bCaptureImage)
		{
			// 加锁;
			std::lock_guard<std::mutex> lk(pView->m_mut_thread);
			// 复制数据;
			pView->m_dwBufferLen = nFrameBufferLen;
			pView->m_pBuffer = new BYTE[nFrameBufferLen];
			memcpy(pView->m_pBuffer, pFrameBuffer, nFrameBufferLen);
			// 通知线程保存图片;
			pView->m_thread_cond.notify_one();
			// 恢复截图标记,防止重复截图;
			pView->m_bCaptureImage = FALSE;
#ifdef DEBUG
			OutputDebugStringA("preview_video_buffer:pView->m_bCaptureImage\n");
#endif
		}

		// 解锁;
		pView->m_mut_cpature.unlock();
	}

	return QCAP_RT_OK;
}

// PREVIEW AUDIO CALLBACK FUNCTION
//
QRETURN on_process_preview_audio_buffer(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
{
	return QCAP_RT_OK;
}

// VIDEO HARDARE ENCODER CALLBACK FUNCTION
//
QRETURN on_process_hardware_encoder_video_buffer(PVOID pDevice, UINT iRecNum, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, BOOL bIsKeyFrame, PVOID pUserData)
{
	return QCAP_RT_OK;
}

QRETURN on_process_snapshot_done(PVOID pDevice, CHAR* pszFilePathName, PVOID pUserData)
{
	return QCAP_RT_OK;
}

QRETURN on_process_snapshot_stream(PVOID pDevice, CHAR* pszFilePathName, BYTE* pStreamBuffer, ULONG nStreamBufferLen, PVOID pUserData)
{
	// 注意：在调用本回调函数前，已经保存了图片！
	CVideoCaptureView* pView = (CVideoCaptureView*)pUserData;
	if (pView->m_bHoriontal || pView->m_bVertically)
		Global::SaveImgByRotate(pszFilePathName, pStreamBuffer, nStreamBufferLen, pView->m_bHoriontal, pView->m_bVertically);

	return QCAP_RT_OK;
}

// CVideoCaptureView

IMPLEMENT_DYNCREATE(CVideoCaptureView, CView)

BEGIN_MESSAGE_MAP(CVideoCaptureView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CVideoCaptureView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_COMMAND(ID_CUT_BMP, &CVideoCaptureView::OnCutBmp)
	ON_COMMAND(ID_CUT_JPG, &CVideoCaptureView::OnCutJpg)
	ON_COMMAND(ID_START_RECORD, &CVideoCaptureView::OnStartRecord)
	ON_COMMAND(ID_STOP_RECORD, &CVideoCaptureView::OnStopRecord)
	ON_COMMAND(ID_CHECK_VERTICALLY, &CVideoCaptureView::OnCheckVertically)
	ON_COMMAND(ID_CHECK_HORIONTAL, &CVideoCaptureView::OnCheckHoriontal)
	ON_UPDATE_COMMAND_UI(ID_CHECK_VERTICALLY, &CVideoCaptureView::OnUpdateCheckVertically)
	ON_UPDATE_COMMAND_UI(ID_CHECK_HORIONTAL, &CVideoCaptureView::OnUpdateCheckHoriontal)
	ON_COMMAND(ID_TRAYMENU_RECONNECT, &CVideoCaptureView::OnTraymenuReconnect)
	ON_COMMAND(ID_CHECK_SUPORT_GPU, &CVideoCaptureView::OnCheckSuportGpu)
	ON_COMMAND(ID_CHECK_FORMAT_MP4, &CVideoCaptureView::OnCheckFormatMp4)
	ON_COMMAND(ID_CHECK_FORMAT_AVI, &CVideoCaptureView::OnCheckFormatAvi)
	ON_UPDATE_COMMAND_UI(ID_CHECK_SUPORT_GPU, &CVideoCaptureView::OnUpdateCheckSuportGpu)
	ON_UPDATE_COMMAND_UI(ID_CHECK_FORMAT_MP4, &CVideoCaptureView::OnUpdateCheckFormatMp4)
	ON_UPDATE_COMMAND_UI(ID_CHECK_FORMAT_AVI, &CVideoCaptureView::OnUpdateCheckFormatAvi)
	ON_UPDATE_COMMAND_UI(ID_START_RECORD, &CVideoCaptureView::OnUpdateStartRecord)
	ON_UPDATE_COMMAND_UI(ID_STOP_RECORD, &CVideoCaptureView::OnUpdateStopRecord)
END_MESSAGE_MAP()

// CVideoCaptureView 构造/析构

CVideoCaptureView::CVideoCaptureView() noexcept
{
	// TODO: 在此处添加构造代码
	m_hVideoDevice = NULL;
	m_bIsRecord = FALSE;
	m_bNoSignal = FALSE;
	m_bVertically = FALSE;
	m_bHoriontal = FALSE;
	m_bAppQuit = FALSE;
	m_pBuffer = NULL;
	m_bCaptureImage = FALSE;
	m_dwBufferLen = 0;
	m_bIsMp4 = TRUE;
	m_bSupportGPU = FALSE;
}

CVideoCaptureView::~CVideoCaptureView()
{
	g_ub530.EndOfThread();
	m_bAppQuit = TRUE;
	HwUninitialize();
}

BOOL CVideoCaptureView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CVideoCaptureView 绘图

void CVideoCaptureView::OnDraw(CDC* pDC)
{
	CVideoCaptureDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TO FILL IN THE TEXT 
	//
	if (m_hVideoDevice == 0 || m_bNoSignal) {

		CFont font;
		ULONG nFontSize = 300;
		font.CreatePointFont(nFontSize, TEXT("Arial"), NULL);
		HFONT hOldFont = (HFONT)pDC->SelectObject(&font);
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(RGB(255, 255, 255));

		CRect rect_client;
		GetClientRect(&rect_client);

		CString string = _T("");
		if (m_hVideoDevice == 0)
		{
			CBrush brush_fill_rect(RGB(0, 0, 0));
			pDC->FillRect(&rect_client, &brush_fill_rect);
			string = TEXT("No Device");
			//g_pMainFrame->SetRibbonStatusBarText("当前采集卡设备被移除。", ID_STATUSBAR_PANE1);
		}
		else if(m_bNoSignal)
		{
			CBrush brush_fill_rect(RGB(0, 0, 255));
			pDC->FillRect(&rect_client, &brush_fill_rect);
			string = TEXT("No Source");
			//g_pMainFrame->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
		}
		pDC->DrawText(string, &rect_client, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

		pDC->SelectObject(&hOldFont);
		font.DeleteObject();
	}

	// TODO: 在此处为本机数据添加绘制代码
}


// CVideoCaptureView 打印


BOOL CVideoCaptureView::HwInitialize()
{
	if (m_hVideoDevice != NULL)
		return TRUE;

	// CALLBACK FUNCTION       
	PF_FORMAT_CHANGED_CALLBACK pFormatChangedCB = { 0 };
	PF_VIDEO_PREVIEW_CALLBACK  pPreviewVideoCB = { 0 };
	PF_AUDIO_PREVIEW_CALLBACK pPreviewAudioCB = { 0 };
	PF_VIDEO_HARDWARE_ENCODER_CALLBACK pHardwareEncoderVideoCB = { 0 };
	PF_NO_SIGNAL_DETECTED_CALLBACK pNoSignalDetectedCB = { 0 };
	PF_SIGNAL_REMOVED_CALLBACK pSignalRemovedCB = { 0 };
	PF_SNAPSHOT_DONE_CALLBACK pSnapShotDoneCB = { 0 };
	PF_SNAPSHOT_STREAM_CALLBACK pSnapShotStreamCB = { 0 };
	// CREATE CAPTURE DEVICE
	//
	if (m_hVideoDevice == NULL)
		QCAP_CREATE("CY3014 USB", 0, m_hWnd, &m_hVideoDevice, 1);

	if (m_hVideoDevice == NULL) {
		return FALSE;
	}

	// REGISTER FORMAT CHANGED CALLBACK FUNCTION
	pFormatChangedCB = on_process_format_changed;
	QCAP_REGISTER_FORMAT_CHANGED_CALLBACK(m_hVideoDevice, pFormatChangedCB, this);

	// REGISTER PREVIEW VIDEO CALLBACK FUNCTION
	pPreviewVideoCB = on_process_preview_video_buffer;
	QCAP_REGISTER_VIDEO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewVideoCB, this);

	// REGISTER PREVIEW AUDIO CALLBACK FUNCTION
	//pPreviewAudioCB = on_process_preview_audio_buffer;
	//QCAP_REGISTER_AUDIO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewAudioCB, this);

	// REGISTER HARDWARE ENCODER VIDEO CALLBACK FUNCTION
	//pHardwareEncoderVideoCB = on_process_hardware_encoder_video_buffer;
	//QCAP_REGISTER_VIDEO_HARDWARE_ENCODER_CALLBACK(m_hVideoDevice, 0, pHardwareEncoderVideoCB, this);

	// REGISTER NO SIGNAL DETECTED CALLBACK FUNCTION
	pNoSignalDetectedCB = on_process_no_signal_detected;
	QCAP_REGISTER_NO_SIGNAL_DETECTED_CALLBACK(m_hVideoDevice, pNoSignalDetectedCB, this);

	// REGISTER SIGNAL REMOVED CALLBACK FUNCTION
	pSignalRemovedCB = on_process_signal_removed;
	QCAP_REGISTER_SIGNAL_REMOVED_CALLBACK(m_hVideoDevice, pSignalRemovedCB, this);

#if 1
	// 
	pSnapShotDoneCB = on_process_snapshot_done;
	QCAP_REGISTER_SNAPSHOT_DONE_CALLBACK(m_hVideoDevice, pSnapShotDoneCB, this);

	// 
	pSnapShotStreamCB = on_process_snapshot_stream;
	QCAP_REGISTER_SNAPSHOT_STREAM_CALLBACK(m_hVideoDevice, pSnapShotStreamCB, this);
#endif

	QCAP_SET_VIDEO_DEINTERLACE_TYPE(m_hVideoDevice, QCAP_SOFTWARE_DEINTERLACE_TYPE_BLENDING);

	QCAP_SET_VIDEO_DEINTERLACE(m_hVideoDevice, 0);
	QCAP_SET_AUDIO_VOLUME(m_hVideoDevice, 100);
	QCAP_SET_VIDEO_HARDWARE_ENCODER_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_FORMAT_H264, QCAP_RECORD_MODE_CBR, 8000, 12 * 1024 * 1024, 30, 0, 0, QCAP_DOWNSCALE_MODE_OFF, 0, 0);

	QCAP_SET_VIDEO_INPUT(m_hVideoDevice, QCAP_INPUT_TYPE_AUTO);
	QCAP_RUN(m_hVideoDevice);

	// 刷新区域;
	Invalidate();

	// UPDATE USER INTERFACE RESOURCE
	if (m_hVideoDevice == 0) {
		/*m_oSetupDialog.m_btnVideoInput.EnableWindow(FALSE);
		m_oSetupDialog.m_btnVideoQuality.EnableWindow(FALSE);
		m_oSetupDialog.m_btnAudioInput.EnableWindow(FALSE);
		m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(FALSE);
		m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
		m_oSetupDialog.m_checkGPU_1_2.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
		m_oSetupDialog.m_checkGPU_1_3.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
		m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(FALSE);
		m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
	}
	else {
		/*m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(TRUE);
		m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(TRUE);
		m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(TRUE);
		m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(TRUE);
		m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
		m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(TRUE);
		m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
		m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
		m_oSetupDialog.m_checkGPU_1_2.EnableWindow(TRUE);
		m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
		m_oSetupDialog.m_checkGPU_1_3.EnableWindow(TRUE);
		m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
		m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(TRUE);
		m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
	}

	return TRUE;
}

BOOL CVideoCaptureView::HwUninitialize()
{
	if (m_hVideoDevice != 0) {
		QCAP_STOP(m_hVideoDevice);
		QCAP_DESTROY(m_hVideoDevice);
		m_hVideoDevice = NULL;
	}

	return TRUE;
}

void CVideoCaptureView::CaptureSingleImage(LPTSTR lpszFileName, BOOL bIsJPG)
{
	if (m_hVideoDevice != NULL)
	{
		if (bIsJPG)
		{
			QCAP_SNAPSHOT_JPG(m_hVideoDevice, lpszFileName, 100, FALSE, 5000); //参数4：是否异步;
		}
		else
		{
			QCAP_SNAPSHOT_BMP(m_hVideoDevice, lpszFileName, FALSE, 5000);
		}
#ifdef _DEBUG
		Global::WriteTextLog("完成：CaptureSingleImage");
#endif
	}
}

std::string CVideoCaptureView::CaptureSingleImageAutoName(LPCTSTR lpszDir, BOOL bIsJPG)
{
	if (m_hVideoDevice != NULL)
	{
		TCHAR szPath[MAX_PATH] = { 0 };
		// 毫秒级;
		time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
		auto tt = std::chrono::system_clock::to_time_t(tp);
		std::tm now = { 0 };
		localtime_s(&now, &tt); // 时间戳转成本地时间;
		int msc = tp.time_since_epoch().count() % 1000;
		if (bIsJPG)
		{
			_stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
				lpszDir ? lpszDir : Global::g_szCurModuleDir,
				now.tm_year + 1990,
				now.tm_mon + 1,
				now.tm_mday,
				now.tm_hour,
				now.tm_min,
				now.tm_sec,
				msc);
			QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, FALSE, 5000);
		}
		else
		{
			_stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
				lpszDir ? lpszDir : Global::g_szCurModuleDir,
				now.tm_year + 1990,
				now.tm_mon + 1,
				now.tm_mday,
				now.tm_hour,
				now.tm_min,
				now.tm_sec,
				msc);
			QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, FALSE, 5000);
		}
#ifdef _DEBUG
		Global::WriteTextLog("完成：CaptureSingleImageAutoName");
#endif
		return std::string(szPath);
	}

	return std::string();
}

void CVideoCaptureView::CaptureMultiImage(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
{
	std::thread t([&](CVideoCaptureView* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
		// 连续截图;
		TCHAR szDir[MAX_PATH] = { 0 };
		TCHAR szPath[MAX_PATH] = { 0 };

		_stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
			lpszDir ? lpszDir : Global::g_szCurModuleDir,
			lpszPrefix ? lpszPrefix : _T(""));

		auto start = system_clock::now();
		while (true)
		{
			// C++11获取当前时间;
			time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
			if (bIsJPG)
			{
				_stprintf_s(szPath, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
				QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, TRUE);
				// 等待磁盘完成写入;
				//Sleep(20);
			}
			else
			{
				_stprintf_s(szPath, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
				QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, TRUE);
				// 等待磁盘完成写入;
				//Sleep(530);
			}

			auto duration = duration_cast<milliseconds>(system_clock::now() - start);
			if (duration.count() >= nDurationTime)
				break;
		}
		}, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
	t.detach();
}

void CVideoCaptureView::CaptureSingleImageEx(LPTSTR lpszFileName, BOOL bIsJPG)
{
	{
		// 加锁;
		std::lock_guard<std::mutex> lk(m_mut_cpature);
		// 标记截图;
		m_bCaptureImage = TRUE;
		// 初始化数据;
		ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
		m_CaptureInfo.bIsJPG = bIsJPG;
		m_CaptureInfo.bSingle = TRUE;
		m_CaptureInfo.IsAutoName = FALSE;
		m_CaptureInfo.nCaputerCount = 0;
		m_CaptureInfo.nKeepTime = 0;
		memset(m_CaptureInfo.szPrefix, 0, 64);
		//_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
		_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
		//m_strCaptureName = lpszFileName;
	}

	// 等待截图完成;
	{
		// 加锁;
		std::unique_lock<std::mutex> lk(m_mut_cpature);
		m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
		// 解锁;
		lk.unlock();
	}
}

std::string CVideoCaptureView::CaptureSingleImageAutoNameEx(LPCTSTR lpszDir, BOOL bIsJPG)
{
	{
		// 加锁;
		std::lock_guard<std::mutex> lk(m_mut_cpature);
		// 标记截图;
		m_bCaptureImage = TRUE;
		// 初始化数据;
		ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
		m_CaptureInfo.bIsJPG = bIsJPG;
		m_CaptureInfo.bSingle = TRUE;
		m_CaptureInfo.IsAutoName = FALSE;
		m_CaptureInfo.nCaputerCount = 0;
		m_CaptureInfo.nKeepTime = 0;
		memset(m_CaptureInfo.szPrefix, 0, 64);
		memset(m_CaptureInfo.szSaveDir, 0, MAX_PATH);

		// 毫秒级;
		time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
		auto tt = std::chrono::system_clock::to_time_t(tp);
		std::tm now = { 0 };
		localtime_s(&now, &tt); // 时间戳转成本地时间;
		int msc = tp.time_since_epoch().count() % 1000;
		if (bIsJPG)
		{
			_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
				lpszDir ? lpszDir : Global::g_szCurModuleDir,
				now.tm_year + 1990,
				now.tm_mon + 1,
				now.tm_mday,
				now.tm_hour,
				now.tm_min,
				now.tm_sec,
				msc);
		}
		else
		{
			_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
				lpszDir ? lpszDir : Global::g_szCurModuleDir,
				now.tm_year + 1990,
				now.tm_mon + 1,
				now.tm_mday,
				now.tm_hour,
				now.tm_min,
				now.tm_sec,
				msc);
		}

#ifdef DEBUG
		OutputDebugStringA(m_CaptureInfo.szSaveDir);
		OutputDebugStringA("\tCVideoCaptureView::CaptureSingleImageAutoNameEx\n");
#endif // DEBUG
	}

	// 等待截图完成;
	{
		// 加锁;
		std::unique_lock<std::mutex> lk(m_mut_cpature);
		m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
		// 解锁;
		lk.unlock();
	}

	return std::string(m_CaptureInfo.szSaveDir);
}

void CVideoCaptureView::CaptureMultiImageEx(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
{
	std::thread t([&](CVideoCaptureView* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
		// 连续截图;
		TCHAR szDir[MAX_PATH] = { 0 };
		_stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
			lpszDir ? lpszDir : Global::g_szCurModuleDir,
			lpszPrefix ? lpszPrefix : _T(""));

		auto start = system_clock::now();
		while (true)
		{
			// C++11获取当前时间;
			time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());

			{
				// 加锁;
				std::lock_guard<std::mutex> lk(m_mut_cpature);
				// 标记截图;
				m_bCaptureImage = TRUE;
				// 初始化数据;
				ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
				m_CaptureInfo.bIsJPG = bIsJPG;
				m_CaptureInfo.bSingle = FALSE;
				m_CaptureInfo.IsAutoName = TRUE;
				m_CaptureInfo.nCaputerCount = 0;
				m_CaptureInfo.nKeepTime = nDurationTime;
				_stprintf_s(m_CaptureInfo.szPrefix, _T("%s"), lpszPrefix);
				if (bIsJPG)
				{
					_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
				}
				else
				{
					_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
				}
			}

			// 等待截图完成;
			{
				// 加锁;
				std::unique_lock<std::mutex> lk(m_mut_cpature);
				m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
				// 解锁;
				lk.unlock();
			}

			auto duration = duration_cast<milliseconds>(system_clock::now() - start);
			if (duration.count() >= nDurationTime)
				break;
		}
		}, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
	t.detach();
}

BOOL CVideoCaptureView::SaveImageByCaptureInfo(const CaptureInfo& capInfo)
{
	if (m_pBuffer == NULL)
	{
		return FALSE;
	}

	BOOL bRet = FALSE;
	// 保存截图;
	HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, m_nVideoWidth * m_nVideoHeight * 4);
	if (hMemery != NULL)
	{
		BYTE* pDstFrameBuffer = NULL;
		pDstFrameBuffer = (BYTE*)GlobalLock(hMemery);
		if (pDstFrameBuffer != NULL)
		{
			QRESULT QRet = QCAP_COLORSPACE_YUY2_TO_ABGR32(m_pBuffer,
				m_nVideoWidth,
				m_nVideoHeight,
				0,
				pDstFrameBuffer,
				m_nVideoWidth,
				m_nVideoHeight,
				0);

			Status stat = GenericError;
			Bitmap* pImg = ::new Bitmap(
				m_nVideoWidth,
				m_nVideoHeight,
				m_nVideoWidth * 4,
				PixelFormat32bppRGB,
				pDstFrameBuffer);

			if (m_bHoriontal && !m_bVertically)
				pImg->RotateFlip(RotateNoneFlipX);// 水平翻转;
			else if (m_bHoriontal && m_bVertically)
				pImg->RotateFlip(Rotate180FlipNone);// 270度;
			else if (!m_bHoriontal && m_bVertically)
				pImg->RotateFlip(Rotate180FlipX);// 垂直翻转;

			CLSID encoderClsid = { 0 };
			CString strFileName = m_CaptureInfo.szSaveDir;
			// 需要判断路径是否存在,不存在创建目录;
			int nIndex = strFileName.ReverseFind(_T('\\'));
			if (nIndex != -1) 
			{
				if (!PathFileExists(strFileName.Left(nIndex)))
				{
					// 如果文件夹不存在,创建;
					SHCreateDirectoryEx(NULL, strFileName.Left(nIndex), NULL);
				}
			}

			BSTR newfile = strFileName.AllocSysString();
			if (!capInfo.bIsJPG)
			{
				Global::GetEncoderClsid(L"image/bmp", &encoderClsid);
				stat = pImg->Save(newfile, &encoderClsid, NULL);
			}
			else
			{
				Global::GetEncoderClsid(L"image/jpeg", &encoderClsid);
				EncoderParameters encoderParameters;
				encoderParameters.Count = 1;
				encoderParameters.Parameter[0].Guid = EncoderQuality;
				encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
				encoderParameters.Parameter[0].NumberOfValues = 1;
				// Save the image as a JPEG with quality level 100.
				ULONG uQuality = 100;
				encoderParameters.Parameter[0].Value = &uQuality;
				stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
			}

			if (pImg)
				::delete pImg;
			pImg = NULL;
			SysFreeString(newfile);

			bRet = (stat == 0 ? TRUE : FALSE);
#ifdef DEBUG
			if (bRet)
			{
				OutputDebugStringA(strFileName);
				OutputDebugStringA("\tSave Image::Ok\n");
			}
#endif
		}
#ifdef DEBUG
		else
		{
			OutputDebugStringA("pDstFrameBuffer == NULL\n");
		}
#endif

		GlobalUnlock(hMemery);
	}
#ifdef DEBUG
	else
	{
		DWORD dwError = GetLastError();
		CString strError = _T("");
		strError.Format(_T("hMemery == NULL分配内存出错：%ld\n"), dwError);
		OutputDebugStringA(strError);
	}
#endif

	if (m_pBuffer)
		delete[]m_pBuffer;
	m_pBuffer = NULL;

	// 必须调用GlobalFree释放;
	GlobalFree(hMemery);

	return bRet;
}

void CVideoCaptureView::CaptureImageThread(CVideoCaptureView* pView)
{
	CString strFileName = _T("");
	while (!pView->m_bAppQuit)
	{
		std::unique_lock<std::mutex> lk(pView->m_mut_thread);   // 这里使用unique_lock是为了后面方便解锁
#if 1	// 避免线程虚假唤醒;
		pView->m_thread_cond.wait(lk, [&]() {return pView->m_pBuffer; });
#else
		while (!pView->m_pBuffer)
			pView->m_data_cond.wait(lk);
#endif
		// 保存截图;
		pView->SaveImageByCaptureInfo(pView->m_CaptureInfo);
		// 通知截图完成;
		pView->m_capture_cond.notify_one();

		// 解锁;
		lk.unlock();

		// sleep 10ms;
		//this_thread::sleep_for(chrono::milliseconds(10));
	}
}

void CVideoCaptureView::StartRecord(DWORD dwDuration, LPCTSTR lpSavePath)
{
	QRESULT QRet = QCAP_RS_SUCCESSFUL;
	if (!m_bIsMp4) // 音频格式;
	{
		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_PCM);
		//_tcscat_s(szPath, _T(".avi"));
	}
	else
	{
		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_AAC);
		//_tcscat_s(szPath, _T(".mp4"));
	}

	// 设置视频属性;
	QRet = QCAP_SET_VIDEO_RECORD_PROPERTY(
		m_hVideoDevice,
		0,
		m_bSupportGPU ? QCAP_ENCODER_TYPE_INTEL_MEDIA_SDK : QCAP_ENCODER_TYPE_SOFTWARE,
		QCAP_ENCODER_FORMAT_H264,
		QCAP_RECORD_MODE_CBR,
		8000,
		16 * 1024 * 1024, // 16最高质量;
		30, // 每秒多少帧
		0,
		0,
		QCAP_DOWNSCALE_MODE_OFF);

	// 开始录屏;
	QRet = QCAP_START_RECORD(m_hVideoDevice, 0, const_cast<CHAR*>(lpSavePath), QCAP_RECORD_FLAG_FULL, 0.0, 0.0, 0.0, 0, NULL);

	m_bIsRecord = TRUE;
}

void CVideoCaptureView::StopRecord()
{
	QCAP_STOP_RECORD(m_hVideoDevice, 0);
	m_bIsRecord = FALSE;
}

void CVideoCaptureView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CVideoCaptureView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CVideoCaptureView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CVideoCaptureView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}

void CVideoCaptureView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CVideoCaptureView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CVideoCaptureView 诊断

#ifdef _DEBUG
void CVideoCaptureView::AssertValid() const
{
	CView::AssertValid();
}

void CVideoCaptureView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CVideoCaptureDoc* CVideoCaptureView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVideoCaptureDoc)));
	return (CVideoCaptureDoc*)m_pDocument;
}
#endif //_DEBUG


// CVideoCaptureView 消息处理程序


void CVideoCaptureView::SetRibbonStatusBarText(CString strText, int uId)
{
	if ( g_pMainFrame )
	{
		g_pMainFrame->SetRibbonStatusBarText(strText, uId);
	}
}

int CVideoCaptureView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// 初始化共享内存;
	CMemoryClient::m_pView = this;
	g_ub530.InitMemery();
	g_ub530.StartThread();

	g_pMainFrame = (CMainFrame*)this->GetParent();

	// TODO:  在此添加您专用的创建代码
	// 创建视频流，并关联指定显示窗口;
	HwInitialize();

	// 创建截图线程;
	std::thread t(CaptureImageThread, this);
	t.detach();

	return 0;
}


void CVideoCaptureView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (nIDEvent == 0)
	{
		KillTimer(0);

		if (m_bNoSignal)
		{
			if (m_bIsRecord)
			{
				QCAP_STOP_RECORD(m_hVideoDevice, 0);
				m_bIsRecord = FALSE;
			}
		}
		else
		{

		}
	}

	CView::OnTimer(nIDEvent);
}


void CVideoCaptureView::OnCutBmp()
{
	// TODO: 在此添加命令处理程序代码
	CaptureSingleImageAutoName(NULL, FALSE);
}


void CVideoCaptureView::OnCutJpg()
{
	// TODO: 在此添加命令处理程序代码
	CaptureSingleImageAutoName(NULL, TRUE);
}


void CVideoCaptureView::OnStartRecord()
{
	// TODO: 在此添加命令处理程序代码
	TCHAR szPath[MAX_PATH] = { 0 };
	// 毫秒级;
	time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
	auto tt = std::chrono::system_clock::to_time_t(tp);
	std::tm now = { 0 };
	localtime_s(&now, &tt); // 时间戳转成本地时间;
	int msc = tp.time_since_epoch().count() % 1000;

	_stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d"),
#ifdef _DEBUG
		_T("D:\\bin\\VideoCapture\\"),
#else
		Global::g_szCurModuleDir,
#endif
		now.tm_year + 1990,
		now.tm_mon + 1,
		now.tm_mday,
		now.tm_hour,
		now.tm_min,
		now.tm_sec,
		msc);

	QRESULT QRet = QCAP_RS_SUCCESSFUL;
	if (!m_bIsMp4) // 音频格式;
	{
		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_PCM);
		_tcscat_s(szPath, _T(".avi"));
	}
	else
	{
		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_AAC);
		_tcscat_s(szPath, _T(".mp4"));
	}
	
	// 设置视频属性;
	QRet = QCAP_SET_VIDEO_RECORD_PROPERTY(
		m_hVideoDevice,
		0,
		m_bSupportGPU ? QCAP_ENCODER_TYPE_INTEL_MEDIA_SDK : QCAP_ENCODER_TYPE_SOFTWARE,
		QCAP_ENCODER_FORMAT_H264,
		QCAP_RECORD_MODE_CBR,
		8000,
		16*1024*1024, // 16最高质量;
		30, // 每秒多少帧
		0, 
		0,
		QCAP_DOWNSCALE_MODE_OFF);
	

	// 开始录屏;
	QRet = QCAP_START_RECORD(m_hVideoDevice, 0, szPath, QCAP_RECORD_FLAG_FULL, 0.0, 0.0, 0.0, 0, NULL);

	m_bIsRecord = TRUE;
}


void CVideoCaptureView::OnStopRecord()
{
	// TODO: 在此添加命令处理程序代码
	QCAP_STOP_RECORD(m_hVideoDevice, 0);
	m_bIsRecord = FALSE;
}


void CVideoCaptureView::OnCheckVertically()
{
	// TODO: 在此添加命令处理程序代码
	CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
	CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_VERTICALLY);
	m_bVertically = !pCheckbox->IsChecked();
	if (m_hVideoDevice)
	{
		QCAP_SET_VIDEO_MIRROR(m_hVideoDevice, m_bHoriontal, m_bVertically);
	}
}


void CVideoCaptureView::OnCheckHoriontal()
{
	// TODO: 在此添加命令处理程序代码
	CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
	CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_HORIONTAL);
	m_bHoriontal = !pCheckbox->IsChecked();
	if (m_hVideoDevice)
	{
		QCAP_SET_VIDEO_MIRROR(m_hVideoDevice, m_bHoriontal, m_bVertically);
	}
}


void CVideoCaptureView::OnUpdateCheckVertically(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(m_bVertically);
}


void CVideoCaptureView::OnUpdateCheckHoriontal(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(m_bHoriontal);
}


void CVideoCaptureView::OnTraymenuReconnect()
{
	// TODO: 在此添加命令处理程序代码
	HwUninitialize();// 断开;
	Invalidate();
	HwInitialize();// 重连;
}


void CVideoCaptureView::OnCheckSuportGpu()
{
	// TODO: 在此添加命令处理程序代码
	CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
	CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_SUPORT_GPU);
	m_bSupportGPU = !pCheckbox->IsChecked();
}


void CVideoCaptureView::OnCheckFormatMp4()
{
	CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
	CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_FORMAT_MP4);
	m_bIsMp4 = !pCheckbox->IsChecked();
}


void CVideoCaptureView::OnCheckFormatAvi()
{
	CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
	CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_FORMAT_AVI);
	m_bIsMp4 = pCheckbox->IsChecked();
}


void CVideoCaptureView::OnUpdateCheckSuportGpu(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(m_bSupportGPU);
}


void CVideoCaptureView::OnUpdateCheckFormatMp4(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(m_bIsMp4);
}


void CVideoCaptureView::OnUpdateCheckFormatAvi(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(!m_bIsMp4);
}


void CVideoCaptureView::OnUpdateStartRecord(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->Enable(!m_bIsRecord);
}


void CVideoCaptureView::OnUpdateStopRecord(CCmdUI* pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->Enable(m_bIsRecord);
}
