mod_facetracking.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "..\\mod_assistantchannel\\AssistantChannel_client_g.h"
  5. using namespace AssistantChannel;
  6. #include "..\\mod_AssistantChannel\\chan_protocol.h"
  7. #include "rec_common.h"
  8. #include "libvideoqueue.h"
  9. #include "jpeg2k.h"
  10. #include "libfacecapture.h"
  11. #include "y2k_time.h"
  12. #include "sysvar.h"
  13. #include "Event.h"
  14. // 脸部跟踪&拍照 devel: 0x302
  15. class CFaceTrackingEntity;
  16. class ChannelClient : public ChannelService_ClientBase
  17. {
  18. public:
  19. ChannelClient(CFaceTrackingEntity *pEntity);
  20. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData);
  21. };
  22. class CFaceTrackingEntity : public CEntityBase, public CHostApi , public CVideoMonitorEvent, public ISysVarListener, public ITimerListener,public ILogListener
  23. {
  24. public:
  25. CFaceTrackingEntity() : m_facecapture(NULL), bIsSessionChange(FALSE),strCustomerID(false),strSessionID(false),bIsCustomerChange(FALSE)
  26. {
  27. // note: this object initialize at DllMain, so it suggests keep your code simple here.
  28. // 1) do simple initializing here
  29. // 2) dont do complex operation, complex operation such as create new process(thread) and so on
  30. }
  31. virtual ~CFaceTrackingEntity() {}
  32. virtual const char *GetEntityName() const { return "FaceTracking"; }
  33. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  34. {
  35. LOG_FUNCTION();
  36. //MessageBoxA(0,0,0,0);
  37. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  38. ErrorCodeEnum Error;
  39. BOOL bRet = FALSE;
  40. m_facecapture = new Clibfacecapture(&bRet, this, this, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE, REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
  41. if (!bRet)
  42. {
  43. Dbg("load libface capture failed!");
  44. pTransactionContext->SendAnswer(Error_Resource);
  45. return;
  46. }
  47. Dbg("load libface capture ok!");
  48. #if 0
  49. m_pChannelClient = new ChannelClient(this);
  50. Error = m_pChannelClient->Connect();
  51. if (Error != Error_Succeed) {
  52. m_pChannelClient->SafeDelete();
  53. pTransactionContext->SendAnswer(Error);
  54. return;
  55. }
  56. ChannelService_BeginRecv_Sub Sub;
  57. Sub.type = ACM_TYPE_PHT;
  58. Error = m_pChannelClient->BeginRecv(Sub);
  59. if (Error != Error_Succeed) {
  60. m_pChannelClient->GetFunction()->CloseSession();
  61. m_pChannelClient->SafeDelete();
  62. m_pChannelClient = NULL;
  63. pTransactionContext->SendAnswer(Error);
  64. return;
  65. }
  66. #endif
  67. Error = GetFunction()->RegistSysVarEvent("SessionID", this);
  68. if (Error != Error_Succeed)
  69. {
  70. LOG_TRACE("register sysvar %s failed!", "SessionID");
  71. }
  72. Error = GetFunction()->RegistSysVarEvent("CustomerID", this);
  73. if (Error != Error_Succeed)
  74. {
  75. LOG_TRACE("register sysvar %s failed!", "CustomerID");
  76. }
  77. Error = GetFunction()->RegistSysVarEvent("CameraState", this);
  78. if (Error != Error_Succeed)
  79. {
  80. LOG_TRACE("register sysvar %s failed!", "CameraState");
  81. }
  82. CSimpleStringA strValue;
  83. GetFunction()->GetSysVar("CameraState", strValue);
  84. if (strValue[0] == 'N')
  85. {
  86. m_facecapture->SetCameraState(0);
  87. Dbg("set Camera State to 0");
  88. }
  89. else if (strValue[0] == 'E')
  90. {
  91. m_facecapture->SetCameraState(1);
  92. Dbg("set Camera State to 1");
  93. }
  94. else if (strValue[0] == 'O')
  95. {
  96. m_facecapture->SetCameraState(2);
  97. Dbg("set Camera State to 2");
  98. }
  99. else if (strValue[0] == 'B')
  100. {
  101. m_facecapture->SetCameraState(3);
  102. Dbg("set Camera State to 3");
  103. }
  104. //is Pad Version
  105. CSystemStaticInfo stStaticinfo;
  106. spFunction->GetSystemStaticInfo(stStaticinfo);
  107. if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
  108. {
  109. m_bIsPadType = TRUE;
  110. }
  111. else
  112. {
  113. m_bIsPadType = FALSE;
  114. }
  115. //int nCount;
  116. //Error = DecideCameraCount(nCount);
  117. //if (Error != Error_Succeed)
  118. //{
  119. // LOG_TRACE("decide camera count failed!");
  120. //}
  121. //Dbg("camera count:%d", nCount);
  122. if (!m_bIsPadType)
  123. {
  124. spFunction->SetTimer(1, this, 500);
  125. }
  126. spFunction->SubscribeLog(m_UUid1, this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_HEADLIGHT_GREEN_OFF,NULL,false);
  127. spFunction->SubscribeLog(m_UUid2, this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_BEGIN_RECORD,NULL,false);
  128. spFunction->SubscribeLog(m_UUid3, this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_END_RECORD,NULL,false);
  129. pTransactionContext->SendAnswer(Error);
  130. }
  131. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  132. {
  133. LOG_FUNCTION();
  134. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  135. spFunction->KillTimer(1); // if timer 1 not exist also ok
  136. delete m_facecapture;
  137. m_facecapture = NULL;
  138. spFunction->UnsubscribeLog(m_UUid1);
  139. spFunction->UnsubscribeLog(m_UUid2);
  140. spFunction->UnsubscribeLog(m_UUid3);
  141. spFunction->UnregistSysVarEvent("SessionID");
  142. spFunction->UnregistSysVarEvent("CustomerID");
  143. spFunction->UnregistSysVarEvent("CameraState");
  144. pTransactionContext->SendAnswer(Error_Succeed);
  145. }
  146. virtual void OnPaused()
  147. {
  148. Capture(0);
  149. }
  150. void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  151. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  152. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
  153. {
  154. if (dwUserCode == LOG_EVT_HEADLIGHT_GREEN_OFF)
  155. {
  156. Dbg("set light change");
  157. m_facecapture->SetLightChange();
  158. }
  159. else if (dwUserCode == EVENT_MOD_BEGIN_RECORD)
  160. {
  161. CSimpleStringA strValue;
  162. GetFunction()->GetSysVar("CameraState", strValue);
  163. if (strValue[0] == 'N')
  164. {
  165. m_facecapture->SetCameraState(0);
  166. Dbg("Begin start Camera,set Camera State to 0");
  167. }
  168. else if (strValue[0] == 'E')
  169. {
  170. m_facecapture->SetCameraState(1);
  171. Dbg("Begin start Camera,set Camera State to 1");
  172. }
  173. else if (strValue[0] == 'O')
  174. {
  175. m_facecapture->SetCameraState(2);
  176. Dbg("Begin start Camera,set Camera State to 2");
  177. }
  178. else if (strValue[0] == 'B')
  179. {
  180. m_facecapture->SetCameraState(3);
  181. Dbg("Begin start Camera,set Camera State to 3");
  182. }
  183. }
  184. else if (dwUserCode == EVENT_MOD_END_RECORD)
  185. {
  186. Dbg(" stop Camera,set camera stat to Error");
  187. m_facecapture->SetCameraState(3);
  188. }
  189. }
  190. void Capture(int id)
  191. {
  192. #if 0
  193. CImageFrame frm;
  194. frm.data = new unsigned char[REC_COMMON_VIDEO_SNAPSHOT_WIDTH*REC_COMMON_VIDEO_SNAPSHOT_HEIGHT*4];
  195. frm.width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  196. frm.height = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  197. frm.framesize = frm.width * frm.height * 3;
  198. if (m_facecapture->SnapShot(frm)) {
  199. Dbg("get video frm ok!");
  200. int rc;
  201. jpeg2k_raw_image raw_image;
  202. jpeg2k_coded_image codec_image = {0};
  203. raw_image.data = frm.data;
  204. raw_image.width = frm.width;
  205. raw_image.height = frm.height;
  206. raw_image.len = raw_image.width * raw_image.height * 3;
  207. rc = jpeg2k_encode(&raw_image, &codec_image, 10);
  208. if (rc == 0) {
  209. ChannelService_Send_Info Info;
  210. Info.compress = false;
  211. Info.encrypt = false;
  212. Info.type = ACM_TYPE_PHT;
  213. Info.id = id;
  214. Info.sub_type = ACM_PHT_ANS | ACM_PHT_SNAPSHOT;
  215. Info.data.m_pData = codec_image.data;
  216. Info.data.m_iLength = codec_image.len;
  217. m_pChannelClient->Send(Info);
  218. }
  219. jpeg2k_encode_free(&codec_image);
  220. } else {
  221. Dbg("get video frm failed!");
  222. }
  223. delete frm.data;
  224. #endif
  225. }
  226. //////////////////////////////////////////////////////////////////////////////////////////////////////
  227. // ITimerListener implementation
  228. virtual void OnTimeout(DWORD dwTimerID)
  229. {
  230. //LOG_FUNCTION();
  231. __int64 uid;
  232. CCustomerStatus status;
  233. //Dbg("before GetMainCustomerStatus");
  234. if (m_facecapture->GetMainCustomerStatus(uid, status))
  235. {
  236. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  237. CSimpleStringA strValue;
  238. //Dbg("OnTimeout, check value, eCamera = %d", status.stCustomerPos.eCamera);
  239. spFunction->GetSysVar(SYSVAR_ACTIVETRACKINGCAMERA, strValue); // E or O
  240. if (status.stCustomerPos.eCamera == EnvironCamera)
  241. {
  242. if (strValue[0] == 'O')
  243. {
  244. //Dbg("ActiveTrackingCamera change from Opt->Env!");
  245. spFunction->SetSysVar(SYSVAR_ACTIVETRACKINGCAMERA, ACTIVETRACKINGCAMERA_ENV); // from Operation -> Environment
  246. }
  247. }
  248. else
  249. {
  250. if (strValue[0] == 'E')
  251. {
  252. //Dbg("ActiveTrackingCamera change from Env->Opt!");
  253. spFunction->SetSysVar(SYSVAR_ACTIVETRACKINGCAMERA, ACTIVETRACKINGCAMERA_OPT); // from Environment -> Operation
  254. }
  255. }
  256. } else
  257. {
  258. Dbg("GetMainCustomerStatus failed!");
  259. }
  260. }
  261. //////////////////////////////////////////////////////////////////////////////////////////////////////
  262. // CHostApi implementation
  263. virtual unsigned __int64 GenerateUUID()
  264. {
  265. m_lastUUID = CUUID::Create(m_lastUUID);
  266. return m_lastUUID;
  267. }
  268. virtual BOOL IsCustomerChange()
  269. {
  270. BOOL bChange = bIsSessionChange||bIsCustomerChange;
  271. return bChange;
  272. }
  273. virtual void GetFaceImgName(char* FaceName)
  274. {
  275. CSimpleStringA strPath;
  276. ErrorCodeEnum Error = GetFunction()->GetPath("UploadPhoto", strPath);
  277. if (Error == Error_Succeed)
  278. {
  279. if (((const char*)strCustomerID == NULL)||(_stricmp(strCustomerID,"N") == 0))
  280. {
  281. sprintf(FaceName, "%s\\%s_0", (LPCSTR)strPath, strSessionID);
  282. }
  283. else
  284. {
  285. sprintf(FaceName, "%s\\%s_%s", (LPCSTR)strPath, strSessionID,strCustomerID);
  286. }
  287. //Debug("get file name =%s",FaceName);
  288. bIsSessionChange = FALSE;
  289. bIsCustomerChange = FALSE;
  290. }
  291. else
  292. {
  293. Dbg("getpath uploadphoto failed!");
  294. }
  295. }
  296. virtual BOOL LoadConfig(CFaceCaptureConfig &config)
  297. {
  298. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  299. CSmartPointer<IConfigInfo> spConfig;
  300. ErrorCodeEnum Error = spFunction->OpenConfig(Config_Software, spConfig);
  301. if (Error == Error_Succeed) {
  302. SpIniMappingTable table;
  303. CSimpleStringA strPath;
  304. config.nServersType = 0;
  305. GetFunction()->GetPath("cfg", strPath);
  306. strcpy(config.strFaceDataDirPath, strPath);
  307. strcat(config.strFaceDataDirPath, "\\facedata");
  308. table.AddEntryInt("general", "PrimCamera", config.nPrimCamera, 0);
  309. table.AddEntryInt("general", "ContourMinAera", config.nContourMinAera, 0);
  310. table.AddEntryInt("general", "UpCameraEdgeLimit", config.nUpCameraEdgeLimit, 0);
  311. table.AddEntryInt("general", "DownCameraEdgeLimit", config.nDownCameraEdgeLimit, 0);
  312. table.AddEntryString("general", "FaceDataDirPath", strPath, 0);
  313. table.AddEntryFloat("general", "OperateFaceSize", config.fOperateFaceSize, 0.0f);
  314. table.AddEntryFloat("general", "CloseFaceSize", config.fCloseFaceSize, 0.0f);
  315. table.AddEntryFloat("general", "FarFaceSize", config.fFarFaceSize, 0.0f);
  316. table.AddEntryFloat("general", "SearchFaceSize", config.fSearchFaceSize, 0.0f);
  317. table.AddEntryFloat("general", "DetectFaceSize", config.fDetectFaceSize, 0.0f);
  318. table.AddEntryInt("general", "FaceSizeOffset", config.nFaceSizeOffset, 0);
  319. table.AddEntryInt("general", "SleepLong", config.nSleepLong, 0);
  320. table.AddEntryInt("general", "SleepMiddle", config.nSleepMiddle, 0);
  321. table.AddEntryInt("general", "SleepShort", config.nSleepShort, 0);
  322. table.AddEntryInt("general", "ThresholdNum", config.nThresholdNum, 0);
  323. Error = table.Load(spConfig);
  324. }
  325. return Error == Error_Succeed;
  326. }
  327. virtual void Debug(const char *fmt, ...)
  328. {
  329. va_list arg;
  330. va_start(arg, fmt);
  331. vDbg(fmt, arg);
  332. va_end(arg);
  333. }
  334. ////////////////////////////////////////////////////////////////////////////////////
  335. // CVideoMonitorEvent
  336. virtual void GenerateCloseEvent()
  337. {
  338. LogEvent(Severity_Middle, 0x30200001, "客户接近 1.5m");
  339. }
  340. virtual void GenerateLeaveEvent()
  341. {
  342. LogEvent(Severity_Middle, 0x30200002, "客户消失或退出到接近距离1.5M之外");
  343. }
  344. virtual void GenerateEnterOperateEvent()
  345. {
  346. LogEvent(Severity_Middle, 0x30200003, "客户进入操作距离0.5m");
  347. }
  348. virtual void GenerateBackToCloseEvent()
  349. {
  350. LogEvent(Severity_Middle, 0x30200004, "客户退回到接近距离");
  351. }
  352. virtual void GenerateAppearEvent() //有人出现在视野中
  353. {
  354. LogEvent(Severity_Middle, 0x30200006, "有人出现");
  355. }
  356. virtual void GenerateCustomerChangeEvent()
  357. {
  358. LogEvent(Severity_Middle, 0x30200005, "客户已经换人");
  359. }
  360. virtual void GenerateCaptureFaceEvent()
  361. {
  362. LogEvent(Severity_Middle, 0x30200011, "捕获脸部事件");
  363. }
  364. virtual void GenerateLoseFaceEvent()
  365. {
  366. LogEvent(Severity_Middle, 0x30200012, "失去脸部事件");
  367. }
  368. virtual void GenerateFaceCaptureFC()
  369. {
  370. //发送最高等级错误事件,由健康模块重启对应实体
  371. LogEvent(Severity_High,EVENT_MOD_FACE_BREAKDOWN,"the opencv library breakdown");
  372. }
  373. private:
  374. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
  375. {
  376. if (_stricmp(pszKey,"SessionID") == 0)
  377. {
  378. GetFunction()->GetSysVar("SessionID",strSessionID);
  379. //Dbg("sessionID change to %s",strSessionID);
  380. bIsSessionChange = TRUE;
  381. }
  382. if (_stricmp(pszKey,"CustomerID") == 0)
  383. {
  384. GetFunction()->GetSysVar("CustomerID",strCustomerID);
  385. //Dbg("customerID change to %s",strCustomerID);
  386. bIsCustomerChange = TRUE;
  387. }
  388. if (_stricmp(pszKey,"CameraState") == 0)
  389. {
  390. CSimpleStringA str;
  391. GetFunction()->GetSysVar("CameraState",str);
  392. //Dbg("customerID change to %s",strCustomerID);
  393. if (str == 'N')
  394. {
  395. m_facecapture->SetCameraState(0);
  396. Dbg("set Camera State to 0");
  397. }
  398. else if (str == 'E')
  399. {
  400. m_facecapture->SetCameraState(1);
  401. Dbg("set Camera State to 1");
  402. }
  403. else if (str == 'O')
  404. {
  405. m_facecapture->SetCameraState(2);
  406. Dbg("set Camera State to 2");
  407. }
  408. else if (str == 'B')
  409. {
  410. m_facecapture->SetCameraState(3);
  411. Dbg("set Camera State to 3");
  412. }
  413. }
  414. }
  415. // we use root.ini Video section config to decide camera count
  416. ErrorCodeEnum DecideCameraCount(int &nCount)
  417. {
  418. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  419. CSmartPointer<IConfigInfo> spConfig;
  420. ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spConfig);
  421. if (Error == Error_Succeed)
  422. {
  423. CSimpleStringA strVideoEnv;
  424. CSimpleStringA strVideoOpt;
  425. SpIniMappingTable table;
  426. nCount = 0;
  427. table.AddEntryString("Video", "EnvCamera", strVideoEnv, "$");
  428. table.AddEntryString("Video", "OptCamera", strVideoOpt, "$");
  429. Error = table.Load(spConfig);
  430. if (Error == Error_Succeed)
  431. {
  432. if (strVideoEnv.GetLength() > 1)
  433. nCount++;
  434. if (strVideoOpt.GetLength() > 1)
  435. nCount++;
  436. }
  437. }
  438. return Error;
  439. }
  440. private:
  441. CUUID m_UUid1,m_UUid2,m_UUid3;
  442. BOOL bIsSessionChange;
  443. BOOL bIsCustomerChange;
  444. BOOL m_bIsPadType;
  445. CSimpleStringA strCustomerID;
  446. CSimpleStringA strSessionID;
  447. CUUID m_lastUUID;
  448. ChannelClient *m_pChannelClient;
  449. Clibfacecapture *m_facecapture;
  450. };
  451. void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
  452. {
  453. LOG_FUNCTION();
  454. if (Error == Error_Succeed)
  455. {
  456. CFaceTrackingEntity *pEntity = static_cast<CFaceTrackingEntity*>(m_pEntityBase);
  457. int cat = ACM_PHT_CAT(Msg.sub_type);
  458. if (cat == ACM_PHT_REQ)
  459. {
  460. //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
  461. pEntity->Capture(Msg.id);
  462. //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  463. } else
  464. {
  465. _ASSERT(0);
  466. }
  467. }
  468. }
  469. ChannelClient::ChannelClient( CFaceTrackingEntity *pEntity ) : ChannelService_ClientBase(pEntity)
  470. {
  471. }
  472. SP_BEGIN_ENTITY_MAP()
  473. SP_ENTITY(CFaceTrackingEntity)
  474. SP_END_ENTITY_MAP()