UB530View.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313
  1. // UB530View.cpp: 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "SATHelper.h"
  5. #include "UB530View.h"
  6. #include "MainFrm.h"
  7. extern CMemoryClient g_ub530;
  8. extern CMainFrame* g_pMainFrame;
  9. VOID Dbg2(CHAR* pszStr, ...)
  10. {
  11. char szData[MAX_PATH] = "[SC] ";
  12. va_list args;
  13. va_start(args, pszStr);
  14. _vsnprintf_s(szData + 5, MAX_PATH - 5, MAX_PATH - 6, pszStr, args);
  15. va_end(args);
  16. strcat_s(szData, "\n");
  17. OutputDebugStringA(szData);
  18. }
  19. // FORMAT CHANGED CALLBACK FUNCTION
  20. //
  21. QRETURN on_process_format_changed2(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, ULONG nVideoWidth, ULONG nVideoHeight, BOOL bVideoIsInterleaved, double dVideoFrameRate, ULONG nAudioChannels, ULONG nAudioBitsPerSample, ULONG nAudioSampleFrequency, PVOID pUserData)
  22. {
  23. //Dbg("format changed Detected \n");
  24. CUB530View* pView = (CUB530View*)pUserData;
  25. if (pView == NULL) { return QCAP_RT_OK; }
  26. if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
  27. pView->m_nVideoWidth = nVideoWidth;
  28. pView->m_nVideoHeight = nVideoHeight;
  29. pView->m_bVideoIsInterleaved = bVideoIsInterleaved;
  30. pView->m_dVideoFrameRate = dVideoFrameRate;
  31. pView->m_nAudioChannels = nAudioChannels;
  32. pView->m_nAudioBitsPerSample = nAudioBitsPerSample;
  33. pView->m_nAudioSampleFrequency = nAudioSampleFrequency;
  34. // OUTPUT FORMAT CHANGED MESSAGE
  35. //
  36. CHAR strVideoInput[MAX_PATH] = { 0 };
  37. CHAR strAudioInput[MAX_PATH] = { 0 };
  38. CHAR strFrameType[MAX_PATH] = { 0 };
  39. UINT nVH = 0;
  40. if (nVideoInput == 0) { sprintf_s(strVideoInput, "COMPOSITE"); }
  41. if (nVideoInput == 1) { sprintf_s(strVideoInput, "SVIDEO"); }
  42. if (nVideoInput == 2) { sprintf_s(strVideoInput, "HDMI"); }
  43. if (nVideoInput == 3) { sprintf_s(strVideoInput, "DVI_D"); }
  44. if (nVideoInput == 4) { sprintf_s(strVideoInput, "COMPONENTS (YCBCR)"); }
  45. if (nVideoInput == 5) { sprintf_s(strVideoInput, "DVI_A (RGB / VGA)"); }
  46. if (nVideoInput == 6) { sprintf_s(strVideoInput, "SDI"); }
  47. if (nVideoInput == 7) { sprintf_s(strVideoInput, "AUTO"); }
  48. if (nAudioInput == 0) { sprintf_s(strAudioInput, "EMBEDDED_AUDIO"); }
  49. if (nAudioInput == 1) { sprintf_s(strAudioInput, "LINE_IN"); }
  50. if (bVideoIsInterleaved == TRUE) { nVH = nVideoHeight / 2; }
  51. else { nVH = nVideoHeight; }
  52. if (bVideoIsInterleaved == TRUE) { sprintf_s(strFrameType, " I "); }
  53. else { sprintf_s(strFrameType, " P "); }
  54. pView->m_strFormatChangedOutput.Format(
  55. _T("INFO : %d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ , VIDEO INPUT : %s , AUDIO INPUT : %s"),
  56. nVideoWidth,
  57. nVH,
  58. strFrameType,
  59. dVideoFrameRate,
  60. nAudioChannels,
  61. nAudioBitsPerSample,
  62. nAudioSampleFrequency,
  63. strVideoInput,
  64. strAudioInput
  65. );
  66. Global::WriteTextLog(_T("采集卡格式变更:%d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ , 视频输入源 : %s , 音频输入源 : %s"),
  67. nVideoWidth,
  68. nVH,
  69. strFrameType,
  70. dVideoFrameRate,
  71. nAudioChannels,
  72. nAudioBitsPerSample,
  73. nAudioSampleFrequency,
  74. strVideoInput,
  75. strAudioInput);
  76. ::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&pView->m_strFormatChangedOutput, ID_STATUSBAR_PANE1);
  77. // NO SOURCE
  78. //
  79. if (nVideoWidth == 0 &&
  80. nVideoHeight == 0 &&
  81. dVideoFrameRate == 0.0 &&
  82. nAudioChannels == 0 &&
  83. nAudioBitsPerSample == 0 &&
  84. nAudioSampleFrequency == 0)
  85. {
  86. pView->m_bNoSignal = TRUE;
  87. }
  88. else
  89. {
  90. pView->m_bNoSignal = FALSE;
  91. }
  92. pView->SetTimer(0x00000000, 1, NULL);
  93. return QCAP_RT_OK;
  94. }
  95. // NO SIGNAL DETEACTED CALLBACK FUNCTION
  96. //
  97. QRETURN on_process_no_signal_detected2(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
  98. {
  99. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  100. CUB530View* pView = (CUB530View*)pUserData;
  101. //Dbg("No Signal Detected \n");
  102. if (pView == NULL) { return QCAP_RT_OK; }
  103. if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
  104. //pView->SetRibbonStatusBarText("当前采集卡无信号。", ID_STATUSBAR_PANE1);
  105. Global::WriteTextLog(_T("当前采集卡无信号"));
  106. ::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&CString("当前采集卡无信号"), ID_STATUSBAR_PANE1);
  107. pView->m_bNoSignal = TRUE;
  108. pView->SetTimer(0x00000000, 1, NULL);
  109. return QCAP_RT_OK;
  110. }
  111. // SIGNAL REMOVED CALLBACK FUNCTION
  112. //
  113. QRETURN on_process_signal_removed2(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
  114. {
  115. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  116. CUB530View* pView = (CUB530View*)pUserData;
  117. if (pView == NULL) { return QCAP_RT_OK; }
  118. if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
  119. //pView->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
  120. Global::WriteTextLog(_T("当前采集卡信号被移除"));
  121. ::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&CString("当前采集卡信号被移除"), ID_STATUSBAR_PANE1);
  122. pView->m_bNoSignal = TRUE;
  123. pView->SetTimer(0x00000000, 1, NULL);
  124. return QCAP_RT_OK;
  125. }
  126. // PREVIEW VIDEO CALLBACK FUNCTION
  127. //
  128. QRETURN on_process_preview_video_buffer2(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
  129. {
  130. CUB530View* pView = (CUB530View*)pUserData;
  131. if (pView)
  132. {
  133. // 尝试加锁;
  134. if (!pView->m_mut_cpature.try_lock())
  135. {
  136. #ifdef DEBUG
  137. OutputDebugStringA("!pView->m_mut_cpature.try_lock()\n");
  138. #endif
  139. return QCAP_RT_OK;
  140. }
  141. // 是否触发截图;
  142. if (pView->m_bCaptureImage)
  143. {
  144. // 加锁;
  145. std::lock_guard<std::mutex> lk(pView->m_mut_thread);
  146. // 复制数据;
  147. pView->m_dwBufferLen = nFrameBufferLen;
  148. pView->m_pBuffer = new BYTE[nFrameBufferLen];
  149. memcpy(pView->m_pBuffer, pFrameBuffer, nFrameBufferLen);
  150. // 通知线程保存图片;
  151. pView->m_thread_cond.notify_one();
  152. // 恢复截图标记,防止重复截图;
  153. pView->m_bCaptureImage = FALSE;
  154. #ifdef DEBUG
  155. OutputDebugStringA("preview_video_buffer:pView->m_bCaptureImage\n");
  156. #endif
  157. }
  158. // 解锁;
  159. pView->m_mut_cpature.unlock();
  160. }
  161. return QCAP_RT_OK;
  162. }
  163. // PREVIEW AUDIO CALLBACK FUNCTION
  164. //
  165. QRETURN on_process_preview_audio_buffer2(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
  166. {
  167. return QCAP_RT_OK;
  168. }
  169. // VIDEO HARDARE ENCODER CALLBACK FUNCTION
  170. //
  171. QRETURN on_process_hardware_encoder_video_buffer2(PVOID pDevice, UINT iRecNum, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, BOOL bIsKeyFrame, PVOID pUserData)
  172. {
  173. return QCAP_RT_OK;
  174. }
  175. QRETURN on_process_snapshot_done2(PVOID pDevice, CHAR* pszFilePathName, PVOID pUserData)
  176. {
  177. return QCAP_RT_OK;
  178. }
  179. QRETURN on_process_snapshot_stream2(PVOID pDevice, CHAR* pszFilePathName, BYTE* pStreamBuffer, ULONG nStreamBufferLen, PVOID pUserData)
  180. {
  181. // 注意:在调用本回调函数前,已经保存了图片!
  182. CUB530View* pView = (CUB530View*)pUserData;
  183. if (pView->m_bHoriontal || pView->m_bVertically)
  184. Global::SaveImgByRotate(pszFilePathName, pStreamBuffer, nStreamBufferLen, pView->m_bHoriontal, pView->m_bVertically);
  185. return QCAP_RT_OK;
  186. }
  187. // CUB530View
  188. IMPLEMENT_DYNCREATE(CUB530View, CFormView)
  189. CUB530View::CUB530View(): CFormView(DLG_UB530VIEW)
  190. {
  191. m_hVideoDevice = NULL;
  192. m_bIsRecord = FALSE;
  193. m_bNoSignal = FALSE;
  194. m_bVertically = FALSE;
  195. m_bHoriontal = FALSE;
  196. m_bAppQuit = FALSE;
  197. m_pBuffer = NULL;
  198. m_bCaptureImage = FALSE;
  199. m_dwBufferLen = 0;
  200. m_bIsMp4 = TRUE;
  201. m_bSupportGPU = FALSE;
  202. m_shotDir = ShotLocal;
  203. }
  204. CUB530View::~CUB530View()
  205. {
  206. g_ub530.EndOfThread();
  207. m_bAppQuit = TRUE;
  208. HwUninitialize();
  209. }
  210. void CUB530View::DoDataExchange(CDataExchange* pDX)
  211. {
  212. CFormView::DoDataExchange(pDX);
  213. }
  214. BEGIN_MESSAGE_MAP(CUB530View, CFormView)
  215. ///////////////////////////////////
  216. ON_WM_TIMER()
  217. ON_COMMAND(ID_CUT_BMP, &CUB530View::OnCutBmp)
  218. ON_COMMAND(ID_CUT_JPG, &CUB530View::OnCutJpg)
  219. ON_COMMAND(ID_START_RECORD, &CUB530View::OnStartRecord)
  220. ON_COMMAND(ID_STOP_RECORD, &CUB530View::OnStopRecord)
  221. ON_COMMAND(ID_CHECK_VERTICALLY, &CUB530View::OnCheckVertically)
  222. ON_COMMAND(ID_CHECK_HORIONTAL, &CUB530View::OnCheckHoriontal)
  223. ON_UPDATE_COMMAND_UI(ID_CHECK_VERTICALLY, &CUB530View::OnUpdateCheckVertically)
  224. ON_UPDATE_COMMAND_UI(ID_CHECK_HORIONTAL, &CUB530View::OnUpdateCheckHoriontal)
  225. ON_COMMAND(ID_TRAYMENU_RECONNECT, &CUB530View::OnTraymenuReconnect)
  226. ON_COMMAND(ID_CHECK_SUPORT_GPU, &CUB530View::OnCheckSuportGpu)
  227. ON_COMMAND(ID_CHECK_FORMAT_MP4, &CUB530View::OnCheckFormatMp4)
  228. ON_COMMAND(ID_CHECK_FORMAT_AVI, &CUB530View::OnCheckFormatAvi)
  229. ON_UPDATE_COMMAND_UI(ID_CHECK_SUPORT_GPU, &CUB530View::OnUpdateCheckSuportGpu)
  230. ON_UPDATE_COMMAND_UI(ID_CHECK_FORMAT_MP4, &CUB530View::OnUpdateCheckFormatMp4)
  231. ON_UPDATE_COMMAND_UI(ID_CHECK_FORMAT_AVI, &CUB530View::OnUpdateCheckFormatAvi)
  232. ON_UPDATE_COMMAND_UI(ID_START_RECORD, &CUB530View::OnUpdateStartRecord)
  233. ON_UPDATE_COMMAND_UI(ID_STOP_RECORD, &CUB530View::OnUpdateStopRecord)
  234. ON_COMMAND(ID_CHECK_SHOT_LOCAL, &CUB530View::OnCheckShotLocal)
  235. ON_UPDATE_COMMAND_UI(ID_CHECK_SHOT_LOCAL, &CUB530View::OnUpdateCheckShotLocal)
  236. ON_COMMAND(ID_CHECK_SHOT_SYSTEM, &CUB530View::OnCheckShotSystem)
  237. ON_UPDATE_COMMAND_UI(ID_CHECK_SHOT_SYSTEM, &CUB530View::OnUpdateCheckShotSystem)
  238. ON_COMMAND(ID_CHECK_SHOT_SPEC, &CUB530View::OnCheckShotSpec)
  239. ON_UPDATE_COMMAND_UI(ID_CHECK_SHOT_SPEC, &CUB530View::OnUpdateCheckShotSpec)
  240. ON_WM_CREATE()
  241. ON_COMMAND(ID_CHECK_IR_SHOT, &CUB530View::OnCheckIrShot)
  242. ON_UPDATE_COMMAND_UI(ID_CHECK_IR_SHOT, &CUB530View::OnUpdateCheckIrShot)
  243. END_MESSAGE_MAP()
  244. // CUB530View 诊断
  245. #ifdef _DEBUG
  246. void CUB530View::AssertValid() const
  247. {
  248. CFormView::AssertValid();
  249. }
  250. #ifndef _WIN32_WCE
  251. void CUB530View::Dump(CDumpContext& dc) const
  252. {
  253. CFormView::Dump(dc);
  254. }
  255. #endif
  256. #endif //_DEBUG
  257. // CUB530View 消息处理程序
  258. void CUB530View::OnInitialUpdate()
  259. {
  260. CFormView::OnInitialUpdate();
  261. // TODO: 在此添加专用代码和/或调用基类
  262. // CMemoryClient::m_pView2 = this;
  263. // g_ub530.InitMemery();
  264. // g_ub530.StartThread();
  265. //
  266. // // TODO: 在此添加您专用的创建代码
  267. // // 创建视频流,并关联指定显示窗口;
  268. // HwInitialize();
  269. //
  270. // // 创建截图线程;
  271. // std::thread t(CaptureImageThread, this);
  272. // t.detach();
  273. }
  274. void CUB530View::OnDraw(CDC* pDC)
  275. {
  276. // TODO: 在此添加专用代码和/或调用基类
  277. // TO FILL IN THE TEXT
  278. //
  279. if (m_hVideoDevice == 0 || m_bNoSignal) {
  280. CFont font;
  281. ULONG nFontSize = 300;
  282. font.CreatePointFont(nFontSize, TEXT("Arial"), NULL);
  283. HFONT hOldFont = (HFONT)pDC->SelectObject(&font);
  284. pDC->SetBkMode(TRANSPARENT);
  285. pDC->SetTextColor(RGB(255, 255, 255));
  286. CRect rect_client;
  287. GetClientRect(&rect_client);
  288. CString string = _T("");
  289. if (m_hVideoDevice == 0)
  290. {
  291. CBrush brush_fill_rect(RGB(0, 0, 0));
  292. pDC->FillRect(&rect_client, &brush_fill_rect);
  293. string = TEXT("No Device");
  294. //g_pMainFrame->SetRibbonStatusBarText("当前采集卡设备被移除。", ID_STATUSBAR_PANE1);
  295. }
  296. else if (m_bNoSignal)
  297. {
  298. CBrush brush_fill_rect(RGB(0, 0, 255));
  299. pDC->FillRect(&rect_client, &brush_fill_rect);
  300. string = TEXT("No Source");
  301. //g_pMainFrame->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
  302. }
  303. pDC->DrawText(string, &rect_client, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  304. pDC->SelectObject(&hOldFont);
  305. font.DeleteObject();
  306. }
  307. }
  308. BOOL CUB530View::HwInitialize()
  309. {
  310. if (m_hVideoDevice != NULL)
  311. return TRUE;
  312. // CALLBACK FUNCTION
  313. PF_FORMAT_CHANGED_CALLBACK pFormatChangedCB = { 0 };
  314. PF_VIDEO_PREVIEW_CALLBACK pPreviewVideoCB = { 0 };
  315. PF_AUDIO_PREVIEW_CALLBACK pPreviewAudioCB = { 0 };
  316. PF_VIDEO_HARDWARE_ENCODER_CALLBACK pHardwareEncoderVideoCB = { 0 };
  317. PF_NO_SIGNAL_DETECTED_CALLBACK pNoSignalDetectedCB = { 0 };
  318. PF_SIGNAL_REMOVED_CALLBACK pSignalRemovedCB = { 0 };
  319. PF_SNAPSHOT_DONE_CALLBACK pSnapShotDoneCB = { 0 };
  320. PF_SNAPSHOT_STREAM_CALLBACK pSnapShotStreamCB = { 0 };
  321. // CREATE CAPTURE DEVICE
  322. //
  323. if (m_hVideoDevice == NULL)
  324. {
  325. QRESULT qr = QCAP_CREATE("CY3014 USB", 0, m_hWnd, &m_hVideoDevice, 1);
  326. if ( qr != QCAP_RS_SUCCESSFUL )
  327. {
  328. OutputDebugString("初始化UB530失败\n");
  329. }
  330. }
  331. if (m_hVideoDevice == NULL) {
  332. return FALSE;
  333. }
  334. // REGISTER FORMAT CHANGED CALLBACK FUNCTION
  335. pFormatChangedCB = on_process_format_changed2;
  336. QCAP_REGISTER_FORMAT_CHANGED_CALLBACK(m_hVideoDevice, pFormatChangedCB, this);
  337. // REGISTER PREVIEW VIDEO CALLBACK FUNCTION
  338. pPreviewVideoCB = on_process_preview_video_buffer2;
  339. QCAP_REGISTER_VIDEO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewVideoCB, this);
  340. // REGISTER PREVIEW AUDIO CALLBACK FUNCTION
  341. //pPreviewAudioCB = on_process_preview_audio_buffer;
  342. //QCAP_REGISTER_AUDIO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewAudioCB, this);
  343. // REGISTER HARDWARE ENCODER VIDEO CALLBACK FUNCTION
  344. //pHardwareEncoderVideoCB = on_process_hardware_encoder_video_buffer;
  345. //QCAP_REGISTER_VIDEO_HARDWARE_ENCODER_CALLBACK(m_hVideoDevice, 0, pHardwareEncoderVideoCB, this);
  346. // REGISTER NO SIGNAL DETECTED CALLBACK FUNCTION
  347. pNoSignalDetectedCB = on_process_no_signal_detected2;
  348. QCAP_REGISTER_NO_SIGNAL_DETECTED_CALLBACK(m_hVideoDevice, pNoSignalDetectedCB, this);
  349. // REGISTER SIGNAL REMOVED CALLBACK FUNCTION
  350. pSignalRemovedCB = on_process_signal_removed2;
  351. QCAP_REGISTER_SIGNAL_REMOVED_CALLBACK(m_hVideoDevice, pSignalRemovedCB, this);
  352. #if 1
  353. //
  354. pSnapShotDoneCB = on_process_snapshot_done2;
  355. QCAP_REGISTER_SNAPSHOT_DONE_CALLBACK(m_hVideoDevice, pSnapShotDoneCB, this);
  356. //
  357. pSnapShotStreamCB = on_process_snapshot_stream2;
  358. QCAP_REGISTER_SNAPSHOT_STREAM_CALLBACK(m_hVideoDevice, pSnapShotStreamCB, this);
  359. #endif
  360. QCAP_SET_VIDEO_DEINTERLACE_TYPE(m_hVideoDevice, QCAP_SOFTWARE_DEINTERLACE_TYPE_BLENDING);
  361. QCAP_SET_VIDEO_DEINTERLACE(m_hVideoDevice, 0);
  362. QCAP_SET_AUDIO_VOLUME(m_hVideoDevice, 100);
  363. 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);
  364. QCAP_SET_VIDEO_INPUT(m_hVideoDevice, QCAP_INPUT_TYPE_AUTO);
  365. QCAP_RUN(m_hVideoDevice);
  366. // 刷新区域;
  367. Invalidate();
  368. // UPDATE USER INTERFACE RESOURCE
  369. if (m_hVideoDevice == 0) {
  370. /*m_oSetupDialog.m_btnVideoInput.EnableWindow(FALSE);
  371. m_oSetupDialog.m_btnVideoQuality.EnableWindow(FALSE);
  372. m_oSetupDialog.m_btnAudioInput.EnableWindow(FALSE);
  373. m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(FALSE);
  374. m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(FALSE);
  375. m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(FALSE);
  376. m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
  377. m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(FALSE);
  378. m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
  379. m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(FALSE);
  380. m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
  381. m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
  382. m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
  383. m_oSetupDialog.m_checkGPU_1_2.EnableWindow(FALSE);
  384. m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
  385. m_oSetupDialog.m_checkGPU_1_3.EnableWindow(FALSE);
  386. m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
  387. m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(FALSE);
  388. m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
  389. }
  390. else {
  391. /*m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(TRUE);
  392. m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(TRUE);
  393. m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(TRUE);
  394. m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
  395. m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(TRUE);
  396. m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
  397. m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(TRUE);
  398. m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
  399. m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
  400. m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
  401. m_oSetupDialog.m_checkGPU_1_2.EnableWindow(TRUE);
  402. m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
  403. m_oSetupDialog.m_checkGPU_1_3.EnableWindow(TRUE);
  404. m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
  405. m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(TRUE);
  406. m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
  407. }
  408. return TRUE;
  409. }
  410. BOOL CUB530View::HwUninitialize()
  411. {
  412. if (m_hVideoDevice != 0) {
  413. QCAP_STOP(m_hVideoDevice);
  414. QCAP_DESTROY(m_hVideoDevice);
  415. m_hVideoDevice = NULL;
  416. }
  417. return TRUE;
  418. }
  419. void CUB530View::CaptureSingleImage(LPTSTR lpszFileName, BOOL bIsJPG)
  420. {
  421. if (m_hVideoDevice != NULL)
  422. {
  423. if (bIsJPG)
  424. {
  425. QCAP_SNAPSHOT_JPG(m_hVideoDevice, lpszFileName, 100, FALSE, 5000); //参数4:是否异步;
  426. }
  427. else
  428. {
  429. QCAP_SNAPSHOT_BMP(m_hVideoDevice, lpszFileName, FALSE, 5000);
  430. }
  431. #ifdef _DEBUG
  432. Global::WriteTextLog("完成:CaptureSingleImage");
  433. #endif
  434. }
  435. }
  436. std::string CUB530View::CaptureSingleImageAutoName(LPCTSTR lpszDir, BOOL bIsJPG)
  437. {
  438. if (m_hVideoDevice != NULL)
  439. {
  440. TCHAR szPath[MAX_PATH] = { 0 };
  441. // 毫秒级;
  442. time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
  443. auto tt = std::chrono::system_clock::to_time_t(tp);
  444. std::tm now = { 0 };
  445. localtime_s(&now, &tt); // 时间戳转成本地时间;
  446. int msc = tp.time_since_epoch().count() % 1000;
  447. if (bIsJPG)
  448. {
  449. _stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
  450. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  451. now.tm_year + 1990,
  452. now.tm_mon + 1,
  453. now.tm_mday,
  454. now.tm_hour,
  455. now.tm_min,
  456. now.tm_sec,
  457. msc);
  458. QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, FALSE, 5000);
  459. }
  460. else
  461. {
  462. _stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
  463. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  464. now.tm_year + 1990,
  465. now.tm_mon + 1,
  466. now.tm_mday,
  467. now.tm_hour,
  468. now.tm_min,
  469. now.tm_sec,
  470. msc);
  471. QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, FALSE, 5000);
  472. }
  473. #ifdef _DEBUG
  474. Global::WriteTextLog("完成:CaptureSingleImageAutoName");
  475. #endif
  476. return std::string(szPath);
  477. }
  478. return std::string();
  479. }
  480. void CUB530View::CaptureMultiImage(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
  481. {
  482. std::thread t([&](CUB530View* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
  483. // 连续截图;
  484. TCHAR szDir[MAX_PATH] = { 0 };
  485. TCHAR szPath[MAX_PATH] = { 0 };
  486. _stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
  487. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  488. lpszPrefix ? lpszPrefix : _T(""));
  489. auto start = system_clock::now();
  490. while (true)
  491. {
  492. // C++11获取当前时间;
  493. time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
  494. if (bIsJPG)
  495. {
  496. _stprintf_s(szPath, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
  497. QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, TRUE);
  498. // 等待磁盘完成写入;
  499. //Sleep(20);
  500. }
  501. else
  502. {
  503. _stprintf_s(szPath, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
  504. QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, TRUE);
  505. // 等待磁盘完成写入;
  506. //Sleep(530);
  507. }
  508. auto duration = duration_cast<milliseconds>(system_clock::now() - start);
  509. if (duration.count() >= nDurationTime)
  510. break;
  511. }
  512. }, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
  513. t.detach();
  514. }
  515. void CUB530View::CaptureSingleImageEx(LPTSTR lpszFileName, BOOL bIsJPG)
  516. {
  517. {
  518. // 加锁;
  519. std::lock_guard<std::mutex> lk(m_mut_cpature);
  520. // 标记截图;
  521. m_bCaptureImage = TRUE;
  522. // 初始化数据;
  523. ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
  524. m_CaptureInfo.bIsJPG = bIsJPG;
  525. m_CaptureInfo.bSingle = TRUE;
  526. m_CaptureInfo.IsAutoName = FALSE;
  527. m_CaptureInfo.nCaputerCount = 0;
  528. m_CaptureInfo.nKeepTime = 0;
  529. memset(m_CaptureInfo.szPrefix, 0, 64);
  530. //_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
  531. _stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
  532. //m_strCaptureName = lpszFileName;
  533. }
  534. // 等待截图完成;
  535. {
  536. // 加锁;
  537. std::unique_lock<std::mutex> lk(m_mut_cpature);
  538. m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
  539. // 解锁;
  540. lk.unlock();
  541. }
  542. }
  543. std::string CUB530View::CaptureSingleImageAutoNameEx(LPCTSTR lpszDir, BOOL bIsJPG)
  544. {
  545. {
  546. // 加锁;
  547. std::lock_guard<std::mutex> lk(m_mut_cpature);
  548. // 标记截图;
  549. m_bCaptureImage = TRUE;
  550. // 初始化数据;
  551. ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
  552. m_CaptureInfo.bIsJPG = bIsJPG;
  553. m_CaptureInfo.bSingle = TRUE;
  554. m_CaptureInfo.IsAutoName = FALSE;
  555. m_CaptureInfo.nCaputerCount = 0;
  556. m_CaptureInfo.nKeepTime = 0;
  557. memset(m_CaptureInfo.szPrefix, 0, 64);
  558. memset(m_CaptureInfo.szSaveDir, 0, MAX_PATH);
  559. // 毫秒级;
  560. time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
  561. auto tt = std::chrono::system_clock::to_time_t(tp);
  562. std::tm now = { 0 };
  563. localtime_s(&now, &tt); // 时间戳转成本地时间;
  564. int msc = tp.time_since_epoch().count() % 1000;
  565. if (bIsJPG)
  566. {
  567. _stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
  568. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  569. now.tm_year + 1990,
  570. now.tm_mon + 1,
  571. now.tm_mday,
  572. now.tm_hour,
  573. now.tm_min,
  574. now.tm_sec,
  575. msc);
  576. }
  577. else
  578. {
  579. _stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
  580. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  581. now.tm_year + 1990,
  582. now.tm_mon + 1,
  583. now.tm_mday,
  584. now.tm_hour,
  585. now.tm_min,
  586. now.tm_sec,
  587. msc);
  588. }
  589. #ifdef DEBUG
  590. OutputDebugStringA(m_CaptureInfo.szSaveDir);
  591. OutputDebugStringA("\tCVideoCaptureView::CaptureSingleImageAutoNameEx\n");
  592. #endif // DEBUG
  593. }
  594. // 等待截图完成;
  595. {
  596. // 加锁;
  597. std::unique_lock<std::mutex> lk(m_mut_cpature);
  598. m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
  599. // 解锁;
  600. lk.unlock();
  601. }
  602. return std::string(m_CaptureInfo.szSaveDir);
  603. }
  604. void CUB530View::CaptureMultiImageEx(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
  605. {
  606. std::thread t([&](CUB530View* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
  607. // 连续截图;
  608. TCHAR szDir[MAX_PATH] = { 0 };
  609. _stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
  610. lpszDir ? lpszDir : Global::g_szCurModuleDir,
  611. lpszPrefix ? lpszPrefix : _T(""));
  612. auto start = system_clock::now();
  613. while (true)
  614. {
  615. // C++11获取当前时间;
  616. time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
  617. {
  618. // 加锁;
  619. std::lock_guard<std::mutex> lk(m_mut_cpature);
  620. // 标记截图;
  621. m_bCaptureImage = TRUE;
  622. // 初始化数据;
  623. ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
  624. m_CaptureInfo.bIsJPG = bIsJPG;
  625. m_CaptureInfo.bSingle = FALSE;
  626. m_CaptureInfo.IsAutoName = TRUE;
  627. m_CaptureInfo.nCaputerCount = 0;
  628. m_CaptureInfo.nKeepTime = nDurationTime;
  629. _stprintf_s(m_CaptureInfo.szPrefix, _T("%s"), lpszPrefix);
  630. if (bIsJPG)
  631. {
  632. _stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
  633. }
  634. else
  635. {
  636. _stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
  637. }
  638. }
  639. // 等待截图完成;
  640. {
  641. // 加锁;
  642. std::unique_lock<std::mutex> lk(m_mut_cpature);
  643. m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
  644. // 解锁;
  645. lk.unlock();
  646. }
  647. auto duration = duration_cast<milliseconds>(system_clock::now() - start);
  648. if (duration.count() >= nDurationTime)
  649. break;
  650. }
  651. }, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
  652. t.detach();
  653. }
  654. BOOL CUB530View::SaveImageByCaptureInfo(const CaptureInfo& capInfo)
  655. {
  656. if (m_pBuffer == NULL)
  657. {
  658. return FALSE;
  659. }
  660. BOOL bRet = FALSE;
  661. // 保存截图;
  662. HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, m_nVideoWidth * m_nVideoHeight * 4);
  663. if (hMemery != NULL)
  664. {
  665. BYTE* pDstFrameBuffer = NULL;
  666. pDstFrameBuffer = (BYTE*)GlobalLock(hMemery);
  667. if (pDstFrameBuffer != NULL)
  668. {
  669. QRESULT QRet = QCAP_COLORSPACE_YUY2_TO_ABGR32(m_pBuffer,
  670. m_nVideoWidth,
  671. m_nVideoHeight,
  672. 0,
  673. pDstFrameBuffer,
  674. m_nVideoWidth,
  675. m_nVideoHeight,
  676. 0);
  677. Status stat = GenericError;
  678. Bitmap* pImg = ::new Bitmap(
  679. m_nVideoWidth,
  680. m_nVideoHeight,
  681. m_nVideoWidth * 4,
  682. PixelFormat32bppRGB,
  683. pDstFrameBuffer);
  684. if (m_bHoriontal && !m_bVertically)
  685. pImg->RotateFlip(RotateNoneFlipX);// 水平翻转;
  686. else if (m_bHoriontal && m_bVertically)
  687. pImg->RotateFlip(Rotate180FlipNone);// 270度;
  688. else if (!m_bHoriontal && m_bVertically)
  689. pImg->RotateFlip(Rotate180FlipX);// 垂直翻转;
  690. CLSID encoderClsid = { 0 };
  691. CString strFileName = m_CaptureInfo.szSaveDir;
  692. // 需要判断路径是否存在,不存在创建目录;
  693. int nIndex = strFileName.ReverseFind(_T('\\'));
  694. if (nIndex != -1)
  695. {
  696. if (!PathFileExists(strFileName.Left(nIndex)))
  697. {
  698. // 如果文件夹不存在,创建;
  699. SHCreateDirectoryEx(NULL, strFileName.Left(nIndex), NULL);
  700. }
  701. }
  702. BSTR newfile = strFileName.AllocSysString();
  703. if (!capInfo.bIsJPG)
  704. {
  705. Global::GetEncoderClsid(L"image/bmp", &encoderClsid);
  706. stat = pImg->Save(newfile, &encoderClsid, NULL);
  707. }
  708. else
  709. {
  710. Global::GetEncoderClsid(L"image/jpeg", &encoderClsid);
  711. EncoderParameters encoderParameters;
  712. encoderParameters.Count = 1;
  713. encoderParameters.Parameter[0].Guid = EncoderQuality;
  714. encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
  715. encoderParameters.Parameter[0].NumberOfValues = 1;
  716. // Save the image as a JPEG with quality level 100.
  717. ULONG uQuality = 100;
  718. encoderParameters.Parameter[0].Value = &uQuality;
  719. stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
  720. }
  721. if (pImg)
  722. ::delete pImg;
  723. pImg = NULL;
  724. SysFreeString(newfile);
  725. bRet = (stat == 0 ? TRUE : FALSE);
  726. #ifdef DEBUG
  727. if (bRet)
  728. {
  729. OutputDebugStringA(strFileName);
  730. OutputDebugStringA("\tSave Image::Ok\n");
  731. }
  732. #endif
  733. }
  734. #ifdef DEBUG
  735. else
  736. {
  737. OutputDebugStringA("pDstFrameBuffer == NULL\n");
  738. }
  739. #endif
  740. GlobalUnlock(hMemery);
  741. }
  742. #ifdef DEBUG
  743. else
  744. {
  745. DWORD dwError = GetLastError();
  746. CString strError = _T("");
  747. strError.Format(_T("hMemery == NULL分配内存出错:%ld\n"), dwError);
  748. OutputDebugStringA(strError);
  749. }
  750. #endif
  751. if (m_pBuffer)
  752. delete[]m_pBuffer;
  753. m_pBuffer = NULL;
  754. // 必须调用GlobalFree释放;
  755. GlobalFree(hMemery);
  756. return bRet;
  757. }
  758. void CUB530View::CaptureImageThread(CUB530View* pView)
  759. {
  760. CString strFileName = _T("");
  761. while (!pView->m_bAppQuit)
  762. {
  763. std::unique_lock<std::mutex> lk(pView->m_mut_thread); // 这里使用unique_lock是为了后面方便解锁
  764. #if 1 // 避免线程虚假唤醒;
  765. pView->m_thread_cond.wait(lk, [&]() {return pView->m_pBuffer; });
  766. #else
  767. while (!pView->m_pBuffer)
  768. pView->m_data_cond.wait(lk);
  769. #endif
  770. // 保存截图;
  771. pView->SaveImageByCaptureInfo(pView->m_CaptureInfo);
  772. // 通知截图完成;
  773. pView->m_capture_cond.notify_one();
  774. // 解锁;
  775. lk.unlock();
  776. // sleep 10ms;
  777. //this_thread::sleep_for(chrono::milliseconds(10));
  778. }
  779. }
  780. void CUB530View::StartRecord(DWORD dwDuration, LPCTSTR lpSavePath)
  781. {
  782. QRESULT QRet = QCAP_RS_SUCCESSFUL;
  783. if (!m_bIsMp4) // 音频格式;
  784. {
  785. QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_PCM);
  786. //_tcscat_s(szPath, _T(".avi"));
  787. }
  788. else
  789. {
  790. QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_AAC);
  791. //_tcscat_s(szPath, _T(".mp4"));
  792. }
  793. // 设置视频属性;
  794. QRet = QCAP_SET_VIDEO_RECORD_PROPERTY(
  795. m_hVideoDevice,
  796. 0,
  797. m_bSupportGPU ? QCAP_ENCODER_TYPE_INTEL_MEDIA_SDK : QCAP_ENCODER_TYPE_SOFTWARE,
  798. QCAP_ENCODER_FORMAT_H264,
  799. QCAP_RECORD_MODE_CBR,
  800. 8000,
  801. 16 * 1024 * 1024, // 16最高质量;
  802. 30, // 每秒多少帧
  803. 0,
  804. 0,
  805. QCAP_DOWNSCALE_MODE_OFF);
  806. // 开始录屏;
  807. QRet = QCAP_START_RECORD(m_hVideoDevice, 0, const_cast<CHAR*>(lpSavePath), QCAP_RECORD_FLAG_FULL, 0.0, 0.0, 0.0, 0, NULL);
  808. m_bIsRecord = TRUE;
  809. }
  810. void CUB530View::StopRecord()
  811. {
  812. QCAP_STOP_RECORD(m_hVideoDevice, 0);
  813. m_bIsRecord = FALSE;
  814. }
  815. //////////////////////////////////////////////////////////////////////////
  816. void CUB530View::SetRibbonStatusBarText(CString strText, int uId)
  817. {
  818. if (g_pMainFrame)
  819. {
  820. g_pMainFrame->SetRibbonStatusBarText(strText, uId);
  821. }
  822. }
  823. void CUB530View::OnTimer(UINT_PTR nIDEvent)
  824. {
  825. // TODO: 在此添加消息处理程序代码和/或调用默认值
  826. if (nIDEvent == 0)
  827. {
  828. KillTimer(0);
  829. if (m_bNoSignal)
  830. {
  831. if (m_bIsRecord)
  832. {
  833. QCAP_STOP_RECORD(m_hVideoDevice, 0);
  834. m_bIsRecord = FALSE;
  835. }
  836. }
  837. else
  838. {
  839. }
  840. }
  841. CView::OnTimer(nIDEvent);
  842. }
  843. void CUB530View::OnCutBmp()
  844. {
  845. // TODO: 在此添加命令处理程序代码
  846. TCHAR szImgDir[MAX_PATH] = {0};
  847. if ( m_shotDir == ShotLocal )
  848. CaptureSingleImageAutoName(NULL, FALSE);
  849. else if (m_shotDir == ShotSystem)
  850. {
  851. CaptureSingleImageAutoName(g_pMainFrame->m_szCurMenuTreeDir, FALSE);
  852. }
  853. else if (m_shotDir == ShotSpec)
  854. {
  855. CaptureSingleImageAutoName(m_szSpecDir, FALSE);
  856. }
  857. }
  858. void CUB530View::OnCutJpg()
  859. {
  860. // TODO: 在此添加命令处理程序代码
  861. TCHAR szImgDir[MAX_PATH] = { 0 };
  862. if (m_shotDir == ShotLocal)
  863. CaptureSingleImageAutoName(NULL, TRUE);
  864. else if (m_shotDir == ShotSystem)
  865. {
  866. CaptureSingleImageAutoName(g_pMainFrame->m_szCurMenuTreeDir, TRUE);
  867. }
  868. else if (m_shotDir == ShotSpec)
  869. {
  870. CaptureSingleImageAutoName(m_szSpecDir, TRUE);
  871. }
  872. }
  873. void CUB530View::OnStartRecord()
  874. {
  875. // TODO: 在此添加命令处理程序代码
  876. TCHAR szPath[MAX_PATH] = { 0 };
  877. // 毫秒级;
  878. time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
  879. auto tt = std::chrono::system_clock::to_time_t(tp);
  880. std::tm now = { 0 };
  881. localtime_s(&now, &tt); // 时间戳转成本地时间;
  882. int msc = tp.time_since_epoch().count() % 1000;
  883. _stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d"),
  884. Global::g_szCurModuleDir,
  885. now.tm_year + 1990,
  886. now.tm_mon + 1,
  887. now.tm_mday,
  888. now.tm_hour,
  889. now.tm_min,
  890. now.tm_sec,
  891. msc);
  892. QRESULT QRet = QCAP_RS_SUCCESSFUL;
  893. if (!m_bIsMp4) // 音频格式;
  894. {
  895. QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_PCM);
  896. _tcscat_s(szPath, _T(".avi"));
  897. }
  898. else
  899. {
  900. QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_AAC);
  901. _tcscat_s(szPath, _T(".mp4"));
  902. }
  903. // 设置视频属性;
  904. QRet = QCAP_SET_VIDEO_RECORD_PROPERTY(
  905. m_hVideoDevice,
  906. 0,
  907. m_bSupportGPU ? QCAP_ENCODER_TYPE_INTEL_MEDIA_SDK : QCAP_ENCODER_TYPE_SOFTWARE,
  908. QCAP_ENCODER_FORMAT_H264,
  909. QCAP_RECORD_MODE_CBR,
  910. 8000,
  911. 16 * 1024 * 1024, // 16最高质量;
  912. 30, // 每秒多少帧
  913. 0,
  914. 0,
  915. QCAP_DOWNSCALE_MODE_OFF);
  916. // 开始录屏;
  917. QRet = QCAP_START_RECORD(m_hVideoDevice, 0, szPath, QCAP_RECORD_FLAG_FULL, 0.0, 0.0, 0.0, 0, NULL);
  918. m_bIsRecord = TRUE;
  919. }
  920. void CUB530View::OnStopRecord()
  921. {
  922. // TODO: 在此添加命令处理程序代码
  923. QCAP_STOP_RECORD(m_hVideoDevice, 0);
  924. m_bIsRecord = FALSE;
  925. }
  926. void CUB530View::OnCheckVertically()
  927. {
  928. // TODO: 在此添加命令处理程序代码
  929. CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
  930. CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_VERTICALLY);
  931. m_bVertically = !pCheckbox->IsChecked();
  932. if (m_hVideoDevice)
  933. {
  934. QCAP_SET_VIDEO_MIRROR(m_hVideoDevice, m_bHoriontal, m_bVertically);
  935. }
  936. }
  937. void CUB530View::OnCheckHoriontal()
  938. {
  939. // TODO: 在此添加命令处理程序代码
  940. CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
  941. CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_HORIONTAL);
  942. m_bHoriontal = !pCheckbox->IsChecked();
  943. if (m_hVideoDevice)
  944. {
  945. QCAP_SET_VIDEO_MIRROR(m_hVideoDevice, m_bHoriontal, m_bVertically);
  946. }
  947. }
  948. void CUB530View::OnUpdateCheckVertically(CCmdUI* pCmdUI)
  949. {
  950. // TODO: 在此添加命令更新用户界面处理程序代码
  951. pCmdUI->SetCheck(m_bVertically);
  952. }
  953. void CUB530View::OnUpdateCheckHoriontal(CCmdUI* pCmdUI)
  954. {
  955. // TODO: 在此添加命令更新用户界面处理程序代码
  956. pCmdUI->SetCheck(m_bHoriontal);
  957. }
  958. void CUB530View::OnTraymenuReconnect()
  959. {
  960. // TODO: 在此添加命令处理程序代码
  961. HwUninitialize();// 断开;
  962. Invalidate();
  963. HwInitialize();// 重连;
  964. }
  965. void CUB530View::OnCheckSuportGpu()
  966. {
  967. // TODO: 在此添加命令处理程序代码
  968. CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
  969. CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_SUPORT_GPU);
  970. m_bSupportGPU = !pCheckbox->IsChecked();
  971. }
  972. void CUB530View::OnCheckFormatMp4()
  973. {
  974. CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
  975. CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_FORMAT_MP4);
  976. m_bIsMp4 = !pCheckbox->IsChecked();
  977. }
  978. void CUB530View::OnCheckFormatAvi()
  979. {
  980. CMainFrame* pMain = (CMainFrame*)AfxGetMainWnd();
  981. CMFCRibbonButton* pCheckbox = pMain->GetRibbonButton(ID_CHECK_FORMAT_AVI);
  982. m_bIsMp4 = pCheckbox->IsChecked();
  983. }
  984. void CUB530View::OnUpdateCheckSuportGpu(CCmdUI* pCmdUI)
  985. {
  986. // TODO: 在此添加命令更新用户界面处理程序代码
  987. pCmdUI->SetCheck(m_bSupportGPU);
  988. }
  989. void CUB530View::OnUpdateCheckFormatMp4(CCmdUI* pCmdUI)
  990. {
  991. // TODO: 在此添加命令更新用户界面处理程序代码
  992. pCmdUI->SetCheck(m_bIsMp4);
  993. }
  994. void CUB530View::OnUpdateCheckFormatAvi(CCmdUI* pCmdUI)
  995. {
  996. // TODO: 在此添加命令更新用户界面处理程序代码
  997. pCmdUI->SetCheck(!m_bIsMp4);
  998. }
  999. void CUB530View::OnUpdateStartRecord(CCmdUI* pCmdUI)
  1000. {
  1001. // TODO: 在此添加命令更新用户界面处理程序代码
  1002. pCmdUI->Enable(!m_bIsRecord);
  1003. }
  1004. void CUB530View::OnUpdateStopRecord(CCmdUI* pCmdUI)
  1005. {
  1006. // TODO: 在此添加命令更新用户界面处理程序代码
  1007. pCmdUI->Enable(m_bIsRecord);
  1008. }
  1009. void CUB530View::OnCheckShotLocal()
  1010. {
  1011. CMFCRibbonBar* pRibbon = g_pMainFrame->GetRibbonBar();
  1012. ASSERT_VALID(pRibbon);
  1013. CMFCRibbonButton* pCheck = DYNAMIC_DOWNCAST(CMFCRibbonButton, pRibbon->FindByID(ID_CHECK_SHOT_LOCAL));
  1014. if ( pCheck )
  1015. {
  1016. if ( pCheck->IsChecked() )
  1017. {
  1018. m_shotDir = ShotSystem;
  1019. }
  1020. else
  1021. {
  1022. m_shotDir = ShotLocal;
  1023. }
  1024. }
  1025. }
  1026. void CUB530View::OnUpdateCheckShotLocal(CCmdUI* pCmdUI)
  1027. {
  1028. // TODO: 在此添加命令更新用户界面处理程序代码
  1029. if (m_shotDir == ShotLocal)
  1030. pCmdUI->SetCheck(TRUE);
  1031. else
  1032. pCmdUI->SetCheck(FALSE);
  1033. }
  1034. void CUB530View::OnCheckShotSystem()
  1035. {
  1036. CMFCRibbonBar* pRibbon = g_pMainFrame->GetRibbonBar();
  1037. ASSERT_VALID(pRibbon);
  1038. CMFCRibbonButton* pCheck = DYNAMIC_DOWNCAST(CMFCRibbonButton, pRibbon->FindByID(ID_CHECK_SHOT_SYSTEM));
  1039. if (pCheck)
  1040. {
  1041. if (pCheck->IsChecked())
  1042. {
  1043. m_shotDir = ShotSpec;
  1044. }
  1045. else
  1046. {
  1047. m_shotDir = ShotSystem;
  1048. }
  1049. }
  1050. }
  1051. void CUB530View::OnUpdateCheckShotSystem(CCmdUI* pCmdUI)
  1052. {
  1053. if (m_shotDir == ShotSystem)
  1054. pCmdUI->SetCheck(TRUE);
  1055. else
  1056. pCmdUI->SetCheck(FALSE);
  1057. }
  1058. void CUB530View::OnCheckShotSpec()
  1059. {
  1060. CMFCRibbonBar* pRibbon = g_pMainFrame->GetRibbonBar();
  1061. ASSERT_VALID(pRibbon);
  1062. CMFCRibbonButton* pCheck = DYNAMIC_DOWNCAST(CMFCRibbonButton, pRibbon->FindByID(ID_CHECK_SHOT_SPEC));
  1063. if (pCheck)
  1064. {
  1065. CFileFind finder;
  1066. CString path;
  1067. BOOL fileExist;
  1068. // 获取特定文件夹的LPITEMIDLIST,可以将之理解为HANDLE
  1069. // 所谓的特定文件夹,你可以用CSIDL_XXX来检索之。
  1070. LPITEMIDLIST rootLoation;
  1071. SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &rootLoation);
  1072. if (rootLoation == NULL) {
  1073. // unkown error
  1074. return;
  1075. }
  1076. // 配置对话框
  1077. BROWSEINFO bi;
  1078. ZeroMemory(&bi, sizeof(bi));
  1079. bi.pidlRoot = rootLoation; // 文件夹对话框之根目录,不指定的话则为我的电脑
  1080. bi.lpszTitle = _T("请选择截图保存路径……"); // 可以不指定
  1081. bi.hwndOwner = m_hWnd;
  1082. // 打开对话框, 有点像DoModal
  1083. LPITEMIDLIST targetLocation = SHBrowseForFolder(&bi);
  1084. if (targetLocation != NULL)
  1085. {
  1086. m_shotDir = ShotSpec;
  1087. SHGetPathFromIDList(targetLocation, m_szSpecDir);
  1088. _tcscat_s(m_szSpecDir, _T("\\"));
  1089. }
  1090. }
  1091. }
  1092. void CUB530View::OnUpdateCheckShotSpec(CCmdUI* pCmdUI)
  1093. {
  1094. if (m_shotDir == ShotSpec)
  1095. pCmdUI->SetCheck(TRUE);
  1096. else
  1097. pCmdUI->SetCheck(FALSE);
  1098. }
  1099. int CUB530View::OnCreate(LPCREATESTRUCT lpCreateStruct)
  1100. {
  1101. if (CFormView::OnCreate(lpCreateStruct) == -1)
  1102. return -1;
  1103. // TODO: 在此添加您专用的创建代码
  1104. // 初始化共享内存;
  1105. #if _USE_DLGVIEW_
  1106. CMemoryClient::m_pView = this;
  1107. #endif
  1108. g_ub530.InitMemery();
  1109. g_ub530.StartThread();
  1110. // TODO: 在此添加您专用的创建代码
  1111. // 创建视频流,并关联指定显示窗口;
  1112. HwInitialize();
  1113. // 创建截图线程;
  1114. std::thread t(CaptureImageThread, this);
  1115. t.detach();
  1116. return 0;
  1117. }
  1118. void CUB530View::OnCheckIrShot()
  1119. {
  1120. // TODO: 在此添加命令处理程序代码
  1121. CMFCRibbonBar* pRibbon = g_pMainFrame->GetRibbonBar();
  1122. ASSERT_VALID(pRibbon);
  1123. CMFCRibbonButton* pCheck = DYNAMIC_DOWNCAST(CMFCRibbonButton, pRibbon->FindByID(ID_CHECK_IR_SHOT));
  1124. if ( pCheck )
  1125. {
  1126. g_pMainFrame->m_bShotIR = !pCheck->IsChecked();
  1127. }
  1128. }
  1129. void CUB530View::OnUpdateCheckIrShot(CCmdUI* pCmdUI)
  1130. {
  1131. // TODO: 在此添加命令更新用户界面处理程序代码
  1132. pCmdUI->SetCheck(g_pMainFrame->m_bShotIR);
  1133. }