mod_livenessdetection.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #include "mod_livenessdetection.h"
  2. #include "../mod_interactivecontrol/Event.h"
  3. //compile with VS2019 bcz jpeg.lib is compiled from VS2010 which lower version.
  4. #ifdef RVC_OS_WIN
  5. #pragma comment(lib, "legacy_stdio_definitions.lib")
  6. extern "C" {
  7. FILE __iob_func[3] = { *stdin, *stdout, *stderr };
  8. }
  9. #endif //RVC_OS_WIN
  10. static int __on_get_videodata(eVideoType eType, eCameraType ecameraid, int* width, int* height, unsigned char* bmpdata, int isize, void* user_data)
  11. {
  12. CLivenessDetectionEntity* pThis = static_cast<CLivenessDetectionEntity*>(user_data);
  13. int iret = pThis->on_get_videodata(eType, ecameraid, width, height, bmpdata, isize);
  14. return iret;
  15. }
  16. #ifdef RVC_OS_WIN
  17. static unsigned int __stdcall start_wsserver(void *arg)
  18. #else
  19. static void* start_wsserver(void* arg)
  20. #endif
  21. {
  22. CLivenessDetectionEntity* liveness_entity = (CLivenessDetectionEntity*)arg;
  23. websocket_callback_t t_callback = {0};
  24. t_callback.user_data = liveness_entity;
  25. t_callback.on_get_videodata = &__on_get_videodata;
  26. rvc_video_param_t t_param = {0};
  27. t_param.iwidth = REC_COMMON_VIDEO_PREVIEW_WIDTH;
  28. t_param.iheight = REC_COMMON_VIDEO_PREVIEW_HEIGHT;
  29. t_param.icapwidth = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  30. t_param.icapheight = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  31. int iRet = liveness_entity->GetWsServer()->Init_WsServer(&t_callback, &t_param, liveness_entity->GetWsPort());
  32. #ifdef RVC_OS_WIN
  33. return 0;
  34. #else
  35. return &iRet;
  36. #endif
  37. }
  38. CLivenessDetectionEntity::CLivenessDetectionEntity()
  39. {
  40. m_WsServer = new RvcWsServer();
  41. m_pFaceVideo = new RvcFaceVideo();
  42. m_iWsPort = RVC_LIVENESS_WS_PORT;
  43. #ifdef RVC_OS_WIN
  44. m_hWsServerThread = NULL;
  45. #else
  46. m_hWsServerThreadId = 0;
  47. #endif
  48. }
  49. CLivenessDetectionEntity::~CLivenessDetectionEntity()
  50. {
  51. if (m_WsServer){
  52. delete m_WsServer;
  53. m_WsServer = NULL;
  54. }
  55. #ifdef RVC_OS_WIN
  56. if (m_pFaceVideo){
  57. delete m_pFaceVideo;
  58. m_pFaceVideo = NULL;
  59. }
  60. DWORD exitCode = 0;
  61. if (m_hWsServerThread)
  62. {
  63. TerminateThread(m_hWsServerThread, exitCode);
  64. m_hWsServerThread = NULL;
  65. }
  66. #else
  67. pthread_cancel(m_hWsServerThreadId);
  68. if (0 == pthread_join(m_hWsServerThreadId, NULL)) {
  69. m_hWsServerThreadId = 0;
  70. }
  71. else {
  72. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join web socket server thread failed!");
  73. }
  74. #endif
  75. }
  76. const char * CLivenessDetectionEntity::GetEntityName() const
  77. {
  78. return "LivenessDetection";
  79. }
  80. void CLivenessDetectionEntity::OnPreStart( CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext )
  81. {
  82. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  83. pTransactionContext->SendAnswer(Error);
  84. }
  85. void CLivenessDetectionEntity::OnStarted()
  86. {
  87. if (Error_Succeed != GetEntityConfigure()){
  88. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[LivenessDetectionFSM] Get Entity Configure Failed!");
  89. }
  90. #ifdef RVC_OS_WIN
  91. m_hWsServerThread = (HANDLE)_beginthreadex(NULL, 0, &start_wsserver, this, 0, NULL);
  92. if (NULL == m_hWsServerThread){
  93. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create web socket server thread failed.");
  94. }
  95. #else
  96. if (GetCameraOnStatus()) {
  97. InitVideoQueueInfo();
  98. }
  99. if (0 != pthread_create(&m_hWsServerThreadId, NULL, start_wsserver, (void*)this)) {
  100. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create web socket server thread failed.");
  101. }
  102. #endif
  103. }
  104. void CLivenessDetectionEntity::OnPreClose( EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext )
  105. {
  106. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  107. pTransactionContext->SendAnswer(Error);
  108. }
  109. ErrorCodeEnum CLivenessDetectionEntity::__OnStart(ErrorCodeEnum preOperationError)
  110. {
  111. if (preOperationError != Error_Succeed) {
  112. return preOperationError;
  113. }
  114. m_eDeviceType = eStand2sType;
  115. //is Pad Version
  116. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  117. CSystemStaticInfo stStaticinfo;
  118. spFunction->GetSystemStaticInfo(stStaticinfo);
  119. if (_stricmp(stStaticinfo.strMachineType,"RVC.Stand1SPlus")==0) {
  120. m_eDeviceType = eStand1SPlusType;
  121. }
  122. else{
  123. m_eDeviceType = eStand2sType;
  124. }
  125. if (m_eDeviceType >= 0 && m_eDeviceType < sizeof(Device_Type_Table) / sizeof(char*)) {
  126. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[m_eDeviceType]);
  127. }
  128. ErrorCodeEnum Error = Error_Succeed;
  129. nActiveCamera = CAMERA_TYPE_ENV;
  130. m_iCameraState = 'N';
  131. #ifdef RVC_OS_WIN
  132. InitVideoQueueInfo();
  133. #endif
  134. int i = 0;
  135. m_arrListener.Init(2);
  136. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED, NULL, false);
  137. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED, NULL, false);
  138. GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA, this);
  139. GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE, this);
  140. CSimpleStringA strValue;
  141. GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue);
  142. m_iCameraState = strValue[0];
  143. if (strValue[0] == 'E'){
  144. nActiveCamera = CAMERA_TYPE_OPT;
  145. }
  146. else if (strValue[0] == 'O'){
  147. nActiveCamera = CAMERA_TYPE_ENV;
  148. }
  149. else if(strValue[0] == 'B') {
  150. nActiveCamera = CAMERA_TYPE_ERROR;
  151. }
  152. else if (strValue[0] == 'N'){
  153. nActiveCamera = CAMERA_TYPE_ENV;
  154. }
  155. return Error;
  156. }
  157. ErrorCodeEnum CLivenessDetectionEntity::__OnClose( ErrorCodeEnum preOperationError )
  158. {
  159. if (preOperationError != Error_Succeed) {
  160. return preOperationError;
  161. }
  162. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  163. for (int i = 0; i < m_arrListener.GetCount(); ++i){
  164. spFunction->UnsubscribeLog(m_arrListener[i]);
  165. }
  166. return Error_Succeed;
  167. }
  168. int CLivenessDetectionEntity::GetActiveCamera()
  169. {
  170. return nActiveCamera;
  171. }
  172. void CLivenessDetectionEntity::OnLog( const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext &pLinkInfo)
  173. {
  174. switch (dwUserCode)
  175. {
  176. case LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED:
  177. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED event");
  178. #ifdef RVC_OS_LINUX
  179. InitVideoQueueInfo();
  180. #endif
  181. break;
  182. case LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED:
  183. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED event");
  184. #ifdef RVC_OS_LINUX
  185. if (m_pFaceVideo){
  186. delete m_pFaceVideo;
  187. m_pFaceVideo = NULL;
  188. }
  189. #endif
  190. break;
  191. default:
  192. break;
  193. }
  194. }
  195. void CLivenessDetectionEntity::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
  196. {
  197. if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
  198. {
  199. m_iCameraState = pszValue[0];
  200. if (pszValue[0] == 'E')
  201. {
  202. nActiveCamera = CAMERA_TYPE_OPT;
  203. }
  204. else if (pszValue[0] == 'O')
  205. {
  206. nActiveCamera = CAMERA_TYPE_ENV;
  207. }
  208. else if(pszValue[0] == 'B') ///////显示贴图
  209. {
  210. nActiveCamera = CAMERA_TYPE_ERROR;
  211. }
  212. else if (pszValue[0] == 'N')
  213. {
  214. nActiveCamera = CAMERA_TYPE_AUTO;
  215. }
  216. }
  217. else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0)
  218. {
  219. if (m_iCameraState == 'N')
  220. {
  221. if (pszValue[0] == 'E')
  222. {
  223. nActiveCamera = CAMERA_TYPE_ENV;
  224. }
  225. else if (pszValue[0] == 'O')
  226. {
  227. nActiveCamera = CAMERA_TYPE_OPT;
  228. }
  229. }
  230. }
  231. }
  232. void CLivenessDetectionEntity::OnSelfTest( EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext )
  233. {
  234. if (Test_ShakeHand == eTestType)
  235. {
  236. pTransactionContext->SendAnswer(Error_Succeed);
  237. }
  238. }
  239. void CLivenessDetectionEntity::InitVideoQueueInfo()
  240. {
  241. if (!m_pFaceVideo) {
  242. m_pFaceVideo = new RvcFaceVideo();
  243. }
  244. if (eStand1SPlusType == m_eDeviceType) {
  245. m_pFaceVideo->InitVideoQueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE, NULL, REC_COMMON_VIDEO_ENV_SHM_PREVIEW_QUEUE, NULL);
  246. }
  247. else {
  248. m_pFaceVideo->InitVideoQueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE, REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_VIDEO_ENV_SHM_PREVIEW_QUEUE, REC_COMMON_VIDEO_OPT_SHM_PREVIEW_QUEUE);
  249. }
  250. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Init Video QueueInfo Success.");
  251. }
  252. bool CLivenessDetectionEntity::GetCameraOnStatus()
  253. {
  254. bool bRet = false;
  255. MediaControlClient* pMediaControlClient = new MediaControlClient(this);
  256. ErrorCodeEnum erroCode = pMediaControlClient->Connect();
  257. if (Error_Succeed != erroCode) {
  258. pMediaControlClient->SafeDelete();
  259. pMediaControlClient = NULL;
  260. }
  261. else {
  262. MediaService_IsCameraOnStatus_Req req;
  263. MediaService_IsCameraOnStatus_Ans ans;
  264. if (Error_Succeed == pMediaControlClient->IsCameraOnStatus(req, ans, 5000)) {
  265. bRet = ans.biscameraon;
  266. }
  267. pMediaControlClient->GetFunction()->CloseSession();
  268. pMediaControlClient = NULL;
  269. }
  270. return bRet;
  271. }
  272. int CLivenessDetectionEntity::on_get_videodata(eVideoType eType, eCameraType ecameraid, int* width, int* height, unsigned char* bmpdata, int isize)
  273. {
  274. int idatalen = 0;
  275. if (!m_pFaceVideo) {
  276. return idatalen;
  277. }
  278. if (ePreview_Type == eType) {
  279. idatalen = m_pFaceVideo->GetPreViewVideoFrameSize(ecameraid, width, height);
  280. }
  281. else{
  282. idatalen = m_pFaceVideo->GetVideoFrameSize(ecameraid, width, height);
  283. }
  284. if (0 < idatalen){
  285. video_frame vframe = {0};
  286. vframe.format = VIDEO_FORMAT_RGB24;
  287. vframe.width = *width;
  288. vframe.height = *height;
  289. videoq_frame qvframe = {0};
  290. qvframe.framesize = idatalen;
  291. qvframe.width = *width;
  292. qvframe.height = *height;
  293. qvframe.data = bmpdata;
  294. bool bRet = false;
  295. if (ePreview_Type == eType){
  296. int iPreviewflag = 3;
  297. #ifdef RVC_OS_WIN
  298. if (eCamera_Env == ecameraid){
  299. iPreviewflag = 1;
  300. }
  301. #endif
  302. bRet = m_pFaceVideo->GetPreViewVideoFrame((int)ecameraid, &qvframe, iPreviewflag);
  303. }
  304. else{
  305. int iCapflag = 2;
  306. #ifdef RVC_OS_WIN
  307. if (eCamera_Env == ecameraid){
  308. iCapflag = 0;
  309. }
  310. #endif
  311. bRet = m_pFaceVideo->GetVideoFrame((int)ecameraid, &qvframe, iCapflag);
  312. }
  313. if (!bRet){
  314. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get video frame from queue failed, and picture data length is %d.", idatalen);
  315. }
  316. }
  317. return idatalen;
  318. }
  319. ErrorCodeEnum CLivenessDetectionEntity::GetEntityConfigure()
  320. {
  321. CSmartPointer<IConfigInfo> spConfig;
  322. ErrorCodeEnum eErrDev;
  323. eErrDev = GetFunction()->OpenConfig(Config_CenterSetting, spConfig);
  324. if (eErrDev != Error_Succeed){
  325. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("open center setting file failed!");
  326. return eErrDev;
  327. }
  328. SpIniMappingTable table;
  329. int iWsPort = RVC_LIVENESS_WS_PORT;
  330. table.AddEntryInt("LivenessDetection","WsServerPort", iWsPort, RVC_LIVENESS_WS_PORT);
  331. eErrDev = table.Load(spConfig);
  332. if (Error_Succeed == eErrDev) {
  333. if (iWsPort > 0) {
  334. m_iWsPort = iWsPort;
  335. }
  336. }
  337. return eErrDev;
  338. }
  339. MediaControlClient::MediaControlClient(CLivenessDetectionEntity* pEntity) : MediaService_ClientBase(pEntity)
  340. {
  341. }
  342. SP_BEGIN_ENTITY_MAP()
  343. SP_ENTITY(CLivenessDetectionEntity)
  344. SP_END_ENTITY_MAP()