LivenessDetectionFSM.cpp 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718
  1. #include "stdafx.h"
  2. #include "SpHelper.h"
  3. #include "LivenessDetectionFSM.h"
  4. #include "Event.h"
  5. #include "Common.h"
  6. #include "..\..\Other\libvideoframework\videoutil.h"
  7. #include "YituLiveSDK.h"
  8. int nCaptureType=CAPTURE_TYPE_PASSIVE;
  9. // 当前活体检测实体的引用
  10. CLivenessDetectionEntity *pDetection = NULL;
  11. // 当前活体检测状态机的引用
  12. CLivenessDetectionFSM *pFsm = NULL;
  13. // 心跳计时器ID号
  14. UINT_PTR TimerID = 88;
  15. // 心跳计时器间隔
  16. UINT Interval = 5000;
  17. // 活体检测窗口句柄
  18. HWND hDetectionWnd = NULL;
  19. // 活体检测窗口线程
  20. HANDLE hWndThread = NULL;
  21. // 活体检测窗口线程id
  22. UINT hWndThreadID = 0;
  23. // 回显摄像头编号
  24. int nEchoCamera = -1;
  25. // 当前回显提示消息
  26. CSimpleStringA strStatus="";
  27. // 历史回显提示消息
  28. CSimpleStringA strLastStatus="";
  29. CLivenessDetectionFSM::CLivenessDetectionFSM( int fps,LPCTSTR videoqueue0name,LPCTSTR videoqueue1name,int videowidth,int videoheight ): m_bStopCapture(FALSE)
  30. {
  31. m_nFps = fps;
  32. if (videoqueue0name)
  33. {
  34. m_VideoQueue0Name = videoqueue0name;
  35. }
  36. if (videoqueue1name)
  37. {
  38. m_VideoQueue1Name = videoqueue1name;
  39. }
  40. m_nTime = 0;
  41. m_hDetectThread = 0;
  42. m_hCameraThread0 = 0;
  43. m_hCameraThread1 = 0;
  44. m_bThreadRun = false;
  45. m_bUpdateScreen = false;
  46. m_nCaptureType = -1;
  47. m_bHasLiveTask = false;
  48. m_bActiveStop = false;
  49. m_bLookLowerScreen = false;
  50. m_nPassiveTimeLimit = TIME_LIMIT_PASSIVE;
  51. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  52. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  53. m_bLoosePassiveStrategy = FALSE;
  54. m_bTimeout = false;
  55. m_StartCtx = NULL;
  56. m_StopCtx = NULL;
  57. m_bSaveLivenessResult = FALSE;
  58. m_Bitmap0.bmType = 0;
  59. m_Bitmap0.bmWidth = videowidth;
  60. m_Bitmap0.bmHeight = videoheight;
  61. m_Bitmap0.bmPlanes = 1;
  62. m_Bitmap0.bmWidthBytes = 3*m_Bitmap0.bmWidth;
  63. m_Bitmap0.bmBitsPixel = 24;
  64. m_Bitmap0.bmBits = NULL;
  65. m_Bitmap1.bmType = 0;
  66. m_Bitmap1.bmWidth = videoheight;
  67. m_Bitmap1.bmHeight = videowidth;
  68. m_Bitmap1.bmPlanes = 1;
  69. m_Bitmap1.bmWidthBytes = 3*m_Bitmap1.bmWidth;
  70. m_Bitmap1.bmBitsPixel = 24;
  71. m_Bitmap1.bmBits = NULL;
  72. m_Bitmap0Disp = m_Bitmap0;
  73. m_Bitmap1Disp = m_Bitmap1;
  74. m_nImageSize = videowidth*videoheight*3;
  75. m_Bitmap0.bmBits = new unsigned char[m_nImageSize];
  76. m_Bitmap1.bmBits = new unsigned char[m_nImageSize];
  77. m_Bitmap0Disp.bmBits = new unsigned char[m_nImageSize];
  78. m_Bitmap1Disp.bmBits = new unsigned char[m_nImageSize];
  79. InitializeCriticalSection(&m_lock1);
  80. InitializeCriticalSection(&m_lock2);
  81. }
  82. CLivenessDetectionFSM::~CLivenessDetectionFSM()
  83. {
  84. if(m_Bitmap0.bmBits != NULL)
  85. {
  86. delete[] m_Bitmap0.bmBits;
  87. m_Bitmap0.bmBits = NULL;
  88. }
  89. if (m_Bitmap0Disp.bmBits != NULL)
  90. {
  91. delete[] m_Bitmap0Disp.bmBits;
  92. m_Bitmap0Disp.bmBits = NULL;
  93. }
  94. if(m_Bitmap1.bmBits != NULL)
  95. {
  96. delete[] m_Bitmap1.bmBits;
  97. m_Bitmap1.bmBits = NULL;
  98. }
  99. if (m_Bitmap1Disp.bmBits != NULL)
  100. {
  101. delete[] m_Bitmap1Disp.bmBits;
  102. m_Bitmap1Disp.bmBits = NULL;
  103. }
  104. DeleteCriticalSection(&m_lock1);
  105. DeleteCriticalSection(&m_lock2);
  106. }
  107. ErrorCodeEnum CLivenessDetectionFSM::OnInit()
  108. {
  109. CSmartPointer<IEntityFunction> spEntityFunction = GetEntityBase()->GetFunction();
  110. CSmartPointer<IConfigInfo> spConfig;
  111. ErrorCodeEnum eErrDev;
  112. eErrDev = spEntityFunction->OpenConfig(Config_CenterSetting, spConfig);
  113. if (eErrDev != Error_Succeed)
  114. {
  115. Dbg("open centersetting file failed!");
  116. return eErrDev;
  117. }
  118. SpIniMappingTable table;
  119. table.AddEntryInt("LivenessDetection","SaveLivenessResult",m_bSaveLivenessResult,FALSE);
  120. table.AddEntryInt("LivenessDetection","PassiveTimeLimit",m_nPassiveTimeLimit,TIME_LIMIT_PASSIVE);
  121. table.AddEntryInt("LivenessDetection","ActiveTimeLimit",m_nActiveTimeLimit,TIME_LIMIT_ACTIVE);
  122. table.AddEntryInt("LivenessDetection","LeastActiveShowTime",m_nLeastActiveShowTime,TIME_LEAST_ACTIVE_SHOW);
  123. table.AddEntryInt("LivenessDetection","LoosePassiveStrategy",m_bLoosePassiveStrategy,FALSE);
  124. eErrDev = table.Load(spConfig);
  125. if (eErrDev != Error_Succeed)
  126. {
  127. Dbg("fail to load centersettings!");
  128. m_bSaveLivenessResult = FALSE;
  129. m_nPassiveTimeLimit = TIME_LIMIT_PASSIVE;
  130. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  131. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  132. m_bLoosePassiveStrategy = FALSE;
  133. }
  134. if (m_nPassiveTimeLimit<=0||m_nPassiveTimeLimit>7200)
  135. {
  136. m_nPassiveTimeLimit = TIME_LIMIT_PASSIVE;
  137. }
  138. if (m_nLeastActiveShowTime<=0||m_nLeastActiveShowTime>TIME_LIMIT_ACTIVE)
  139. {
  140. m_nLeastActiveShowTime = TIME_LEAST_ACTIVE_SHOW;
  141. }
  142. if (m_nActiveTimeLimit<m_nLeastActiveShowTime||m_nActiveTimeLimit>TIME_LIMIT_ACTIVE)
  143. {
  144. m_nActiveTimeLimit = TIME_LIMIT_ACTIVE;
  145. }
  146. if (m_bLoosePassiveStrategy != 0 && m_bLoosePassiveStrategy != 1)
  147. {
  148. m_bLoosePassiveStrategy = FALSE;
  149. }
  150. if (m_bSaveLivenessResult)
  151. {
  152. eErrDev = m_pEntity->GetFunction()->GetPath("UploadPhoto", m_LivenessResultPath);
  153. if (eErrDev != Error_Succeed)
  154. {
  155. Dbg("fail to get UploadPhotoPath!");
  156. m_LivenessResultPath = "";
  157. }
  158. else
  159. {
  160. int len = m_LivenessResultPath.GetLength();
  161. if (m_LivenessResultPath.GetLength() > 0 && m_LivenessResultPath[len-1] != '\\') {
  162. m_LivenessResultPath += "\\";
  163. }
  164. }
  165. }
  166. VideoInit(m_VideoQueue0Name.c_str(),m_VideoQueue1Name.c_str());
  167. StartMsgHwnd(5000);
  168. // TODO: Add extra initialization here
  169. return Error_Succeed;
  170. }
  171. ErrorCodeEnum CLivenessDetectionFSM::OnExit()
  172. {
  173. if (videoframe0->data != NULL)
  174. {
  175. delete videoframe0->data;
  176. videoframe0->data = NULL;
  177. }
  178. if (videoframe0 != NULL)
  179. {
  180. delete videoframe0;
  181. videoframe0 = NULL;
  182. }
  183. if (videoframe1->data != NULL)
  184. {
  185. delete videoframe1->data;
  186. videoframe1->data = NULL;
  187. }
  188. if (videoframe1 != NULL)
  189. {
  190. delete videoframe1;
  191. videoframe1 = NULL;
  192. }
  193. if (m_videoqueue0 != NULL)
  194. {
  195. delete m_videoqueue0;
  196. m_videoqueue0 = NULL;
  197. }
  198. if (m_videoqueue1 != NULL)
  199. {
  200. delete m_videoqueue1;
  201. m_videoqueue1 = NULL;
  202. }
  203. if (m_hEventWait)
  204. {
  205. CloseHandle(m_hEventWait);
  206. m_hEventWait = NULL;
  207. }
  208. if (m_hEventTask)
  209. {
  210. CloseHandle(m_hEventTask);
  211. m_hEventTask = NULL;
  212. }
  213. StopMsgHwnd();
  214. return Error_Succeed;
  215. }
  216. void CLivenessDetectionFSM::OnStateTrans( int iSrcState, int iDstState )
  217. {
  218. Dbg("[LivenessDetectionFSM] State trans from %d to %d!", iSrcState, iDstState);
  219. }
  220. void CLivenessDetectionFSM::s0_on_entry()
  221. {
  222. LOG_FUNCTION();
  223. if (m_bLookLowerScreen)
  224. {
  225. ScheduleTimer(1,4000);
  226. }
  227. else
  228. {
  229. SetEvent(m_hEventTask);
  230. }
  231. }
  232. void CLivenessDetectionFSM::s0_on_exit()
  233. {
  234. LOG_FUNCTION();
  235. CancelTimer(1);
  236. }
  237. unsigned int CLivenessDetectionFSM::s0_on_event( FSMEvent* e )
  238. {
  239. switch(e->iEvt)
  240. {
  241. case EVT_TIMER:
  242. if (m_bLookLowerScreen)
  243. {
  244. m_bLookLowerScreen=false;
  245. SetEvent(m_hEventTask);
  246. }
  247. break;
  248. case USER_EVT_STOPCAPTURE:
  249. StopLivenessDetection();
  250. m_nCaptureType=-1;
  251. m_bHasLiveTask=false;
  252. if (m_StopCtx!=NULL)
  253. {
  254. m_StopCtx->Answer(Error_Succeed);
  255. m_StopCtx=NULL;
  256. }
  257. e->SetHandled();
  258. break;
  259. case USER_EVT_STARTCAPTURE:
  260. SaveLiveConfig(m_StartCtx);
  261. m_bHasLiveTask=true;
  262. e->SetHandled();
  263. break;
  264. case USER_EVT_QUIT:
  265. e->SetHandled();
  266. LOG_TRACE("s0 on event quit");
  267. break;
  268. default:
  269. break;
  270. }
  271. return 0;
  272. }
  273. void CLivenessDetectionFSM::s1_on_entry()
  274. {
  275. LOG_FUNCTION();
  276. StartCaptureTask *task = new StartCaptureTask(this);
  277. //m_pEntity->GetFunction()->PostThreadPoolTask(task);
  278. m_pEntity->GetFunction()->PostEntityTaskFIFO(task);
  279. }
  280. void CLivenessDetectionFSM::s1_on_exit()
  281. {
  282. LOG_FUNCTION();
  283. }
  284. unsigned int CLivenessDetectionFSM::s1_on_event( FSMEvent* e )
  285. {
  286. int ret = 0;
  287. switch(e->iEvt)
  288. {
  289. case USER_EVT_STOPCAPTURE:
  290. StopLivenessDetection();
  291. m_nCaptureType=-1;
  292. m_bHasLiveTask=false;
  293. if (m_StopCtx!=NULL)
  294. {
  295. m_StopCtx->Answer(Error_Succeed);
  296. m_StopCtx=NULL;
  297. }
  298. e->SetHandled();
  299. break;
  300. case USER_EVT_STARTCAPTURE_FINISHED:
  301. e->SetHandled();
  302. ret = e->param1;
  303. break;
  304. default:
  305. break;
  306. }
  307. return ret;
  308. }
  309. void CLivenessDetectionFSM::s2_on_entry()
  310. {
  311. LOG_FUNCTION();
  312. }
  313. void CLivenessDetectionFSM::s2_on_exit()
  314. {
  315. LOG_FUNCTION();
  316. }
  317. unsigned int CLivenessDetectionFSM::s2_on_event( FSMEvent* e )
  318. {
  319. int ret = 0;
  320. switch(e->iEvt)
  321. {
  322. case USER_EVT_STOPCAPTURE:
  323. {
  324. StopCaptureTask *task = new StopCaptureTask(this);
  325. //m_pEntity->GetFunction()->PostThreadPoolTask(task);
  326. m_pEntity->GetFunction()->PostEntityTaskLIFO(task);
  327. e->SetHandled();
  328. }
  329. break;
  330. case USER_EVT_CAPTURE_FINISHED:
  331. m_bHasLiveTask=false;
  332. if (m_bTimeout)
  333. {
  334. m_bTimeout=false;
  335. DetectionStopUnExpected evt;
  336. evt.IsActive=(m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS||m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITH_LIVENESS?true:false);
  337. evt.ActionID=CSimpleStringA2W(m_uid.ToString());
  338. evt.ErrorCode=CSimpleStringA2W("Error_TimeOut");
  339. if (evt.IsActive)
  340. {
  341. evt.ErrorMsg = CSimpleStringA2W("主动捕获超时,已终止!");
  342. }
  343. else
  344. {
  345. evt.ErrorMsg = CSimpleStringA2W("被动捕获超时,已终止!");
  346. }
  347. SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(DetectionStopUnExpected), SP_MSG_SIG_OF(DetectionStopUnExpected), evt);
  348. Dbg("[dbg]: DetectionStopUnExpected has broadcasted.");
  349. }
  350. if (m_StopCtx!=NULL)
  351. {
  352. m_StopCtx->Answer(Error_Succeed);
  353. m_StopCtx=NULL;
  354. }
  355. m_nCaptureType=-1;
  356. e->SetHandled();
  357. break;
  358. default:
  359. break;
  360. }
  361. return ret;
  362. }
  363. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  364. {
  365. switch (message)
  366. {
  367. case WM_LIVENESS_DONE:
  368. if (pFsm->m_bHasLiveTask)
  369. {
  370. Dbg("主动捕获成功");
  371. pFsm->m_bHasLiveTask=false; // 防止重复广播
  372. // send to rvcweb
  373. ActiveDetectionDone evt;
  374. int nLiveType = (int)wParam;
  375. char *LiveTypes[]={"N","Y","X"};
  376. evt.VerifyResult=CSimpleStringA2W(LiveTypes[nLiveType]);
  377. Dbg("ActiveLiveType:%s",LiveTypes[nLiveType]);
  378. evt.ActionID=CSimpleStringA2W(pFsm->m_uid.ToString());
  379. BITMAP bitmap;
  380. YituLiveSDK::YituGetImage(&bitmap);
  381. if (bitmap.bmBits!=NULL)
  382. {
  383. if (pFsm->m_bSaveLivenessResult&&pFsm->m_LivenessResultPath.GetLength()>0)
  384. {
  385. // save liveness result
  386. char szPhoto[MAX_PATH]={0};
  387. sprintf(szPhoto,"%s%s_Active_%d_0.jpg",(LPCTSTR)pFsm->m_LivenessResultPath,
  388. (LPCTSTR)pFsm->m_uid.ToString(),nLiveType);
  389. SaveLivenessPhoto(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,szPhoto);
  390. }
  391. int nJpgSize=0;
  392. int size = 3*bitmap.bmHeight*bitmap.bmWidth;
  393. char *pJpg=new char[size];
  394. RGB2JPG(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,&nJpgSize,pJpg,pDetection);
  395. if (nJpgSize)
  396. {
  397. evt.SnapShotPhotoLength = nJpgSize;
  398. evt.SnapShotPhotoData.Alloc(nJpgSize);
  399. memmove(evt.SnapShotPhotoData.m_pData, pJpg, nJpgSize);
  400. evt.SnapShotPhotoData.Resize(nJpgSize);
  401. }
  402. else
  403. {
  404. evt.SnapShotPhotoLength=0;
  405. }
  406. delete []pJpg; pJpg=NULL;
  407. }
  408. else
  409. {
  410. evt.SnapShotPhotoLength=0;
  411. }
  412. int nTimeUsed=pFsm->m_nSeconds;
  413. int nLeastActiveShowTime=pFsm->m_nLeastActiveShowTime;
  414. if (nTimeUsed<nLeastActiveShowTime)
  415. {
  416. ::Sleep((nLeastActiveShowTime-nTimeUsed)*1000); // 保证至少进行nLeastActiveShowTime才结束并通知
  417. }
  418. pFsm->StopLivenessDetection();
  419. pFsm->PostEventFIFO(new FSMEvent(USER_EVT_CAPTURE_FINISHED));
  420. SpSendBroadcast(pDetection->GetFunction(), SP_MSG_OF(ActiveDetectionDone), SP_MSG_SIG_OF(ActiveDetectionDone), evt);
  421. Dbg("[dbg]: ActiveDetectionDone has broadcasted.");
  422. }
  423. break;
  424. case WM_IMAGE_INFO:
  425. if (pFsm->m_bHasLiveTask) // 如果还未报活体结束
  426. {
  427. strStatus="";
  428. switch(lParam) {
  429. case STATUS_HeadLeft:
  430. strStatus="请左转一些";
  431. break;
  432. case STATUS_HeadRight:
  433. strStatus="请右转一些";
  434. break;
  435. case STATUS_HeadUp:
  436. strStatus="请不要抬头太高";
  437. break;
  438. case STATUS_HeadDown:
  439. strStatus="请不要低头";
  440. break;
  441. case STATUS_HalfFace:
  442. strStatus="请不要遮挡面部";
  443. break;
  444. case STATUS_HasSunGlasses:
  445. strStatus="请不要遮挡眼睛";
  446. break;
  447. case STATUS_HasMask:
  448. strStatus="请不要遮挡嘴部";
  449. break;
  450. case STATUS_HasHat:
  451. strStatus="请取下帽子";
  452. break;
  453. case STATUS_NoFace:
  454. strStatus="请对准摄像头";
  455. break;
  456. case STATUS_Normal:
  457. strStatus="请保持";
  458. break;
  459. default:
  460. Dbg("receive status code: %d",lParam);
  461. break;
  462. }
  463. //Dbg("strStatus:%s(%d)",(LPCTSTR)strStatus,lParam);
  464. if (strStatus.GetLength() > 0 && strStatus != strLastStatus)
  465. {
  466. AutoSnapshotRemind evt;
  467. evt.ActionID=CSimpleStringA2W(pFsm->m_uid.ToString());
  468. evt.RemindInfo=CSimpleStringA2W(strStatus);
  469. LogEvent(Severity_Middle,LOG_EVT_SHOWACTIVECAPTUREMSG,(LPCTSTR)strStatus); // notify iebrowser
  470. SpSendBroadcast(pDetection->GetFunction(), SP_MSG_OF(AutoSnapshotRemind), SP_MSG_SIG_OF(AutoSnapshotRemind), evt);
  471. Dbg("[dbg]: AutoSnapshotRemind has broadcasted.");
  472. strLastStatus=strStatus;
  473. }
  474. }
  475. break;
  476. case WM_CAMERA_ECHO:
  477. {
  478. nEchoCamera=(int)wParam;
  479. char strEchoCamera[2]={0};
  480. sprintf(strEchoCamera,"%d",nEchoCamera);
  481. LogEvent(Severity_Middle,LOG_EVT_ECHOACTIVECAPTURECAM,strEchoCamera); // notify chh(sipphone)
  482. }
  483. break;
  484. case WM_TIME_UPDATE:
  485. {
  486. //Dbg("[dbg] WM_TIME_UPDATE received.");
  487. //CLivenessDetectionFSM *pFSM = (CLivenessDetectionFSM *)lParam;
  488. //pFSM->UpdateTime((int)wParam);
  489. }
  490. break;
  491. case WM_CAMERA_FAULT:
  492. {
  493. Dbg("On WM_CAMERA_FAULT!");
  494. CLivenessDetectionFSM *pFSM = (CLivenessDetectionFSM *)lParam;
  495. pFSM->NotifyCameraFault();
  496. }
  497. break;
  498. case WM_DESTROY:
  499. PostQuitMessage(0);
  500. break;
  501. /*case WM_TIMER:
  502. printf("[dbg] got Timer Message.\n");
  503. break;*/
  504. default:
  505. return DefWindowProc(hWnd, message, wParam, lParam);
  506. }
  507. return 0;
  508. }
  509. VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
  510. {
  511. if (NULL == pDetection)
  512. {
  513. Dbg("[dbg]: heartbeat cann't be sent.");
  514. return;
  515. }
  516. LivenessDetectionHeartBeat evt;
  517. evt.Status = 0;
  518. SpSendBroadcast(pDetection->GetFunction(), SP_MSG_OF(LivenessDetectionHeartBeat), SP_MSG_SIG_OF(LivenessDetectionHeartBeat), evt);
  519. Dbg("[dbg]: heartbeat has sent.");
  520. }
  521. UINT CALLBACK HWndThreadProc( LPVOID param )
  522. {
  523. pDetection = dynamic_cast<CLivenessDetectionEntity *>((CEntityBase*)param);
  524. TCHAR szClassName[256] = {'l', 'd', 0};
  525. SYSTEMTIME st;
  526. GetLocalTime(&st);
  527. srand(GetTickCount());
  528. sprintf_s(szClassName+2, 250, "%d%d%d%d%d%d", rand(), rand(), st.wMinute, st.wSecond, st.wMilliseconds, GetTickCount());
  529. Dbg("[dbg] szClassName: %s.", szClassName);
  530. WNDCLASSEX wcex = {0};
  531. wcex.cbSize = sizeof(WNDCLASSEX);
  532. wcex.style = CS_HREDRAW | CS_VREDRAW;
  533. wcex.lpfnWndProc = (WNDPROC)WndProc;
  534. wcex.lpszClassName = szClassName;
  535. if (!RegisterClassEx(&wcex))
  536. {
  537. Dbg("[dbg] RegisterClassEx Failed!\r\n");
  538. return 1;
  539. }
  540. hDetectionWnd = CreateWindow(szClassName, "", WS_OVERLAPPEDWINDOW,
  541. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL);
  542. HideCaret(hDetectionWnd);
  543. MSG msg;
  544. assert(hDetectionWnd!=NULL);
  545. CSimpleStringA csBinPath;
  546. ErrorCodeEnum errCode=pDetection->GetFunction()->GetPath("Bin",csBinPath);
  547. CSimpleStringA dllName;
  548. if (errCode!=Error_Succeed)
  549. {
  550. return 2;
  551. }
  552. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  553. if (!(ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType))
  554. {
  555. dllName=csBinPath.Append("\\Liveness.0.12.dll");
  556. }
  557. else
  558. {
  559. dllName=csBinPath.Append("\\Liveness4Pad\\Liveness.0.12.dll");
  560. }
  561. Dbg("[dbg] dllName:%s",(LPCTSTR)dllName);
  562. YituLiveSDK::Yitu_InitParam Iniparam;
  563. Iniparam.szPath=".";
  564. Iniparam.hwnd=hDetectionWnd;
  565. Iniparam.uMsgLivenessDone=WM_LIVENESS_DONE;
  566. Iniparam.uMsgImageInfo=WM_IMAGE_INFO;
  567. Iniparam.uMsgEchoCamera=WM_CAMERA_ECHO;
  568. Dbg("[dbg] begin to call YituInit.");
  569. int rtn=YituLiveSDK::YituInit((LPCTSTR)dllName,&Iniparam);
  570. Dbg("[dbg] end to call YituInit.");
  571. assert(rtn==FUNCTION_RTN_SUCC);
  572. //SetTimer(hDetectionWnd,TimerID,Interval,TimerProc);
  573. while (GetMessage(&msg, NULL, 0, 0))
  574. {
  575. TranslateMessage(&msg);
  576. DispatchMessage(&msg);
  577. }
  578. return 0;
  579. }
  580. BOOL CLivenessDetectionFSM::StartMsgHwnd( UINT nInterval )
  581. {
  582. if (hWndThread)
  583. {
  584. Dbg("[dbg] DetectionWndThread has started.");
  585. return TRUE;
  586. }
  587. Interval = nInterval;
  588. pFsm = this;
  589. hWndThread = (HANDLE)_beginthreadex(NULL, 0, HWndThreadProc, this->GetEntityBase(), 0, &hWndThreadID);
  590. return hWndThread ? TRUE : FALSE;
  591. }
  592. BOOL CLivenessDetectionFSM::StopMsgHwnd()
  593. {
  594. if (hDetectionWnd)
  595. {
  596. //KillTimer(hDetectionWnd, TimerID);
  597. SendMessage(hDetectionWnd,WM_CLOSE,0,0);
  598. if (hDetectionWnd)
  599. {
  600. WaitForSingleObject(hWndThread,-1);
  601. CloseHandle(hWndThread);
  602. }
  603. hWndThread = NULL;
  604. hDetectionWnd = NULL;
  605. int rtn=YituLiveSDK::YituUninit();
  606. assert(rtn==FUNCTION_RTN_SUCC);
  607. }
  608. return TRUE;
  609. }
  610. void CLivenessDetectionFSM::VideoInit( LPCTSTR videoqueue0name,LPCTSTR videoqueue1name )
  611. {
  612. videoframe0 = new videoq_frame;
  613. memset(videoframe0,0,sizeof(videoq_frame));
  614. videoframe1 = new videoq_frame;
  615. memset(videoframe1,0,sizeof(videoq_frame));
  616. m_hEventWait= ::CreateEventA(NULL, TRUE, 0, 0);
  617. if (!m_hEventWait)
  618. {
  619. Dbg("create hEventWait failed!");
  620. return;
  621. }
  622. m_hEventTask = ::CreateEventA(NULL, TRUE, TRUE, "TaskFinishEvent");
  623. if (!m_hEventTask)
  624. {
  625. Dbg("create hEventTask failed!");
  626. }
  627. if (videoqueue0name&&strlen(videoqueue0name)>0)
  628. {
  629. m_videoqueue0 = new Clibvideoqueue(videoqueue0name);
  630. }
  631. else
  632. {
  633. m_videoqueue0 = NULL;
  634. }
  635. if (videoqueue1name&&strlen(videoqueue1name)>0)
  636. {
  637. m_videoqueue1 = new Clibvideoqueue(videoqueue1name);
  638. }
  639. else
  640. {
  641. m_videoqueue1 = NULL;
  642. }
  643. }
  644. int CLivenessDetectionFSM::GetVideoFrameSize( int&nWidth,int&nHeight )
  645. {
  646. int size = 0;
  647. if (m_videoqueue0 == NULL)
  648. {
  649. Dbg("videoqueue not initialized,not exsit!");
  650. size = 0;
  651. }
  652. if (m_videoqueue1)
  653. {
  654. int width1 = 0;
  655. int height1 = 0;
  656. int width2 = 0;
  657. int height2 = 0;
  658. size = m_videoqueue0->GetFrameSize(width1,height1);
  659. if (size)
  660. {
  661. (width1>height1)?(nWidth=nHeight=width1):(nWidth=nHeight=height1);
  662. }
  663. else
  664. {
  665. size = m_videoqueue1->GetFrameSize(width2,height2);
  666. (width2>height2)?(nWidth=nHeight=width2):(nWidth=nHeight=height2);
  667. }
  668. size = nWidth*nHeight*3;
  669. }
  670. else
  671. {
  672. size = m_videoqueue0->GetFrameSize(nWidth,nHeight);
  673. int width1 = nWidth;
  674. int height1 = nHeight;
  675. (width1>height1)?(nWidth=nHeight=width1):(nWidth=nHeight=height1);
  676. size = nWidth*nHeight*3;
  677. }
  678. return size;
  679. }
  680. BOOL CLivenessDetectionFSM::GetVideoFrameByCameraID( int CameraID, videoq_frame* Video, int flags )
  681. {
  682. assert(CameraID == 0 || CameraID == 1);
  683. if (CameraID == 0) // For StandVTM or Pad
  684. {
  685. BOOL bRslt = FALSE;
  686. int width = 0;
  687. int height = 0;
  688. m_videoqueue0->GetFrameSize(width,height);
  689. memset(Video->data,0,Video->framesize);
  690. videoq_frame*tmp_frm = new videoq_frame;
  691. //tmp_frm->data = Video->data+ Video->width*(width-height)/2*3;
  692. tmp_frm->data = Video->data;
  693. bRslt = m_videoqueue0->GetVideo(tmp_frm, flags);
  694. if (!bRslt)
  695. {
  696. delete tmp_frm;
  697. Dbg("get video from videoqueue0 fail!");
  698. return FALSE;
  699. }
  700. delete tmp_frm;
  701. return TRUE;
  702. }
  703. else // For StandVTM
  704. {
  705. BOOL bRslt = FALSE;
  706. int width = 0;
  707. int height = 0;
  708. m_videoqueue1->GetFrameSize(width,height);
  709. memset(Video->data,0,Video->framesize);
  710. videoq_frame*tmp_frm = new videoq_frame;
  711. //tmp_frm->data = Video->data + (height-width)/2*3;
  712. tmp_frm->data = Video->data;
  713. //横向摄像头图像,拼接
  714. bRslt = m_videoqueue1->GetVideo(tmp_frm, flags);
  715. if (!bRslt)
  716. {
  717. delete tmp_frm;
  718. Dbg("get video from videoqueue1 fail!");
  719. return FALSE;
  720. }
  721. delete tmp_frm;
  722. return TRUE;
  723. }
  724. }
  725. void CLivenessDetectionFSM::FSleep( int ms )
  726. {
  727. DWORD dwRet = WaitForSingleObject(m_hEventWait, ms);
  728. if (dwRet == WAIT_OBJECT_0) // 如果等到信号
  729. {
  730. throw std::exception(); // 抛个异常表明是外界停止捕获
  731. }
  732. }
  733. UINT CLivenessDetectionFSM::VideoCapture0()
  734. {
  735. int nWidth = 0;
  736. int nHeight = 0;
  737. int nVideoFrameSize = 0; //视频帧的大小
  738. BOOL bInitVideoParam = FALSE;
  739. unsigned char* pData0=NULL;
  740. unsigned char* pData1=NULL;
  741. bool bHasOneMoreData=false;
  742. int nVideoSizeFailedTimes = 0; // add by ly 20160716
  743. while (m_bCameraThreadRun)
  744. {
  745. try
  746. {
  747. if (!bInitVideoParam)
  748. {
  749. //获取视频帧大小
  750. if (nVideoFrameSize <= 0)
  751. {
  752. if (nVideoSizeFailedTimes >= 400)
  753. {
  754. Dbg("[dbg] camera0 fault,nVideoSizeFailedTimes=%d!",nVideoSizeFailedTimes);
  755. m_bCameraThreadRun=false;
  756. ::PostMessage(hDetectionWnd,WM_CAMERA_FAULT,0,(LONG_PTR)this);
  757. continue;
  758. }
  759. //nVideoFrameSize = GetVideoFrameSize(nWidth,nHeight);
  760. nWidth = m_Bitmap0.bmWidth;
  761. nHeight = m_Bitmap0.bmHeight;
  762. nVideoFrameSize = 3*nWidth*nHeight;
  763. if(nVideoFrameSize <= 0)
  764. {
  765. ++nVideoSizeFailedTimes;
  766. Dbg("[Capture0] nVideoFrameSize = 0");
  767. FSleep(5);
  768. continue;
  769. }
  770. pData1=new unsigned char[nVideoFrameSize];
  771. //初始化视频buffer
  772. if (videoframe0->data == NULL)
  773. {
  774. videoframe0->data = new unsigned char[nVideoFrameSize];
  775. videoframe0->framesize = nVideoFrameSize;
  776. videoframe0->height = nHeight;
  777. videoframe0->width = nWidth;
  778. videoframe0->format = VIDEO_FORMAT_RGB24;
  779. }
  780. }
  781. bInitVideoParam = TRUE;
  782. continue;
  783. }
  784. BOOL bVideoLens = (m_videoqueue0->GetVideoLens()>0);
  785. if (bVideoLens)
  786. {
  787. if(m_bHasData0==false)
  788. {
  789. if (bHasOneMoreData)
  790. {
  791. memcpy(m_Bitmap0.bmBits,pData1,nVideoFrameSize);
  792. //FlipImage(&m_Bitmap0);
  793. bHasOneMoreData=false;
  794. EnterCriticalSection(&m_lock2);
  795. m_bHasData0=true;
  796. LeaveCriticalSection(&m_lock2);
  797. //Dbg("[dbg] VideoCapture0 got frame at 1.");
  798. }
  799. else
  800. {
  801. BOOL bGetvideo = GetVideoFrameByCameraID(0,videoframe0,0);
  802. if (!bGetvideo)
  803. {
  804. FSleep(2);
  805. continue;
  806. }
  807. pData0=videoframe0->data;
  808. if (pData0!=NULL)
  809. {
  810. memcpy(m_Bitmap0.bmBits,pData0,nVideoFrameSize);
  811. //FlipImage(&m_Bitmap0);
  812. EnterCriticalSection(&m_lock2);
  813. m_bHasData0=true;
  814. LeaveCriticalSection(&m_lock2);
  815. //Dbg("[dbg] VideoCapture0 got frame at 2.");
  816. }
  817. }
  818. }
  819. else if (bHasOneMoreData==false)
  820. {
  821. BOOL bGetvideo = GetVideoFrameByCameraID(0,videoframe0,0);
  822. if (!bGetvideo)
  823. {
  824. FSleep(2);
  825. continue;
  826. }
  827. pData0=videoframe0->data;
  828. if (pData0!=NULL)
  829. {
  830. memcpy(pData1,pData0,nVideoFrameSize);
  831. bHasOneMoreData=true;
  832. //Dbg("[dbg] VideoCapture0 put frame to buffer.");
  833. }
  834. }
  835. }
  836. else
  837. {
  838. //Dbg("[dbg] VideoCapture1 got no frame.");
  839. // 摄像头启动失败无法采集,填充黑色
  840. if (m_bHasData0 == false)
  841. {
  842. if (bHasOneMoreData)
  843. {
  844. memcpy(m_Bitmap0.bmBits,pData1,nVideoFrameSize);
  845. //FlipImage(&m_Bitmap0);
  846. bHasOneMoreData=false;
  847. EnterCriticalSection(&m_lock2);
  848. m_bHasData0=true;
  849. LeaveCriticalSection(&m_lock2);
  850. }
  851. else
  852. {
  853. memset(m_Bitmap0.bmBits,0,nVideoFrameSize);
  854. EnterCriticalSection(&m_lock2);
  855. m_bHasData0=true;
  856. LeaveCriticalSection(&m_lock2);
  857. }
  858. }
  859. else if (bHasOneMoreData == false)
  860. {
  861. memset(pData1,0,nVideoFrameSize);
  862. bHasOneMoreData=true;
  863. }
  864. }
  865. FSleep(5);
  866. }
  867. catch (...)
  868. {
  869. Dbg("[Captrue0] exception occurred or stop capture.");
  870. Sleep(50);
  871. continue;
  872. }
  873. }
  874. if (pData1)
  875. {
  876. delete pData1;
  877. pData1=NULL;
  878. }
  879. m_hCameraThread0=0;
  880. return 0;
  881. }
  882. UINT CLivenessDetectionFSM::VideoCapture1()
  883. {
  884. int nWidth = 0;
  885. int nHeight = 0;
  886. int nVideoFrameSize = 0; //视频帧的大小
  887. BOOL bInitVideoParam = FALSE;
  888. unsigned char* pData0=NULL;
  889. unsigned char* pData1=NULL;
  890. bool bHasOneMoreData=false;
  891. int nVideoSizeFailedTimes = 0; // add by ly 20160716
  892. while (m_bCameraThreadRun)
  893. {
  894. try
  895. {
  896. if (!bInitVideoParam)
  897. {
  898. //获取视频帧大小
  899. if (nVideoFrameSize <= 0)
  900. {
  901. if (nVideoSizeFailedTimes >= 400)
  902. {
  903. Dbg("[dbg] camera1 fault,nVideoSizeFailedTimes=%d!",nVideoSizeFailedTimes);
  904. m_bCameraThreadRun=false;
  905. ::PostMessage(hDetectionWnd,WM_CAMERA_FAULT,0,(LONG_PTR)this);
  906. continue;
  907. }
  908. //nVideoFrameSize = GetVideoFrameSize(nWidth,nHeight);
  909. nWidth = m_Bitmap1.bmWidth;
  910. nHeight = m_Bitmap1.bmHeight;
  911. nVideoFrameSize = 3*nWidth*nHeight;
  912. if(nVideoFrameSize <= 0)
  913. {
  914. ++nVideoSizeFailedTimes;
  915. Dbg("[Capture1] nVideoFrameSize = 0");
  916. FSleep(5);
  917. continue;
  918. }
  919. pData1=new unsigned char[nVideoFrameSize];
  920. //初始化视频buffer
  921. if (videoframe1->data == NULL)
  922. {
  923. videoframe1->data = new unsigned char[nVideoFrameSize];
  924. videoframe1->framesize = nVideoFrameSize;
  925. videoframe1->height = nHeight;
  926. videoframe1->width = nWidth;
  927. videoframe1->format = VIDEO_FORMAT_RGB24;
  928. }
  929. }
  930. bInitVideoParam = TRUE;
  931. continue;
  932. }
  933. BOOL bVideoLens = (m_videoqueue1->GetVideoLens()>0);
  934. if (bVideoLens)
  935. {
  936. if(m_bHasData1==false)
  937. {
  938. if (bHasOneMoreData)
  939. {
  940. memcpy(m_Bitmap1.bmBits,pData1,nVideoFrameSize);
  941. //FlipImage(&m_Bitmap1);
  942. bHasOneMoreData=false;
  943. EnterCriticalSection(&m_lock2);
  944. m_bHasData1=true;
  945. LeaveCriticalSection(&m_lock2);
  946. //Dbg("[dbg] VideoCapture1 got frame at 1.");
  947. }
  948. else
  949. {
  950. BOOL bGetvideo = GetVideoFrameByCameraID(1,videoframe1,0);
  951. if (!bGetvideo)
  952. {
  953. FSleep(2);
  954. continue;
  955. }
  956. pData0=videoframe1->data;
  957. if (pData0!=NULL)
  958. {
  959. memcpy(m_Bitmap1.bmBits,pData0,nVideoFrameSize);
  960. //FlipImage(&m_Bitmap1);
  961. EnterCriticalSection(&m_lock2);
  962. m_bHasData1=true;
  963. LeaveCriticalSection(&m_lock2);
  964. //Dbg("[dbg] VideoCapture1 got frame at 2.");
  965. }
  966. }
  967. }
  968. else if (bHasOneMoreData==false)
  969. {
  970. BOOL bGetvideo = GetVideoFrameByCameraID(1,videoframe1,0);
  971. if (!bGetvideo)
  972. {
  973. FSleep(2);
  974. continue;
  975. }
  976. pData0=videoframe1->data;
  977. if (pData0!=NULL)
  978. {
  979. memcpy(pData1,pData0,nVideoFrameSize);
  980. bHasOneMoreData=true;
  981. //Dbg("[dbg] VideoCapture1 put frame to buffer.");
  982. }
  983. }
  984. }
  985. else
  986. {
  987. //Dbg("[dbg] VideoCapture1 got no frame.");
  988. // 摄像头启动失败无法采集,用黑色填充
  989. if (m_bHasData1 == false)
  990. {
  991. if (bHasOneMoreData)
  992. {
  993. memcpy(m_Bitmap1.bmBits,pData1,nVideoFrameSize);
  994. //FlipImage(&m_Bitmap1);
  995. bHasOneMoreData=false;
  996. EnterCriticalSection(&m_lock2);
  997. m_bHasData1=true;
  998. LeaveCriticalSection(&m_lock2);
  999. }
  1000. else
  1001. {
  1002. memset(m_Bitmap1.bmBits,0,nVideoFrameSize);
  1003. EnterCriticalSection(&m_lock2);
  1004. m_bHasData1=true;
  1005. LeaveCriticalSection(&m_lock2);
  1006. }
  1007. }
  1008. else if (bHasOneMoreData == false)
  1009. {
  1010. memset(pData1,0,nVideoFrameSize);
  1011. bHasOneMoreData=true;
  1012. }
  1013. }
  1014. FSleep(5);
  1015. }
  1016. catch (...)
  1017. {
  1018. Dbg("[Captrue1] exception occurred or stop capture.");
  1019. Sleep(50);
  1020. continue;
  1021. }
  1022. }
  1023. if (pData1)
  1024. {
  1025. delete pData1;
  1026. pData1=NULL;
  1027. }
  1028. m_hCameraThread1=0;
  1029. return 0;
  1030. }
  1031. UINT CLivenessDetectionFSM::SingleCameraDetect()
  1032. {
  1033. int nFrameID = 0;
  1034. DWORD dwStart = GetTickCount();
  1035. while (m_bThreadRun)
  1036. {
  1037. if (m_bHasData0 == false)
  1038. {
  1039. Sleep(5);
  1040. continue;
  1041. }
  1042. DWORD dwTime = GetTickCount();
  1043. YituLiveSDK::Yitu_ImageData data;
  1044. data.pImage = &m_Bitmap0;
  1045. data.nCameraID = 0;
  1046. data.nFrameID = nFrameID;
  1047. data.dTimeStamp = GetTickCount() / 1000.0;
  1048. YituLiveSDK::YituAppendFrame(&data);
  1049. if (m_nCaptureType == CAPTURE_TYPE_PASSIVE)
  1050. {
  1051. data.pImage = NULL;
  1052. data.nCameraID = 1;
  1053. YituLiveSDK::YituAppendFrame(&data);
  1054. }
  1055. nFrameID++;
  1056. if (GetTickCount() - dwStart > 1000)
  1057. {
  1058. dwStart += 1000;
  1059. //::PostMessage(hDetectionWnd, WM_TIME_UPDATE, nFrameID, 0);
  1060. m_nSeconds++;
  1061. if (IsTimeOut())
  1062. {
  1063. m_bTimeout=true;
  1064. m_bThreadRun=false;
  1065. PostEventFIFO(new FSMEvent(USER_EVT_STOPCAPTURE));
  1066. continue;
  1067. }
  1068. }
  1069. else
  1070. {
  1071. EnterCriticalSection(&m_lock1);
  1072. memcpy(m_Bitmap0Disp.bmBits, m_Bitmap0.bmBits, m_nImageSize);
  1073. LeaveCriticalSection(&m_lock1);
  1074. }
  1075. m_nTime += GetTickCount() - dwTime;
  1076. EnterCriticalSection(&m_lock2);
  1077. m_bHasData0 = false;
  1078. LeaveCriticalSection(&m_lock2);
  1079. }
  1080. m_hDetectThread = 0;
  1081. return 0;
  1082. }
  1083. UINT CLivenessDetectionFSM::LiveDetect()
  1084. {
  1085. int nFrameID=0;
  1086. DWORD dwStart=GetTickCount();
  1087. while (m_bThreadRun)
  1088. {
  1089. if (m_bHasData0==false||m_bHasData1==false)
  1090. {
  1091. Sleep(5);
  1092. continue;
  1093. }
  1094. //Dbg("[dbg] do detect.");
  1095. DWORD dwTime=GetTickCount();
  1096. YituLiveSDK::Yitu_ImageData data;
  1097. // 目前只能先传0后传1
  1098. data.pImage=&m_Bitmap0;
  1099. data.nCameraID=0;
  1100. data.nFrameID=nFrameID;
  1101. data.dTimeStamp=GetTickCount()/1000.0;
  1102. YituLiveSDK::YituAppendFrame(&data);
  1103. data.pImage=&m_Bitmap1;
  1104. data.nCameraID=1;
  1105. YituLiveSDK::YituAppendFrame(&data);
  1106. nFrameID++;
  1107. if (GetTickCount()-dwStart>1000)
  1108. {
  1109. dwStart+=1000;
  1110. //::PostMessage(hDetectionWnd,WM_TIME_UPDATE,nFrameID,(LONG_PTR)this);
  1111. m_nSeconds++;
  1112. if (IsTimeOut())
  1113. {
  1114. m_bTimeout=true;
  1115. m_bThreadRun=false;
  1116. PostEventFIFO(new FSMEvent(USER_EVT_STOPCAPTURE));
  1117. continue;
  1118. }
  1119. }
  1120. else
  1121. {
  1122. EnterCriticalSection(&m_lock1);
  1123. memcpy(m_Bitmap0Disp.bmBits,m_Bitmap0.bmBits,m_nImageSize);
  1124. memcpy(m_Bitmap1Disp.bmBits,m_Bitmap1.bmBits,m_nImageSize);
  1125. LeaveCriticalSection(&m_lock1);
  1126. // show image msg
  1127. }
  1128. m_nTime+=GetTickCount()-dwTime;
  1129. EnterCriticalSection(&m_lock2);
  1130. m_bHasData0=false;
  1131. m_bHasData1=false;
  1132. LeaveCriticalSection(&m_lock2);
  1133. }
  1134. m_hDetectThread=0;
  1135. return 0;
  1136. }
  1137. UINT WINAPI CameraThread0(LPVOID pM)
  1138. {
  1139. CLivenessDetectionFSM* pFSM=(CLivenessDetectionFSM*)pM;
  1140. return pFSM->VideoCapture0();
  1141. }
  1142. UINT WINAPI CameraThread1(LPVOID pM)
  1143. {
  1144. CLivenessDetectionFSM* pFSM=(CLivenessDetectionFSM*)pM;
  1145. return pFSM->VideoCapture1();
  1146. }
  1147. UINT WINAPI SingleCameraDetectThread(LPVOID pM)
  1148. {
  1149. CLivenessDetectionFSM* pFSM=(CLivenessDetectionFSM*)pM;
  1150. return pFSM->SingleCameraDetect();
  1151. }
  1152. UINT WINAPI DetectThread(LPVOID pM)
  1153. {
  1154. CLivenessDetectionFSM* pFSM=(CLivenessDetectionFSM*)pM;
  1155. return pFSM->LiveDetect();
  1156. }
  1157. bool CLivenessDetectionFSM::IsTimeOut()
  1158. {
  1159. if (m_nCaptureType==-1)
  1160. {
  1161. return true;
  1162. }
  1163. int nTimeLimit=(m_nCaptureType==CAPTURE_TYPE_PASSIVE?m_nPassiveTimeLimit:m_nActiveTimeLimit);
  1164. return m_nSeconds>=nTimeLimit?true:false;
  1165. }
  1166. void CLivenessDetectionFSM::UpdateTime( int nFrame )
  1167. {
  1168. m_nSeconds++;
  1169. Dbg("Second=%d , FPS=%d, algorithm time=%.3fs",m_nSeconds,nFrame-m_nLastFrame,m_nTime/1000.0);
  1170. m_nTime=0;
  1171. m_nLastFrame=nFrame;
  1172. // 显示人脸检测框
  1173. int nCount=0,i;
  1174. YituLiveSDK::Yitu_TrackData data;
  1175. int rtn=YituLiveSDK::YituGetTrackCount(0,&nCount);
  1176. for (i=0;i<nCount;i++)
  1177. {
  1178. if (0==YituLiveSDK::YituGetTrackData(0,i,&data))
  1179. {
  1180. EnterCriticalSection(&m_lock1);
  1181. DrawRect(data.rectFace,&m_Bitmap0);
  1182. memcpy(m_Bitmap0Disp.bmBits,m_Bitmap0.bmBits,m_nImageSize);
  1183. BMP_SaveFile("d:\\rvc\\face_0.jpg",m_Bitmap0Disp.bmBits,m_Bitmap0Disp.bmWidth,m_Bitmap0Disp.bmHeight,m_Bitmap0Disp.bmBitsPixel);
  1184. LeaveCriticalSection(&m_lock1);
  1185. }
  1186. }
  1187. rtn=YituLiveSDK::YituGetTrackCount(1,&nCount);
  1188. for (i=0;i<nCount;i++)
  1189. {
  1190. if (0==YituLiveSDK::YituGetTrackData(1,i,&data))
  1191. {
  1192. EnterCriticalSection(&m_lock1);
  1193. DrawRect(data.rectFace,&m_Bitmap1);
  1194. memcpy(m_Bitmap1Disp.bmBits,m_Bitmap1.bmBits,m_nImageSize);
  1195. BMP_SaveFile("d:\\rvc\\face_1.jpg",m_Bitmap1Disp.bmBits,m_Bitmap1Disp.bmWidth,m_Bitmap1Disp.bmHeight,m_Bitmap1Disp.bmBitsPixel);
  1196. LeaveCriticalSection(&m_lock1);
  1197. }
  1198. }
  1199. }
  1200. void CLivenessDetectionFSM::DrawRect( RECT rect,BITMAP* pPic )
  1201. {
  1202. if (rect.right<0 || rect.left<0 || rect.top<0 || rect.bottom<0)
  1203. {
  1204. return;
  1205. }
  1206. if (rect.right>=pPic->bmWidth || rect.left>=pPic->bmWidth ||
  1207. rect.top>=pPic->bmHeight || rect.bottom>=pPic->bmHeight)
  1208. {
  1209. return;
  1210. }
  1211. int i;
  1212. unsigned char* p1=(unsigned char*)pPic->bmBits;
  1213. for (i=rect.left;i<rect.right;i++)
  1214. {
  1215. p1[rect.top*pPic->bmWidthBytes+i*3]=0;
  1216. p1[rect.top*pPic->bmWidthBytes+i*3+1]=0;
  1217. p1[rect.top*pPic->bmWidthBytes+i*3+2]=255;
  1218. p1[rect.bottom*pPic->bmWidthBytes+i*3]=0;
  1219. p1[rect.bottom*pPic->bmWidthBytes+i*3+1]=0;
  1220. p1[rect.bottom*pPic->bmWidthBytes+i*3+2]=255;
  1221. }
  1222. for (i=rect.top;i<rect.bottom;i++)
  1223. {
  1224. p1[i*pPic->bmWidthBytes+rect.left*3]=0;
  1225. p1[i*pPic->bmWidthBytes+rect.left*3+1]=0;
  1226. p1[i*pPic->bmWidthBytes+rect.left*3+2]=255;
  1227. p1[i*pPic->bmWidthBytes+rect.right*3]=0;
  1228. p1[i*pPic->bmWidthBytes+rect.right*3+1]=0;
  1229. p1[i*pPic->bmWidthBytes+rect.right*3+2]=255;
  1230. }
  1231. int leftborder=rect.left<1?0:rect.left-1;
  1232. int rightborder=rect.right>pPic->bmWidth-1?pPic->bmWidth:rect.right+1;
  1233. int topborder=rect.top<1?0:rect.top-1;
  1234. int bottomborder=rect.bottom>pPic->bmHeight-1?pPic->bmHeight:rect.bottom+1;
  1235. for (i=leftborder;i<rightborder;i++)
  1236. {
  1237. p1[topborder*pPic->bmWidthBytes+i*3]=0;
  1238. p1[topborder*pPic->bmWidthBytes+i*3+1]=0;
  1239. p1[topborder*pPic->bmWidthBytes+i*3+2]=255;
  1240. p1[bottomborder*pPic->bmWidthBytes+i*3]=0;
  1241. p1[bottomborder*pPic->bmWidthBytes+i*3+1]=0;
  1242. p1[bottomborder*pPic->bmWidthBytes+i*3+2]=255;
  1243. }
  1244. for (i=topborder;i<bottomborder;i++)
  1245. {
  1246. p1[i*pPic->bmWidthBytes+leftborder*3]=0;
  1247. p1[i*pPic->bmWidthBytes+leftborder*3+1]=0;
  1248. p1[i*pPic->bmWidthBytes+leftborder*3+2]=255;
  1249. p1[i*pPic->bmWidthBytes+rightborder*3]=0;
  1250. p1[i*pPic->bmWidthBytes+rightborder*3+1]=0;
  1251. p1[i*pPic->bmWidthBytes+rightborder*3+2]=255;
  1252. }
  1253. }
  1254. int CLivenessDetectionFSM::StartLivenessDetection()
  1255. {
  1256. if (m_nCaptureType!=-1 /*&& m_nCaptureType!=nCaptureType*/)
  1257. {
  1258. StopLivenessDetection();
  1259. m_nCaptureType=-1;
  1260. }
  1261. m_nCaptureType=nCaptureType;
  1262. if (m_nCaptureType == CAPTURE_TYPE_ACTIVE_WITH_LIVENESS ||
  1263. m_nCaptureType == CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS)
  1264. {
  1265. Dbg("主动人像捕获中...");
  1266. }
  1267. else
  1268. {
  1269. Dbg("人像捕获中...");
  1270. }
  1271. int rtn=YituLiveSDK::YituStartCapture(m_nCaptureType);
  1272. if (rtn!=FUNCTION_RTN_SUCC)
  1273. {
  1274. Dbg("StartCapture(CAPTURE_TYPE_%d) failed!(%d)",m_nCaptureType,rtn);
  1275. m_bHasLiveTask=false;
  1276. return 1;
  1277. }
  1278. else
  1279. {
  1280. if (m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITH_LIVENESS ||
  1281. m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS)
  1282. {
  1283. //LogEvent(Severity_Middle,LOG_EVT_STARTACTIVECAPTURE,"0@0@0@0@1792@40@896@896"); // for standvtm notify iebrowser and chh(sipphone)
  1284. ActiveDetectionStarted evt;
  1285. CLivenessDetectionEntity *pDetection = dynamic_cast<CLivenessDetectionEntity *>(m_pEntity);
  1286. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  1287. if (!(ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType))
  1288. {
  1289. //evt.Param="0@0@0@0@1792@40@896@896";
  1290. evt.Param="0@0@0@0@1838@290@600@600";
  1291. }
  1292. else
  1293. {
  1294. evt.Param="0@0@0@0@711@275@500@500"; // pad或低柜双屏回显位置
  1295. }
  1296. SpSendBroadcast(pDetection->GetFunction(),SP_MSG_OF(ActiveDetectionStarted),SP_MSG_SIG_OF(ActiveDetectionStarted),evt);
  1297. Dbg("[dbg]: ActiveDetectionStarted has broadcasted.");
  1298. }
  1299. else if (m_nCaptureType==CAPTURE_TYPE_PASSIVE)
  1300. {
  1301. m_uid=CUUID::Create(m_uid);
  1302. Dbg("NEW Liveness SessionID=%s",m_uid.ToString());
  1303. }
  1304. m_bCameraThreadRun=true;
  1305. m_bThreadRun=true;
  1306. m_bUpdateScreen=true;
  1307. m_nLastFrame=0;
  1308. m_nSeconds=0;
  1309. m_bHasData0=false;
  1310. m_bHasData1=false;
  1311. strLastStatus="";
  1312. strStatus="";
  1313. ResetEvent(m_hEventWait); // add by ly
  1314. ResetEvent(m_hEventTask);
  1315. m_StartCtx=NULL;
  1316. if (!m_videoqueue1)
  1317. {
  1318. m_hCameraThread0=(HANDLE)_beginthreadex(NULL,0,CameraThread0,this,0,NULL);
  1319. m_hCameraThread1=NULL;
  1320. m_hDetectThread=(HANDLE)_beginthreadex(NULL,0,SingleCameraDetectThread,this,0,NULL);
  1321. }
  1322. else
  1323. {
  1324. m_hCameraThread0=(HANDLE)_beginthreadex(NULL,0,CameraThread0,this,0,NULL);
  1325. m_hCameraThread1=(HANDLE)_beginthreadex(NULL,0,CameraThread1,this,0,NULL);
  1326. m_hDetectThread=(HANDLE)_beginthreadex(NULL,0,DetectThread,this,0,NULL);
  1327. }
  1328. }
  1329. return 0;
  1330. }
  1331. void CLivenessDetectionFSM::StopLivenessDetection()
  1332. {
  1333. SetEvent(m_hEventWait); // add by ly at 20160630
  1334. if (m_hDetectThread!=0)
  1335. {
  1336. m_bThreadRun=false;
  1337. WaitForSingleObject(m_hDetectThread,2000);
  1338. }
  1339. if (m_hCameraThread0!=0 ||m_hCameraThread1!=0)
  1340. {
  1341. m_bCameraThreadRun=false;
  1342. WaitForSingleObject(m_hCameraThread0,2000);
  1343. WaitForSingleObject(m_hCameraThread1,2000);
  1344. }
  1345. if (m_nCaptureType==CAPTURE_TYPE_PASSIVE)
  1346. {
  1347. int nCount=0;
  1348. Dbg("[dbg] begin to call YituGetLiveImageCount.");
  1349. int rtn=YituLiveSDK::YituGetLiveImageCount(&nCount);
  1350. Dbg("[dbg] end to call YituGetLiveImageCount.");
  1351. if (rtn==0)
  1352. {
  1353. Dbg("捕获到%d个活体人像",nCount);
  1354. int n = (nCount < 10 ? nCount : 10);
  1355. if (n > 0)
  1356. {
  1357. char szPhoto[MAX_PATH]={0};
  1358. BYTE *pBuf = new BYTE[n*m_nImageSize];
  1359. int lens[10] = {0};
  1360. int offset = 0;
  1361. int nLive = 0, nHack = 0, nNoSure = 0;
  1362. int nImageIndex = 0;
  1363. for (int i=0;i<n;i++)
  1364. {
  1365. BITMAP bitmap;
  1366. bitmap.bmBits=NULL;
  1367. int nLiveType=LIVENESSTYPE_NOT_SURE;
  1368. Dbg("[dbg] begin to call YituGetLiveImage.");
  1369. rtn=YituLiveSDK::YituGetLiveImage(i,&bitmap,&nLiveType);
  1370. Dbg("[dbg] end to call YituGetLiveImage.");
  1371. if (rtn==0 && bitmap.bmBits!=NULL)
  1372. {
  1373. if (m_bSaveLivenessResult&&m_LivenessResultPath.GetLength()>0)
  1374. {
  1375. sprintf(szPhoto,"%s%s_Passive_%d_%d.jpg",(LPCTSTR)pFsm->m_LivenessResultPath,
  1376. (LPCTSTR)pFsm->m_uid.ToString(),nLiveType,nImageIndex++);
  1377. SaveLivenessPhoto(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,szPhoto);
  1378. }
  1379. if (nLiveType==LIVENESSTYPE_LIVE)
  1380. {
  1381. ++nLive;
  1382. int size=3*bitmap.bmWidth*bitmap.bmHeight;
  1383. char *pJpg=new char[size];
  1384. int nJpgSize=0;
  1385. RGB2JPG(bitmap.bmBits,bitmap.bmWidth,bitmap.bmHeight,&nJpgSize,pJpg,pDetection);
  1386. if (nJpgSize)
  1387. {
  1388. lens[i] = nJpgSize;
  1389. memcpy(pBuf+offset,pJpg,lens[i]);
  1390. }
  1391. delete []pJpg; pJpg=NULL;
  1392. }
  1393. else if (nLiveType==LIVENESSTYPE_HACK)
  1394. {
  1395. ++nHack;
  1396. lens[i] = 0;
  1397. }
  1398. else if (nLiveType==LIVENESSTYPE_NOT_SURE)
  1399. {
  1400. ++nNoSure;
  1401. lens[i] = 0;
  1402. }
  1403. }
  1404. else
  1405. {
  1406. Dbg("[YituGetLiveImage] rtn!=0 or bitmap.bmBits==NULL!");
  1407. lens[i] = 0;
  1408. }
  1409. offset += lens[i];
  1410. }
  1411. Dbg("[dbg] nLive=%d,nHack=%d,nNoSure=%d!",nLive,nHack,nNoSure);
  1412. char lenstr[MAX_PATH] = "", tmpstr[32] = "";
  1413. int size = 0;
  1414. for (int i=0;i<nLive;i++)
  1415. {
  1416. if (lens[i]!=0)
  1417. {
  1418. sprintf(tmpstr,"%d",lens[i]);
  1419. strcat(lenstr,tmpstr);
  1420. }
  1421. if (i<nLive-1)
  1422. strcat(lenstr,"|");
  1423. size += lens[i];
  1424. }
  1425. // send to rvcweb
  1426. if (m_StopCtx!=NULL) // edit by ly @2018/04/12
  1427. {
  1428. m_StopCtx->Ans.ActionID=CSimpleStringA2W(m_uid.ToString());
  1429. if (!m_bLoosePassiveStrategy)
  1430. {
  1431. if (nHack>0) // 有攻击就不过
  1432. {
  1433. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("N");
  1434. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1435. }
  1436. else if (nLive>0&&nNoSure==0) // 全活体则过
  1437. {
  1438. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("Y");
  1439. Dbg("LivePhotosLength=%s",lenstr);
  1440. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W(lenstr);
  1441. CBlob *pImagesData=&m_StopCtx->Ans.LivePhotosData;
  1442. pImagesData->Alloc(size);
  1443. memmove(pImagesData->m_pData,pBuf,size);
  1444. pImagesData->Resize(size);
  1445. }
  1446. else // 不确定
  1447. {
  1448. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("X");
  1449. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1450. }
  1451. }
  1452. else
  1453. {
  1454. if (nLive>0) // 有活体就通过
  1455. {
  1456. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("Y");
  1457. Dbg("LivePhotosLength=%s",lenstr);
  1458. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W(lenstr);
  1459. CBlob *pImagesData=&m_StopCtx->Ans.LivePhotosData;
  1460. pImagesData->Alloc(size);
  1461. memmove(pImagesData->m_pData,pBuf,size);
  1462. pImagesData->Resize(size);
  1463. }
  1464. else if (nHack>0&&nNoSure==0) // 全攻击则不过
  1465. {
  1466. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("N");
  1467. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1468. }
  1469. else // 不确定
  1470. {
  1471. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("X");
  1472. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1473. }
  1474. }
  1475. }
  1476. delete[] pBuf; pBuf = NULL;
  1477. }
  1478. else
  1479. {
  1480. // send to rvcweb
  1481. if (m_StopCtx!=NULL)
  1482. {
  1483. m_StopCtx->Ans.ActionID=CSimpleStringA2W(m_uid.ToString());
  1484. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("X");
  1485. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1486. }
  1487. }
  1488. }
  1489. else
  1490. {
  1491. // send to rvcweb
  1492. if (m_StopCtx!=NULL)
  1493. {
  1494. m_StopCtx->Ans.ActionID=CSimpleStringA2W(m_uid.ToString());
  1495. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("X");
  1496. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1497. }
  1498. }
  1499. }
  1500. else if (m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITH_LIVENESS ||
  1501. m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS)
  1502. {
  1503. //do nothing here
  1504. }
  1505. else // multiple stop
  1506. {
  1507. // send to rvcweb
  1508. if (m_StopCtx!=NULL)
  1509. {
  1510. m_StopCtx->Ans.ActionID=CSimpleStringA2W(m_uid.ToString());
  1511. m_StopCtx->Ans.VerifyResult=CSimpleStringA2W("X");
  1512. m_StopCtx->Ans.LivePhotosLength=CSimpleStringA2W("");
  1513. }
  1514. }
  1515. Dbg("[dbg] begin to call YituStopCapture.");
  1516. YituLiveSDK::YituStopCapture();
  1517. Dbg("[dbg] end to call YituStopCapture.");
  1518. if (m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITH_LIVENESS ||
  1519. m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS)
  1520. {
  1521. if (m_StartCtx==NULL||!m_StartCtx->Req.IsActive)
  1522. {
  1523. ::Sleep(50); // 50ms后发出主动活体结束广播
  1524. //LogEvent(Severity_Middle,LOG_EVT_STOPACTIVECAPTURE,"looklowerscreen.jpg"); // notify iebrowser and chh(sipphone)
  1525. ActiveDetectionStopped evt;
  1526. CLivenessDetectionEntity *pDetection = dynamic_cast<CLivenessDetectionEntity *>(m_pEntity);
  1527. DeviceTypeEnum deviceType = pDetection->GetDeviceType();
  1528. if (!(ePadtype==deviceType||eMobilePadType==deviceType||eDesk2SType==deviceType))
  1529. {
  1530. evt.Param="looklowerscreen.jpg";
  1531. m_bLookLowerScreen=true;
  1532. }
  1533. SpSendBroadcast(pDetection->GetFunction(),SP_MSG_OF(ActiveDetectionStopped),SP_MSG_SIG_OF(ActiveDetectionStopped),evt);
  1534. Dbg("[dbg]: ActiveDetectionStopped has broadcasted.");
  1535. }
  1536. else
  1537. {
  1538. Dbg("[dbg]: A new active task has come in!");
  1539. }
  1540. }
  1541. /*m_nCaptureType=-1;*/
  1542. }
  1543. BOOL CLivenessDetectionFSM::SaveLiveConfig(SpReqAnsContext<LivenessDetectionService_StartLivenessDetection_Req, LivenessDetectionService_StartLivenessDetection_Ans>::Pointer ctx)
  1544. {
  1545. // 是否是主动捕获,主动捕获是否做活体检测
  1546. bool bActiveCapture=false, bDoActiveDetect=false;
  1547. bActiveCapture=ctx->Req.IsActive;
  1548. bDoActiveDetect=CSimpleStringW2A(ctx->Req.Reserved)=="Y"?true:false;
  1549. Dbg("[dbg] bActiveCapture=%d, bDoActiveDetect=%d.",bActiveCapture,bDoActiveDetect);
  1550. nCaptureType=CAPTURE_TYPE_PASSIVE;
  1551. if (bActiveCapture)
  1552. {
  1553. nCaptureType=bDoActiveDetect?CAPTURE_TYPE_ACTIVE_WITH_LIVENESS:CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS;
  1554. }
  1555. /*m_ActionID=(LPCTSTR)CSimpleStringW2A(ctx->Req.ActionID);*/
  1556. return TRUE;
  1557. }
  1558. void CLivenessDetectionFSM::StartLiveDetect( SpReqAnsContext<LivenessDetectionService_StartLivenessDetection_Req, LivenessDetectionService_StartLivenessDetection_Ans>::Pointer ctx )
  1559. {
  1560. m_StartCtx = ctx;
  1561. if (m_bHasLiveTask || strcmp(GetCurrStateName(),"Normal") || m_bLookLowerScreen)
  1562. {
  1563. Dbg("GetCurrStateName:%s",GetCurrStateName());
  1564. Dbg("[dbg]: Waiting for the last live task terminate...");
  1565. WaitCaptureFinishTask *task = new WaitCaptureFinishTask(this);
  1566. m_pEntity->GetFunction()->PostThreadPoolTask(task);
  1567. }
  1568. else
  1569. {
  1570. ctx->Answer(Error_Succeed);
  1571. PostEventFIFO(new FSMEvent(USER_EVT_STARTCAPTURE));
  1572. }
  1573. }
  1574. void CLivenessDetectionFSM::SetActiveStopLiveDetect( SpReqAnsContext<LivenessDetectionService_StopLivenessDetection_Req, LivenessDetectionService_StopLivenessDetection_Ans>::Pointer ctx )
  1575. {
  1576. m_StopCtx = ctx;
  1577. //m_bActiveStop = true;
  1578. PostEventFIFO(new FSMEvent(USER_EVT_STOPCAPTURE));
  1579. }
  1580. void CLivenessDetectionFSM::NotifyCameraFault()
  1581. {
  1582. if (m_bHasLiveTask)
  1583. {
  1584. StopLivenessDetection(); // 停止活体 抛出异常
  1585. DetectionStopUnExpected evt;
  1586. evt.ActionID=CSimpleStringA2W(m_uid.ToString());
  1587. evt.IsActive=(m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITHOUT_LIVENESS||m_nCaptureType==CAPTURE_TYPE_ACTIVE_WITH_LIVENESS?true:false);
  1588. evt.ErrorCode=CSimpleStringA2W("Error_CameraFault");
  1589. evt.ErrorMsg=CSimpleStringA2W("摄像头故障,捕获已终止!");
  1590. PostEventFIFO(new FSMEvent(USER_EVT_CAPTURE_FINISHED));
  1591. SpSendBroadcast(pDetection->GetFunction(),SP_MSG_OF(DetectionStopUnExpected),SP_MSG_SIG_OF(DetectionStopUnExpected),evt);
  1592. Dbg("[dbg]: DetectionStopUnExpected has broadcasted.");
  1593. }
  1594. }