#include "mod_livenessdetection.h" #include "../mod_interactivecontrol/Event.h" //compile with VS2019 bcz jpeg.lib is compiled from VS2010 which lower version. #ifdef RVC_OS_WIN #pragma comment(lib, "legacy_stdio_definitions.lib") extern "C" { FILE __iob_func[3] = { *stdin, *stdout, *stderr }; } #endif //RVC_OS_WIN static int __on_get_videodata(eVideoType eType, eCameraType ecameraid, int* width, int* height, unsigned char* bmpdata, int isize, void* user_data) { CLivenessDetectionEntity* pThis = static_cast(user_data); int iret = pThis->on_get_videodata(eType, ecameraid, width, height, bmpdata, isize); return iret; } #ifdef RVC_OS_WIN static unsigned int __stdcall start_wsserver(void *arg) #else static void* start_wsserver(void* arg) #endif { CLivenessDetectionEntity* liveness_entity = (CLivenessDetectionEntity*)arg; websocket_callback_t t_callback = {0}; t_callback.user_data = liveness_entity; t_callback.on_get_videodata = &__on_get_videodata; rvc_video_param_t t_param = {0}; t_param.iwidth = REC_COMMON_VIDEO_PREVIEW_WIDTH; t_param.iheight = REC_COMMON_VIDEO_PREVIEW_HEIGHT; t_param.icapwidth = REC_COMMON_VIDEO_SNAPSHOT_WIDTH; t_param.icapheight = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT; int iRet = liveness_entity->GetWsServer()->Init_WsServer(&t_callback, &t_param, liveness_entity->GetWsPort()); #ifdef RVC_OS_WIN return 0; #else return &iRet; #endif } CLivenessDetectionEntity::CLivenessDetectionEntity() { m_WsServer = new RvcWsServer(); m_pFaceVideo = new RvcFaceVideo(); m_iWsPort = RVC_LIVENESS_WS_PORT; #ifdef RVC_OS_WIN m_hWsServerThread = NULL; #else m_hWsServerThreadId = 0; #endif } CLivenessDetectionEntity::~CLivenessDetectionEntity() { if (m_WsServer){ delete m_WsServer; m_WsServer = NULL; } #ifdef RVC_OS_WIN if (m_pFaceVideo){ delete m_pFaceVideo; m_pFaceVideo = NULL; } DWORD exitCode = 0; if (m_hWsServerThread) { TerminateThread(m_hWsServerThread, exitCode); m_hWsServerThread = NULL; } #else pthread_cancel(m_hWsServerThreadId); if (0 == pthread_join(m_hWsServerThreadId, NULL)) { m_hWsServerThreadId = 0; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join web socket server thread failed!"); } #endif } const char * CLivenessDetectionEntity::GetEntityName() const { return "LivenessDetection"; } void CLivenessDetectionEntity::OnPreStart( CAutoArray strArgs,CSmartPointer pTransactionContext ) { ErrorCodeEnum Error = __OnStart(Error_Succeed); pTransactionContext->SendAnswer(Error); } void CLivenessDetectionEntity::OnStarted() { if (Error_Succeed != GetEntityConfigure()){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[LivenessDetectionFSM] Get Entity Configure Failed!"); } #ifdef RVC_OS_WIN m_hWsServerThread = (HANDLE)_beginthreadex(NULL, 0, &start_wsserver, this, 0, NULL); if (NULL == m_hWsServerThread){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create web socket server thread failed."); } #else if (GetCameraOnStatus()) { InitVideoQueueInfo(); } if (0 != pthread_create(&m_hWsServerThreadId, NULL, start_wsserver, (void*)this)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create web socket server thread failed."); } #endif } void CLivenessDetectionEntity::OnPreClose( EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext ) { ErrorCodeEnum Error = __OnClose(Error_Succeed); pTransactionContext->SendAnswer(Error); } ErrorCodeEnum CLivenessDetectionEntity::__OnStart(ErrorCodeEnum preOperationError) { if (preOperationError != Error_Succeed) { return preOperationError; } m_eDeviceType = eStand2sType; //is Pad Version CSmartPointer spFunction = GetFunction(); CSystemStaticInfo stStaticinfo; spFunction->GetSystemStaticInfo(stStaticinfo); if (_stricmp(stStaticinfo.strMachineType,"RVC.Stand1SPlus")==0) { m_eDeviceType = eStand1SPlusType; } else{ m_eDeviceType = eStand2sType; } if (m_eDeviceType >= 0 && m_eDeviceType < sizeof(Device_Type_Table) / sizeof(char*)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[m_eDeviceType]); } ErrorCodeEnum Error = Error_Succeed; nActiveCamera = CAMERA_TYPE_ENV; m_iCameraState = 'N'; #ifdef RVC_OS_WIN InitVideoQueueInfo(); #endif int i = 0; m_arrListener.Init(2); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED, NULL, false); GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED, NULL, false); GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA, this); GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE, this); CSimpleStringA strValue; GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue); m_iCameraState = strValue[0]; if (strValue[0] == 'E'){ nActiveCamera = CAMERA_TYPE_OPT; } else if (strValue[0] == 'O'){ nActiveCamera = CAMERA_TYPE_ENV; } else if(strValue[0] == 'B') { nActiveCamera = CAMERA_TYPE_ERROR; } else if (strValue[0] == 'N'){ nActiveCamera = CAMERA_TYPE_ENV; } return Error; } ErrorCodeEnum CLivenessDetectionEntity::__OnClose( ErrorCodeEnum preOperationError ) { if (preOperationError != Error_Succeed) { return preOperationError; } CSmartPointer spFunction = GetFunction(); for (int i = 0; i < m_arrListener.GetCount(); ++i){ spFunction->UnsubscribeLog(m_arrListener[i]); } return Error_Succeed; } int CLivenessDetectionEntity::GetActiveCamera() { return nActiveCamera; } void CLivenessDetectionEntity::OnLog( const CAutoArray &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext &pLinkInfo) { switch (dwUserCode) { case LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED event"); #ifdef RVC_OS_LINUX InitVideoQueueInfo(); #endif break; case LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED event"); #ifdef RVC_OS_LINUX if (m_pFaceVideo){ delete m_pFaceVideo; m_pFaceVideo = NULL; } #endif break; default: break; } } void CLivenessDetectionEntity::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName ) { if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0) { m_iCameraState = pszValue[0]; if (pszValue[0] == 'E') { nActiveCamera = CAMERA_TYPE_OPT; } else if (pszValue[0] == 'O') { nActiveCamera = CAMERA_TYPE_ENV; } else if(pszValue[0] == 'B') ///////显示贴图 { nActiveCamera = CAMERA_TYPE_ERROR; } else if (pszValue[0] == 'N') { nActiveCamera = CAMERA_TYPE_AUTO; } } else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0) { if (m_iCameraState == 'N') { if (pszValue[0] == 'E') { nActiveCamera = CAMERA_TYPE_ENV; } else if (pszValue[0] == 'O') { nActiveCamera = CAMERA_TYPE_OPT; } } } } void CLivenessDetectionEntity::OnSelfTest( EntityTestEnum eTestType,CSmartPointer pTransactionContext ) { if (Test_ShakeHand == eTestType) { pTransactionContext->SendAnswer(Error_Succeed); } } void CLivenessDetectionEntity::InitVideoQueueInfo() { if (!m_pFaceVideo) { m_pFaceVideo = new RvcFaceVideo(); } if (eStand1SPlusType == m_eDeviceType) { m_pFaceVideo->InitVideoQueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE, NULL, REC_COMMON_VIDEO_ENV_SHM_PREVIEW_QUEUE, NULL); } else { 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); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Init Video QueueInfo Success."); } bool CLivenessDetectionEntity::GetCameraOnStatus() { bool bRet = false; MediaControlClient* pMediaControlClient = new MediaControlClient(this); ErrorCodeEnum erroCode = pMediaControlClient->Connect(); if (Error_Succeed != erroCode) { pMediaControlClient->SafeDelete(); pMediaControlClient = NULL; } else { MediaService_IsCameraOnStatus_Req req; MediaService_IsCameraOnStatus_Ans ans; if (Error_Succeed == pMediaControlClient->IsCameraOnStatus(req, ans, 5000)) { bRet = ans.biscameraon; } pMediaControlClient->GetFunction()->CloseSession(); pMediaControlClient = NULL; } return bRet; } int CLivenessDetectionEntity::on_get_videodata(eVideoType eType, eCameraType ecameraid, int* width, int* height, unsigned char* bmpdata, int isize) { int idatalen = 0; if (!m_pFaceVideo) { return idatalen; } if (ePreview_Type == eType) { idatalen = m_pFaceVideo->GetPreViewVideoFrameSize(ecameraid, width, height); } else{ idatalen = m_pFaceVideo->GetVideoFrameSize(ecameraid, width, height); } if (0 < idatalen){ video_frame vframe = {0}; vframe.format = VIDEO_FORMAT_RGB24; vframe.width = *width; vframe.height = *height; videoq_frame qvframe = {0}; qvframe.framesize = idatalen; qvframe.width = *width; qvframe.height = *height; qvframe.data = bmpdata; bool bRet = false; if (ePreview_Type == eType){ int iPreviewflag = 3; #ifdef RVC_OS_WIN if (eCamera_Env == ecameraid){ iPreviewflag = 1; } #endif bRet = m_pFaceVideo->GetPreViewVideoFrame((int)ecameraid, &qvframe, iPreviewflag); } else{ int iCapflag = 2; #ifdef RVC_OS_WIN if (eCamera_Env == ecameraid){ iCapflag = 0; } #endif bRet = m_pFaceVideo->GetVideoFrame((int)ecameraid, &qvframe, iCapflag); } if (!bRet){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get video frame from queue failed, and picture data length is %d.", idatalen); } } else{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get video frame size failed, and picture data length is %d.", idatalen); } return idatalen; } ErrorCodeEnum CLivenessDetectionEntity::GetEntityConfigure() { CSmartPointer spConfig; ErrorCodeEnum eErrDev; eErrDev = GetFunction()->OpenConfig(Config_CenterSetting, spConfig); if (eErrDev != Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("open center setting file failed!"); return eErrDev; } SpIniMappingTable table; table.AddEntryInt("LivenessDetection","WsServerPort", m_iWsPort, RVC_LIVENESS_WS_PORT); eErrDev = table.Load(spConfig); return eErrDev; } MediaControlClient::MediaControlClient(CLivenessDetectionEntity* pEntity) : MediaService_ClientBase(pEntity) { } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CLivenessDetectionEntity) SP_END_ENTITY_MAP()