RvcFaceCapturer.cpp 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. #ifdef RVC_OS_WIN
  2. #include "stdafx.h"
  3. #endif // RVC_OS_WIN
  4. #include "RvcFaceCapturer.h"
  5. #include "MyEvent.h"
  6. #include "Common.h"
  7. #include "../../Other/libvideoframework/videoutil.h"
  8. #include <process.h>
  9. namespace RvcFaceCapture
  10. {
  11. #define MAX(a,b) ((a)<(b)?(b):(a))
  12. #define WNDCLS_NAME "facerect"
  13. // 人脸框窗口句柄
  14. HWND hFaceRectWnd = NULL;
  15. HDC hdcBuffer = NULL; //人脸回显框背景图缓冲
  16. RvcFaceCapturer::RvcFaceCapturer( LPCTSTR videoqueue0name,LPCTSTR videoqueue1name,int videowidth,int videoheight )
  17. {
  18. if (videoqueue0name)
  19. {
  20. m_VideoQueue0Name = videoqueue0name;
  21. }
  22. if (videoqueue1name)
  23. {
  24. m_VideoQueue1Name = videoqueue1name;
  25. }
  26. m_bCaptured = FALSE;
  27. m_hInstance = NULL;
  28. RvcFaceCapInit = NULL;
  29. RvcFaceCapStartCapture = NULL;
  30. RvcFaceCapFeedFrame = NULL;
  31. RvcFaceCapStopCapture = NULL;
  32. RvcFaceCapGetImage = NULL;
  33. RvcFaceCapUnInit = NULL;
  34. RvcFaceCapGetTrackData = NULL;
  35. m_nEchoCamera = 0;
  36. m_hEventWait = NULL;
  37. m_strStatus = "";
  38. m_strLastStatus= "";
  39. m_nLastEchoCamera = -1;
  40. m_bThreadRun = false;
  41. m_hCaptureThread = NULL;
  42. m_hFaceRectThread = NULL;
  43. videoframe0 = NULL;
  44. videoframe1 = NULL;
  45. m_videoqueue0 = NULL;
  46. m_videoqueue1 = NULL;
  47. m_bTimeout = false;
  48. m_nSeconds = 0;
  49. m_bitmap0.bmPlanes = 1;
  50. m_bitmap0.bmType = 0;
  51. m_bitmap0.bmBitsPixel = 24;
  52. m_bitmap0.bmWidth = videowidth;
  53. m_bitmap0.bmHeight = videoheight;
  54. m_bitmap0.bmWidthBytes = 3*m_bitmap0.bmWidth;
  55. m_nImageSize = m_bitmap0.bmWidthBytes*m_bitmap0.bmHeight;
  56. m_bitmap0.bmBits = new unsigned char[m_nImageSize];
  57. m_bitmap1.bmPlanes = 1;
  58. m_bitmap1.bmType = 0;
  59. m_bitmap1.bmBitsPixel = 24;
  60. m_bitmap1.bmWidth = videoheight;
  61. m_bitmap1.bmHeight = videowidth;
  62. m_bitmap1.bmWidthBytes = 3*m_bitmap1.bmWidth;
  63. m_nImageSize = m_bitmap1.bmWidthBytes*m_bitmap1.bmHeight;
  64. m_bitmap1.bmBits = new unsigned char[m_nImageSize];
  65. m_bSaveCaptureResult = FALSE;
  66. }
  67. RvcFaceCapturer::~RvcFaceCapturer()
  68. {
  69. if(m_bitmap0.bmBits)
  70. {
  71. delete[] m_bitmap0.bmBits;
  72. m_bitmap0.bmBits = NULL;
  73. }
  74. if(m_bitmap1.bmBits)
  75. {
  76. delete[] m_bitmap1.bmBits;
  77. m_bitmap1.bmBits = NULL;
  78. }
  79. RvcFaceCapInit = NULL;
  80. RvcFaceCapStartCapture = NULL;
  81. RvcFaceCapFeedFrame = NULL;
  82. RvcFaceCapStopCapture = NULL;
  83. RvcFaceCapGetImage = NULL;
  84. RvcFaceCapUnInit = NULL;
  85. RvcFaceCapGetTrackData = NULL;
  86. m_hCaptureThread = NULL;
  87. }
  88. void RvcFaceCapturer::OnFaceCapImgInfo( const char* msg )
  89. {
  90. if(m_timer.isRunning())
  91. {
  92. return;
  93. }
  94. else
  95. {
  96. m_timer.start();
  97. }
  98. m_strStatus=msg;
  99. if (m_strStatus.GetLength() > 0 && m_strStatus != m_strLastStatus)
  100. {
  101. //发送告警信息
  102. LogWarn(Severity_High,Error_Debug,LOG_EVT_SHOWACTIVECAPTUREMSG,m_strStatus.GetData());
  103. AutoSnapshotRemind evt;
  104. evt.ActionID=CSimpleStringA2W(m_ActionID);
  105. evt.RemindInfo=CSimpleStringA2W(m_strStatus);
  106. LogEvent(Severity_Middle,
  107. LOG_EVT_SHOWACTIVECAPTUREMSG,
  108. (LPCTSTR)m_strStatus); // notify iebrowser
  109. SpSendBroadcast(m_pDetection->GetFunction(),
  110. SP_MSG_OF(AutoSnapshotRemind),
  111. SP_MSG_SIG_OF(AutoSnapshotRemind),
  112. evt);
  113. Dbg("[RvcFaceCapturer]: AutoSnapshotRemind has broadcasted.");
  114. m_strLastStatus=m_strStatus;
  115. }
  116. }
  117. void RvcFaceCapturer::OnEchoCamera( int cameraID )
  118. {
  119. m_nEchoCamera = cameraID;
  120. if (m_nEchoCamera != m_nLastEchoCamera)
  121. {
  122. //发送告警信息
  123. CSimpleString msg = CSimpleString::Format("EchoCameraID:%d", m_nEchoCamera);
  124. LogWarn(Severity_High, Error_Debug, LOG_EVT_ECHOACTIVECAPTURECAM, msg);
  125. char strEchoCamera[2]={0};
  126. sprintf(strEchoCamera,"%d",m_nEchoCamera);
  127. LogEvent(Severity_Middle,
  128. LOG_EVT_ECHOACTIVECAPTURECAM,
  129. strEchoCamera); // notify chh(sipphone)
  130. m_nLastEchoCamera = m_nEchoCamera;
  131. }
  132. }
  133. void RvcFaceCapturer::OnFaceCapDone()
  134. {
  135. m_bCaptured = TRUE;
  136. Dbg("主动捕获成功");
  137. }
  138. //人脸捕获线程
  139. UINT WINAPI FaceCaptureThread(LPVOID pM)
  140. {
  141. Dbg("FaceCaptureThread entered!");
  142. RvcFaceCapturer* pFaceCapturer = (RvcFaceCapturer*)pM;
  143. return pFaceCapturer->StartCapture();
  144. }
  145. // 重画边框的具体代码
  146. void DrawBorder(HWND hWnd)
  147. {
  148. if (hWnd)
  149. {
  150. PAINTSTRUCT pt;
  151. HDC hdc;
  152. hdc = BeginPaint(hWnd,&pt); //开始重绘
  153. HBRUSH brush = CreateSolidBrush(RGB(0,255,0));
  154. HBRUSH oldBrush = (HBRUSH)SelectObject(hdc,brush);
  155. RECT rtWnd;
  156. GetWindowRect(hWnd,&rtWnd);
  157. int width = rtWnd.right-rtWnd.left;
  158. int height = rtWnd.bottom-rtWnd.top;
  159. POINT point;
  160. //填充顶部框架
  161. point.x = width;
  162. point.y = GetSystemMetrics(SM_CYFRAME)+1;
  163. PatBlt(hdc, 0, 0, point.x, point.y, PATCOPY);
  164. //填充左侧框架
  165. point.x = GetSystemMetrics(SM_CXFRAME);
  166. point.y = height;
  167. PatBlt(hdc, 0, 0, point.x, point.y, PATCOPY);
  168. //填充底部框架
  169. point.x = width;
  170. point.y = GetSystemMetrics(SM_CYFRAME) + 1;
  171. PatBlt(hdc, 0, height-point.y, point.x, point.y, PATCOPY);
  172. //填充右侧框架
  173. point.x = GetSystemMetrics(SM_CXFRAME);
  174. point.y = height;
  175. PatBlt(hdc, width-point.x, 0, point.x, point.y, PATCOPY);
  176. SelectObject(hdc,oldBrush);//恢复以前的画笔
  177. DeleteObject(brush);
  178. DeleteObject(oldBrush);
  179. EndPaint(hWnd, &pt); //停止重绘 不加这一句会造成死循环
  180. }
  181. }
  182. // 重画边框的具体代码
  183. void DrawBorder(HWND hWnd,int iWidth)
  184. {
  185. if (hWnd)
  186. {
  187. PAINTSTRUCT pt;
  188. HDC hdc;
  189. hdc = BeginPaint(hWnd,&pt); //开始重绘
  190. HBRUSH brush = CreateSolidBrush(RGB(0,255,0));
  191. HBRUSH oldBrush = (HBRUSH)SelectObject(hdc,brush);
  192. RECT rtWnd;
  193. GetWindowRect(hWnd,&rtWnd);
  194. int width = rtWnd.right-rtWnd.left;
  195. int height = rtWnd.bottom-rtWnd.top;
  196. //将位图复制到背景
  197. BitBlt(hdc, 0, 0, width, height, hdcBuffer, 0, 0, SRCCOPY);
  198. POINT point;
  199. //填充顶部框架
  200. point.x = width;
  201. point.y = iWidth;
  202. PatBlt(hdc, 0, 0, point.x, point.y, PATCOPY);
  203. //填充左侧框架
  204. point.x = iWidth;
  205. point.y = height;
  206. PatBlt(hdc, 0, 0, point.x, point.y, PATCOPY);
  207. //填充底部框架
  208. point.x = width;
  209. point.y = iWidth;
  210. PatBlt(hdc, 0, height-point.y, point.x, point.y, PATCOPY);
  211. //填充右侧框架
  212. point.x = iWidth;
  213. point.y = height;
  214. PatBlt(hdc, width-point.x, 0, point.x, point.y, PATCOPY);
  215. SelectObject(hdc,oldBrush);//恢复以前的画笔
  216. DeleteObject(brush);
  217. DeleteObject(oldBrush);
  218. EndPaint(hWnd, &pt); //停止重绘 不加这一句会造成死循环
  219. }
  220. }
  221. LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  222. {
  223. switch (msg) {
  224. case WM_DESTROY:
  225. PostQuitMessage(0);
  226. return 0;
  227. case WM_ACTIVATE:
  228. case WM_TOUCH:
  229. case WM_GESTURE:
  230. ReleaseCapture();
  231. return 0;
  232. case WM_WINDOWPOSCHANGED:
  233. {
  234. LPWINDOWPOS pPos = (LPWINDOWPOS)lParam;
  235. if (pPos->hwndInsertAfter != HWND_TOPMOST && pPos->hwndInsertAfter != HWND_TOP) {
  236. BringWindowToTop(hWnd);
  237. } else {
  238. return DefWindowProc(hWnd, msg, wParam, lParam);
  239. }
  240. }
  241. return 0;
  242. //return DefWindowProc(hWnd, msg, wParam, lParam);
  243. case WM_MBUTTONDOWN:
  244. case WM_MBUTTONUP:
  245. case WM_MBUTTONDBLCLK:
  246. case WM_LBUTTONDBLCLK:
  247. case WM_LBUTTONDOWN:
  248. case WM_LBUTTONUP:
  249. OutputDebugStringA("mouse clicked!");
  250. return 0;
  251. case WM_CLOSE:
  252. DestroyWindow(hWnd);
  253. return 0;
  254. case WM_PAINT:
  255. DrawBorder(hWnd, 2);
  256. return 0;
  257. default:
  258. return DefWindowProc(hWnd, msg, wParam, lParam);
  259. }
  260. }
  261. UINT WINAPI FaceRectThread(LPVOID pM)
  262. {
  263. WNDCLASSA wc = {0};
  264. ATOM a = 0;
  265. HWND hWnd = NULL;
  266. MSG msg;
  267. HINSTANCE hInst = ModuleBase::GetModuleBase()->GetInstance();
  268. CoInitialize(0);
  269. wc.cbClsExtra = 0;
  270. wc.cbWndExtra = 0;
  271. wc.hInstance = hInst;
  272. //wc.hbrBackground = CreateSolidBrush(RGB(255,0,0));
  273. wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);//空画刷
  274. wc.hCursor = NULL;
  275. wc.hIcon = NULL;
  276. wc.lpfnWndProc = &WndProc;
  277. wc.lpszClassName = WNDCLS_NAME;
  278. wc.style = CS_HREDRAW | CS_OWNDC | CS_VREDRAW;
  279. a = RegisterClassA(&wc);
  280. if (a == 0)
  281. {
  282. Dbg("RegisterClassA is 0, error(%d)!", GetLastError());
  283. return 0;
  284. }
  285. hWnd = CreateWindowExA(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
  286. WNDCLS_NAME, NULL, WS_POPUP|WS_VISIBLE,
  287. 0, 0, 0, 0,
  288. NULL, NULL, hInst, NULL);
  289. hFaceRectWnd = hWnd;
  290. if (hWnd) {
  291. //设置背景透明
  292. SetWindowLongPtrA(hWnd,GWL_EXSTYLE,GetWindowLongPtrA(hWnd,GWL_EXSTYLE)^WS_EX_LAYERED);
  293. SetLayeredWindowAttributes(hWnd,RGB(0,0,0),0,LWA_COLORKEY); // 透明
  294. SetWindowPos(hWnd, HWND_TOP, 0, 0, 100, 100, SWP_HIDEWINDOW);
  295. //缓冲背景图
  296. HDC hdc = ::GetDC(hWnd);
  297. hdcBuffer = CreateCompatibleDC(hdc);
  298. RECT rtWnd;
  299. GetWindowRect(hWnd,&rtWnd);
  300. int width = rtWnd.right-rtWnd.left;
  301. int height = rtWnd.bottom-rtWnd.top;
  302. HBITMAP hBitMap = CreateCompatibleBitmap(hdc, width*2.5, height*2.5);
  303. ReleaseDC(hWnd, hdc);
  304. if(hBitMap != NULL)
  305. {
  306. SelectObject(hdcBuffer, hBitMap);
  307. }
  308. else
  309. {
  310. LOG_TRACE("hBitMap is NULL");
  311. }
  312. DrawBorder(hWnd,2);
  313. ShowCursor(FALSE);
  314. while (GetMessageA(&msg, NULL, NULL, NULL))
  315. {
  316. TranslateMessage(&msg);
  317. DispatchMessageA(&msg);
  318. }
  319. }
  320. else {
  321. Dbg("hWnd IS NULL!");
  322. }
  323. if (a) {
  324. UnregisterClassA(WNDCLS_NAME, hInst);
  325. }
  326. CoUninitialize();
  327. return 0;
  328. }
  329. BOOL RvcFaceCapturer::StartFaceCapture()
  330. {
  331. //发送告警信息
  332. LogWarn(Severity_High,Error_Debug,LOG_EVT_STARTACTIVECAPTURE,"FaceCapture Start");
  333. Dbg("[dbg] StartFaceCapture");
  334. if (m_hCaptureThread != NULL)
  335. {
  336. Dbg("[RvcFaceCapturer]: Waiting for the last capture task terminate...");
  337. StopFaceCapture();
  338. }
  339. ResetEvent(m_hEventWait);
  340. m_bCaptured = FALSE;
  341. m_bThreadRun = true;
  342. m_nSeconds = 0;
  343. m_strLastStatus = "";
  344. m_nLastEchoCamera = -1;
  345. m_nEchoCamera = 0;
  346. m_strStatus = "";
  347. m_hCaptureThread = (HANDLE)_beginthreadex(NULL,0,FaceCaptureThread,this,0,NULL);
  348. m_hFaceRectThread = (HANDLE)_beginthreadex(NULL, 0, &FaceRectThread, NULL, 0, NULL);
  349. ActiveDetectionStarted evt;
  350. CLivenessDetectionEntity *pDetection = dynamic_cast<CLivenessDetectionEntity *>(m_pDetection);
  351. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  352. if (ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType)
  353. {
  354. //evt.Param="0@0@0@0@711@275@500@500"; // PAD或低柜双屏回显位置
  355. evt.Param="0@0@0@0@10@10@500@500"; // just for test
  356. m_EchoWinRect.left=10;
  357. m_EchoWinRect.top=10;
  358. m_EchoWinRect.right=m_EchoWinRect.left+500;
  359. m_EchoWinRect.bottom=m_EchoWinRect.top+500;
  360. }
  361. else
  362. {
  363. evt.Param="0@0@0@0@1838@290@600@600";
  364. m_EchoWinRect.left=1838;
  365. m_EchoWinRect.top=290;
  366. m_EchoWinRect.right=m_EchoWinRect.left+600;
  367. m_EchoWinRect.bottom=m_EchoWinRect.top+600;
  368. }
  369. SpSendBroadcast(pDetection->GetFunction(),SP_MSG_OF(ActiveDetectionStarted),SP_MSG_SIG_OF(ActiveDetectionStarted),evt);
  370. Dbg("[RvcFaceCapturer]: ActiveDetectionStarted has broadcasted.");
  371. return TRUE;
  372. }
  373. BOOL RvcFaceCapturer::StopFaceCapture()
  374. {
  375. //发送告警信息
  376. LogWarn(Severity_High,Error_Debug,LOG_EVT_STOPACTIVECAPTURE,"FaceCapture Stop");
  377. //关闭人脸框回显线程
  378. ::PostMessage(hFaceRectWnd,WM_CLOSE,NULL,NULL);//关掉人脸窗口
  379. WaitForSingleObject(m_hFaceRectThread, INFINITE);//等待当前线程执行完毕
  380. ReleaseDC(hFaceRectWnd, hdcBuffer);
  381. CloseHandle(m_hFaceRectThread);//关闭当前线程
  382. m_hFaceRectThread = NULL;
  383. hFaceRectWnd = NULL;
  384. hdcBuffer = NULL;
  385. SetEvent(m_hEventWait);
  386. m_bThreadRun = false;
  387. WaitForSingleObject(m_hCaptureThread, INFINITE);
  388. CloseHandle(m_hCaptureThread);
  389. m_hCaptureThread = NULL;
  390. ::Sleep(50); // 50ms后发出抓拍结束广播
  391. ActiveDetectionStopped evt;
  392. CLivenessDetectionEntity *pDetection = dynamic_cast<CLivenessDetectionEntity *>(m_pDetection);
  393. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  394. if (!(ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType))
  395. {
  396. evt.Param="looklowerscreen.jpg";
  397. }
  398. SpSendBroadcast(pDetection->GetFunction(),SP_MSG_OF(ActiveDetectionStopped),SP_MSG_SIG_OF(ActiveDetectionStopped),evt);
  399. Dbg("[RvcFaceCapturer]: ActiveDetectionStopped has broadcasted.");
  400. return TRUE;
  401. }
  402. void RvcFaceCapturer::NotifyCameraFault()
  403. {
  404. if (m_hCaptureThread != NULL)
  405. {
  406. StopFaceCapture(); // 停止捕获 抛出异常
  407. DetectionStopUnExpected evt;
  408. evt.ActionID=CSimpleStringA2W(m_ActionID);
  409. evt.IsActive=true;
  410. evt.ErrorCode=CSimpleStringA2W("Error_CameraFault");
  411. evt.ErrorMsg=CSimpleStringA2W("摄像头故障,捕获已终止!");
  412. SpSendBroadcast(m_pDetection->GetFunction(),SP_MSG_OF(DetectionStopUnExpected),SP_MSG_SIG_OF(DetectionStopUnExpected),evt);
  413. Dbg("[RvcFaceCapturer]: DetectionStopUnExpected has broadcasted.");
  414. }
  415. }
  416. UINT RvcFaceCapturer::StartCapture()
  417. {
  418. Dbg("RvcFaceCapturer::StartCapture");
  419. RvcFaceCapStartCapture();
  420. int nFrameID=0;
  421. DWORD dwStart=GetTickCount();
  422. while (m_bThreadRun)
  423. {
  424. try
  425. {
  426. BOOL bGetVideo0 = FALSE;
  427. BOOL bGetVideo1 = FALSE;
  428. if (m_videoqueue0->GetVideoLens() > 0)
  429. {
  430. bGetVideo0 = GetVideoFrameByCameraID(0,videoframe0,0);
  431. if (bGetVideo0)
  432. {
  433. memcpy(m_bitmap0.bmBits,videoframe0->data,m_nImageSize);
  434. }
  435. else
  436. {
  437. Dbg("bGetvideo0=%d",bGetVideo0);
  438. }
  439. }
  440. if (m_videoqueue1)
  441. {
  442. if (m_videoqueue1->GetVideoLens() > 0)
  443. {
  444. bGetVideo1 = GetVideoFrameByCameraID(1,videoframe1,0);
  445. if (bGetVideo1)
  446. {
  447. memcpy(m_bitmap1.bmBits,videoframe1->data,m_nImageSize);
  448. }
  449. else
  450. {
  451. Dbg("bGetVideo1=%d",bGetVideo1);
  452. }
  453. }
  454. }
  455. if (bGetVideo0&&!bGetVideo1)
  456. {
  457. OnEchoCamera(0);
  458. }
  459. if (!bGetVideo0&&bGetVideo1)
  460. {
  461. OnEchoCamera(1);
  462. }
  463. if(!bGetVideo0&&!bGetVideo1)
  464. {
  465. //发送告警信息
  466. LogError(Severity_High,Error_Debug,LOG_EVT_ACTIVECAPTURENOVIDEO,"No VideoFrame in videoqueue");
  467. Dbg("No VideoFrame in videoqueue!!!!");
  468. }
  469. RVC_ImageData imageData;
  470. imageData.pImage = &m_bitmap0;
  471. imageData.nCameraID = 0;
  472. imageData.nFrameID = nFrameID;
  473. imageData.dTimeStamp = GetTickCount()/1000.0;
  474. // 摄像头采集成功,才送去捕获
  475. if (bGetVideo0)
  476. {
  477. //Dbg("[dbg] begin to call RvcFaceCapFeedFrame");
  478. RvcFaceCapFeedFrame(&imageData);
  479. //Dbg("[dbg] end to call RvcFaceCapFeedFrame");
  480. }
  481. if (m_videoqueue1)
  482. {
  483. imageData.pImage = &m_bitmap1;
  484. imageData.nCameraID = 1;
  485. if (bGetVideo1)
  486. {
  487. //Dbg("[dbg] begin to call RvcFaceCapFeedFrame");
  488. RvcFaceCapFeedFrame(&imageData);
  489. //Dbg("[dbg] end to call RvcFaceCapFeedFrame");
  490. }
  491. }
  492. RVC_TrackData trackdata;
  493. if (nFrameID >= 8 && 0 == RvcFaceCapGetTrackData(m_nEchoCamera,&trackdata))
  494. {
  495. CLivenessDetectionEntity *pDetection = dynamic_cast<CLivenessDetectionEntity *>(m_pDetection);
  496. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  497. if (ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType)
  498. {
  499. // 镜像
  500. trackdata.rectFace.x = m_bitmap0.bmWidth - trackdata.rectFace.x - trackdata.rectFace.width;
  501. // 640x360->480x360->500x500
  502. trackdata.rectFace.x -= 80;
  503. if (trackdata.rectFace.x < 0)
  504. {
  505. trackdata.rectFace.width += trackdata.rectFace.x;
  506. trackdata.rectFace.x = 0;
  507. }
  508. if (trackdata.rectFace.x + trackdata.rectFace.width > m_bitmap0.bmWidth - 160)
  509. {
  510. trackdata.rectFace.width = m_bitmap0.bmWidth - 160 - trackdata.rectFace.x;
  511. }
  512. double x_ratio=1.0*(m_EchoWinRect.right-m_EchoWinRect.left)/480;
  513. double y_ratio=1.0*(m_EchoWinRect.bottom-m_EchoWinRect.top)/360;
  514. trackdata.rectFace.x*=x_ratio;
  515. trackdata.rectFace.y*=y_ratio;
  516. trackdata.rectFace.width*=x_ratio;
  517. trackdata.rectFace.height*=y_ratio;
  518. RECT rect;
  519. rect.left = m_EchoWinRect.left;
  520. rect.top = m_EchoWinRect.top;
  521. rect.left += trackdata.rectFace.x;
  522. rect.top += trackdata.rectFace.y;
  523. rect.right = rect.left+trackdata.rectFace.width;
  524. rect.bottom = rect.top+trackdata.rectFace.height;
  525. //DrawRectangle(GetDesktopWindow(), rect, 2, m_EchoWinRect);
  526. ::SetWindowPos(hFaceRectWnd, HWND_TOPMOST, rect.left,rect.top,
  527. rect.right-rect.left,rect.bottom-rect.top,SWP_SHOWWINDOW);
  528. }
  529. else
  530. {
  531. double ratio=1.0*(m_EchoWinRect.right-m_EchoWinRect.left)/m_bitmap0.bmWidth;
  532. trackdata.rectFace.x*=ratio;
  533. trackdata.rectFace.y*=ratio;
  534. trackdata.rectFace.width*=ratio;
  535. trackdata.rectFace.height*=ratio;
  536. int offset = (m_bitmap0.bmWidth-m_bitmap0.bmHeight)/2*ratio;
  537. RECT rect;
  538. if (0 == m_nEchoCamera)
  539. {
  540. rect.left = m_EchoWinRect.left;
  541. rect.top = m_EchoWinRect.top+offset;
  542. }
  543. else
  544. {
  545. rect.left = m_EchoWinRect.left+offset;
  546. rect.top = m_EchoWinRect.top;
  547. }
  548. rect.left += trackdata.rectFace.x;
  549. rect.top += trackdata.rectFace.y;
  550. rect.right = rect.left+trackdata.rectFace.width;
  551. rect.bottom = rect.top+trackdata.rectFace.height;
  552. //DrawRectangle(GetDesktopWindow(), rect, 2, m_EchoWinRect);
  553. ::SetWindowPos(hFaceRectWnd, HWND_TOPMOST, rect.left,rect.top,
  554. rect.right-rect.left,rect.bottom-rect.top,SWP_SHOWWINDOW);
  555. }
  556. }
  557. else
  558. {
  559. SetWindowPos(hFaceRectWnd, HWND_TOP, 0, 0, 100, 100, SWP_HIDEWINDOW);
  560. }
  561. nFrameID++;
  562. if (m_bCaptured)
  563. {
  564. //抓拍成功
  565. SYSTEMTIME startTime;
  566. GetLocalTime(&startTime);
  567. LogWarn(Severity_High, Error_Debug, LOG_EVT_ACTIVECAPTURECOST,
  568. generateAlarmJson("LivenessDetection", formatTime(startTime).c_str(), GetTickCount()-dwStart).GetData());
  569. // send to rvcweb
  570. ActiveDetectionDone evt;
  571. evt.VerifyResult=CSimpleStringA2W("X");
  572. evt.ActionID=CSimpleStringA2W(m_ActionID);
  573. BITMAP bitmap;
  574. RVC_FaceRect face;
  575. RvcFaceCapGetImage(&bitmap,&face);
  576. Dbg("[OnFaceCapDone]:%d,%d,%d,%d",face.x,face.y,face.width,face.height);
  577. if (bitmap.bmBits!=NULL)
  578. {
  579. RECT roi={face.x,face.y,face.x+face.width,face.y+face.height};
  580. if (m_bSaveCaptureResult&&m_CaptureResultPath.GetLength()>0)
  581. {
  582. // save capture result
  583. char szPhoto[MAX_PATH]={0};
  584. sprintf(szPhoto,"%s%s_Capture.jpg",(LPCTSTR)m_CaptureResultPath,(LPCTSTR)m_ActionID);
  585. SaveLivenessPhoto(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,szPhoto);
  586. sprintf(szPhoto,"%s%s_Face.jpg",(LPCTSTR)m_CaptureResultPath,(LPCTSTR)m_ActionID);
  587. SaveLivenessPhoto(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,szPhoto,&roi);
  588. }
  589. int nJpgSize[2]={0};
  590. char *pJpg=new char[2*m_nImageSize];
  591. RGB2JPG(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,&nJpgSize[0],pJpg,m_pDetection,&roi);
  592. RGB2JPG(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,&nJpgSize[1],pJpg+nJpgSize[0],m_pDetection);
  593. if (nJpgSize[0]>0&&nJpgSize[1]>0)
  594. {
  595. int size = nJpgSize[0]+nJpgSize[1];
  596. evt.SnapShotPhotoLength = size;
  597. evt.SnapShotPhotoData.Alloc(size);
  598. memmove(evt.SnapShotPhotoData.m_pData, pJpg, size);
  599. evt.SnapShotPhotoData.Resize(size);
  600. evt.VerifyResult = CSimpleStringA2W(CSimpleStringA::Format("X|%d,%d,%d,%d,%d,%d,%d,%d,%d",
  601. nJpgSize[0],nJpgSize[1],MAX(m_nSeconds,1),bitmap.bmWidth,bitmap.bmHeight,roi.left,roi.top,roi.right-roi.left,roi.bottom-roi.top));
  602. }
  603. else
  604. {
  605. evt.SnapShotPhotoLength=0;
  606. }
  607. delete []pJpg; pJpg=NULL;
  608. }
  609. else
  610. {
  611. evt.SnapShotPhotoLength=0;
  612. }
  613. int nTimeUsed=m_nSeconds;
  614. int nLeastActiveShowTime=m_nLeastActiveShowTime;
  615. if (nTimeUsed<nLeastActiveShowTime)
  616. {
  617. ::PostMessage(hFaceRectWnd,WM_CLOSE,NULL,NULL);
  618. ::Sleep((nLeastActiveShowTime-nTimeUsed)*1000); // 保证至少进行nLeastActiveShowTime才结束并通知
  619. }
  620. SpSendBroadcast(m_pDetection->GetFunction(), SP_MSG_OF(ActiveDetectionDone), SP_MSG_SIG_OF(ActiveDetectionDone), evt);
  621. Dbg("[RvcFaceCapturer]: ActiveDetectionDone has broadcasted.");
  622. m_bThreadRun = false;
  623. StopFaceCaptureTask *task = new StopFaceCaptureTask(this);
  624. m_pDetection->GetFunction()->PostThreadPoolTask(task);
  625. continue;
  626. }
  627. if (GetTickCount()-dwStart>1000)
  628. {
  629. dwStart+=1000;
  630. m_nSeconds++;
  631. if (IsTimeOut())
  632. {
  633. m_bTimeout=true;
  634. m_bThreadRun=false;
  635. StopFaceCaptureTask *task = new StopFaceCaptureTask(this);
  636. m_pDetection->GetFunction()->PostThreadPoolTask(task);
  637. continue;
  638. }
  639. }
  640. }
  641. catch (...)
  642. {
  643. Dbg("[Captrue] exception occurred or stop capture.");
  644. FSleep(50);
  645. continue;
  646. }
  647. }
  648. m_hCaptureThread=0;
  649. RvcFaceCapStopCapture();
  650. if (m_bTimeout)
  651. {
  652. m_bTimeout = false;
  653. DetectionStopUnExpected evt;
  654. evt.IsActive=true;
  655. evt.ActionID=CSimpleStringA2W(m_ActionID);
  656. evt.ErrorCode=CSimpleStringA2W("Error_TimeOut");
  657. evt.ErrorMsg = CSimpleStringA2W("主动捕获超时,已终止!");
  658. SpSendBroadcast(m_pDetection->GetFunction(), SP_MSG_OF(DetectionStopUnExpected), SP_MSG_SIG_OF(DetectionStopUnExpected), evt);
  659. Dbg("[RvcFaceCapturer]: DetectionStopUnExpected has broadcasted.");
  660. }
  661. return 0;
  662. }
  663. ErrorCodeEnum RvcFaceCapturer::Init(CEntityBase* pDetection)
  664. {
  665. m_pDetection = pDetection;
  666. CSmartPointer<IEntityFunction> spEntityFunction = m_pDetection->GetFunction();
  667. CSmartPointer<IConfigInfo> spConfig;
  668. ErrorCodeEnum eErrDev;
  669. eErrDev = spEntityFunction->OpenConfig(Config_CenterSetting, spConfig);
  670. if (eErrDev == Error_Succeed)
  671. {
  672. SpIniMappingTable table;
  673. table.AddEntryInt("LivenessDetection","SaveLivenessResult",m_bSaveCaptureResult,FALSE);
  674. table.AddEntryInt("LivenessDetection","ActiveTimeLimit",m_nActiveTimeLimit,TIME_LIMIT_ACTIVE);
  675. table.AddEntryInt("LivenessDetection","LeastActiveShowTime",m_nLeastActiveShowTime,TIME_LEAST_ACTIVE_SHOW);
  676. table.AddEntryInt("LivenessDetection","SendInfoInterval",m_nSendInfoIntervalTime,TIME_INTERVAL_SENDINFO);
  677. eErrDev = table.Load(spConfig);
  678. if (eErrDev != Error_Succeed)
  679. {
  680. Dbg("fail to load centersettings!");
  681. m_bSaveCaptureResult = FALSE;
  682. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  683. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  684. }
  685. if (m_nLeastActiveShowTime<=0||m_nLeastActiveShowTime>TIME_LIMIT_ACTIVE)
  686. {
  687. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  688. }
  689. if (m_nActiveTimeLimit<m_nLeastActiveShowTime||m_nActiveTimeLimit>TIME_LIMIT_ACTIVE)
  690. {
  691. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  692. }
  693. }
  694. else
  695. {
  696. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  697. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  698. m_nSendInfoIntervalTime = TIME_INTERVAL_SENDINFO;
  699. }
  700. if (m_bSaveCaptureResult)
  701. {
  702. eErrDev = m_pDetection->GetFunction()->GetPath("UploadPhoto", m_CaptureResultPath);
  703. if (eErrDev != Error_Succeed)
  704. {
  705. Dbg("fail to get UploadPhotoPath!");
  706. m_CaptureResultPath = "";
  707. }
  708. else
  709. {
  710. int len = m_CaptureResultPath.GetLength();
  711. if (m_CaptureResultPath.GetLength() > 0 && m_CaptureResultPath[len-1] != '\\') {
  712. m_CaptureResultPath += "\\";
  713. }
  714. }
  715. }
  716. videoframe0 = new videoq_frame;
  717. memset(videoframe0,0,sizeof(videoq_frame));
  718. videoframe1 = new videoq_frame;
  719. memset(videoframe1,0,sizeof(videoq_frame));
  720. m_hEventWait= ::CreateEventA(NULL, TRUE, 0, 0);
  721. if (!m_hEventWait)
  722. {
  723. Dbg("create hEventWait failed!");
  724. return Error_Null;
  725. }
  726. if (m_VideoQueue0Name.length()>0)
  727. {
  728. m_videoqueue0 = new Clibvideoqueue(m_VideoQueue0Name.c_str());
  729. }
  730. else
  731. {
  732. m_videoqueue0 = NULL;
  733. }
  734. if (m_VideoQueue1Name.length()>0)
  735. {
  736. m_videoqueue1 = new Clibvideoqueue(m_VideoQueue1Name.c_str());
  737. }
  738. else
  739. {
  740. m_videoqueue1 = NULL;
  741. }
  742. //初始化视频buffer
  743. if (videoframe0->data == NULL)
  744. {
  745. videoframe0->data = new unsigned char[m_nImageSize];
  746. videoframe0->framesize = m_nImageSize;
  747. videoframe0->height = m_bitmap0.bmHeight;
  748. videoframe0->width = m_bitmap0.bmWidth;
  749. videoframe0->format = VIDEO_FORMAT_RGB24;
  750. }
  751. if (videoframe1->data == NULL)
  752. {
  753. videoframe1->data = new unsigned char[m_nImageSize];
  754. videoframe1->framesize = m_nImageSize;
  755. videoframe1->height = m_bitmap1.bmHeight;
  756. videoframe1->width = m_bitmap1.bmWidth;
  757. videoframe1->format = VIDEO_FORMAT_RGB24;
  758. }
  759. CSimpleStringA csBinPath;
  760. m_pDetection->GetFunction()->GetPath("Bin",csBinPath);
  761. CSimpleStringA dllName=csBinPath.Append("\\RvcFaceCapture.dll");
  762. Dbg("dllName:%s",(LPCTSTR)dllName);
  763. m_hInstance = ::LoadLibrary((LPCTSTR)dllName);
  764. if (m_hInstance)
  765. {
  766. RvcFaceCapInit = (tPfnInit)GetProcAddress(m_hInstance,"Init");
  767. RvcFaceCapStartCapture = (tPfnStartCapture)GetProcAddress(m_hInstance,"StartCapture");
  768. RvcFaceCapFeedFrame = (tPfnFeedFrame)GetProcAddress(m_hInstance,"FeedFrame");
  769. RvcFaceCapStopCapture = (tPfnStopCapture)GetProcAddress(m_hInstance,"StopCapture");
  770. RvcFaceCapGetImage = (tPfnGetImage)GetProcAddress(m_hInstance,"GetImage");
  771. RvcFaceCapUnInit = (tPfnUnInit)GetProcAddress(m_hInstance,"UnInit");
  772. RvcFaceCapGetTrackData = (tPfnGetTrackData)GetProcAddress(m_hInstance,"GetTrackData");
  773. if (!(RvcFaceCapInit&&RvcFaceCapStartCapture&&RvcFaceCapFeedFrame&&
  774. RvcFaceCapStopCapture&&RvcFaceCapGetImage&&RvcFaceCapUnInit&&RvcFaceCapGetTrackData))
  775. {
  776. Dbg("failed to get function from hinstance(%d)", GetLastError());
  777. return Error_Null;
  778. }
  779. else
  780. {
  781. Dbg("[dbg] begin to call RvcFaceCapInit");
  782. CSystemStaticInfo stStaticinfo;
  783. spEntityFunction->GetSystemStaticInfo(stStaticinfo);
  784. int rtn=RvcFaceCapInit(this, (LPCTSTR)stStaticinfo.strMachineType);
  785. Dbg("[dbg] end to call RvcFaceCapInit");
  786. if (rtn!=0)
  787. {
  788. return Error_Unexpect;
  789. }
  790. }
  791. }
  792. else
  793. {
  794. //发送告警信息
  795. CSimpleString msg = CSimpleString::Format("failed to load RvcFaceCapture dll(%d)", GetLastError());
  796. LogError(Severity_High,Error_Debug, LOG_EVT_ACTIVECAPTURELOADDEPFAIL, msg.GetData());
  797. Dbg(msg.GetData());
  798. return Error_Null;
  799. }
  800. //设置定时器超时时间
  801. m_timer.setWaitTime(m_nSendInfoIntervalTime);
  802. return Error_Succeed;
  803. }
  804. ErrorCodeEnum RvcFaceCapturer::UnInit()
  805. {
  806. if (videoframe0->data != NULL)
  807. {
  808. delete videoframe0->data;
  809. videoframe0->data = NULL;
  810. }
  811. if (videoframe0 != NULL)
  812. {
  813. delete videoframe0;
  814. videoframe0 = NULL;
  815. }
  816. if (videoframe1->data != NULL)
  817. {
  818. delete videoframe1->data;
  819. videoframe1->data = NULL;
  820. }
  821. if (videoframe1 != NULL)
  822. {
  823. delete videoframe1;
  824. videoframe1 = NULL;
  825. }
  826. if (m_videoqueue0 != NULL)
  827. {
  828. delete m_videoqueue0;
  829. m_videoqueue0 = NULL;
  830. }
  831. if (m_videoqueue1 != NULL)
  832. {
  833. delete m_videoqueue1;
  834. m_videoqueue1 = NULL;
  835. }
  836. if (m_hEventWait)
  837. {
  838. CloseHandle(m_hEventWait);
  839. m_hEventWait = NULL;
  840. }
  841. if (RvcFaceCapUnInit)
  842. {
  843. Dbg("[dbg] begin to call RvcFaceCapUnInit");
  844. RvcFaceCapUnInit();
  845. Dbg("[dbg] end to call RvcFaceCapUnInit");
  846. }
  847. if (m_hInstance)
  848. {
  849. ::FreeLibrary(m_hInstance);
  850. m_hInstance = NULL;
  851. }
  852. return Error_Succeed;
  853. }
  854. BOOL RvcFaceCapturer::GetVideoFrameByCameraID( int CameraID, videoq_frame* Video, int flags )
  855. {
  856. assert(CameraID == 0 || CameraID == 1);
  857. if (CameraID == 0) // For StandVTM or Pad
  858. {
  859. BOOL bRslt = FALSE;
  860. int width = 0;
  861. int height = 0;
  862. m_videoqueue0->GetFrameSize(width,height);
  863. memset(Video->data,0,Video->framesize);
  864. videoq_frame*tmp_frm = new videoq_frame;
  865. tmp_frm->data = Video->data;
  866. bRslt = m_videoqueue0->GetVideo(tmp_frm, flags);
  867. if (!bRslt)
  868. {
  869. delete tmp_frm;
  870. Dbg("get video from videoqueue0 fail!");
  871. return FALSE;
  872. }
  873. delete tmp_frm;
  874. return TRUE;
  875. }
  876. else // For StandVTM
  877. {
  878. BOOL bRslt = FALSE;
  879. int width = 0;
  880. int height = 0;
  881. m_videoqueue1->GetFrameSize(width,height);
  882. memset(Video->data,0,Video->framesize);
  883. videoq_frame*tmp_frm = new videoq_frame;
  884. tmp_frm->data = Video->data;
  885. bRslt = m_videoqueue1->GetVideo(tmp_frm, flags);
  886. if (!bRslt)
  887. {
  888. delete tmp_frm;
  889. Dbg("get video from videoqueue1 fail!");
  890. return FALSE;
  891. }
  892. delete tmp_frm;
  893. return TRUE;
  894. }
  895. }
  896. void RvcFaceCapturer::FSleep( int ms )
  897. {
  898. DWORD dwRet = WaitForSingleObject(m_hEventWait, ms);
  899. if (dwRet == WAIT_OBJECT_0) // 如果等到信号
  900. {
  901. throw std::exception(); // 抛个异常表明是外界停止捕获
  902. }
  903. }
  904. bool RvcFaceCapturer::IsTimeOut()
  905. {
  906. return m_nSeconds >= m_nActiveTimeLimit;
  907. }
  908. void StopFaceCaptureTask::Process()
  909. {
  910. m_pCapture->StopFaceCapture();
  911. }
  912. std::string RvcFaceCapturer::formatTime(SYSTEMTIME time)
  913. {
  914. char tBuf[1024] = "";
  915. sprintf(tBuf, "%04u-%02u-%02u %02u:%02u:%02u:%03u", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
  916. return tBuf;
  917. }
  918. CSimpleString RvcFaceCapturer::generateAlarmJson(CSimpleString entityName, CSimpleString startTime, int cost)
  919. {
  920. return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost);
  921. }
  922. }