RvcFaceCapturer.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  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. LogWarn(Severity_Middle, 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. LogWarn(Severity_Middle, 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. }