|
|
@@ -0,0 +1,366 @@
|
|
|
+#include "stdafx.h"
|
|
|
+#include <stdint.h>
|
|
|
+#include "mod_livenessdetection.h"
|
|
|
+#include "videoframework.h"
|
|
|
+
|
|
|
+//compile with VS2019
|
|
|
+#if defined(RVC_OS_WIN)
|
|
|
+#pragma comment(lib, "legacy_stdio_definitions.lib")
|
|
|
+extern "C" {
|
|
|
+ FILE __iob_func[3] = { *stdin, *stdout, *stderr };
|
|
|
+}
|
|
|
+#endif //RVC_OS_WIN
|
|
|
+
|
|
|
+CLivenessDetectionEntity::CLivenessDetectionEntity(): m_bStarted(FALSE), m_nCaptureType(-1)/*, m_pFsm(NULL), m_pCapturer(NULL)*/
|
|
|
+{
|
|
|
+ m_WsServer = new RvcWsServer();
|
|
|
+ m_pFaceVideo = new RvcFaceVideo();
|
|
|
+ m_hWsServerThread = NULL;
|
|
|
+ m_iWsPort = RVC_LIVENESS_WS_PORT;
|
|
|
+ m_iCapType = 1;
|
|
|
+}
|
|
|
+
|
|
|
+CLivenessDetectionEntity::~CLivenessDetectionEntity()
|
|
|
+{
|
|
|
+ if (m_WsServer){
|
|
|
+ delete m_WsServer;
|
|
|
+ m_WsServer = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_pFaceVideo){
|
|
|
+ delete m_pFaceVideo;
|
|
|
+ m_pFaceVideo = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD exitCode = 0;
|
|
|
+ if (m_hWsServerThread)
|
|
|
+ {
|
|
|
+ TerminateThread(m_hWsServerThread, exitCode);
|
|
|
+ m_hWsServerThread = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+const char * CLivenessDetectionEntity::GetEntityName() const
|
|
|
+{
|
|
|
+ return "LivenessDetection";
|
|
|
+}
|
|
|
+
|
|
|
+void CLivenessDetectionEntity::OnPreStart( CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext )
|
|
|
+{
|
|
|
+ ErrorCodeEnum Error = __OnStart(Error_Succeed);
|
|
|
+ pTransactionContext->SendAnswer(Error);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+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<CLivenessDetectionEntity *>(user_data);
|
|
|
+
|
|
|
+ int iret = pThis->on_get_videodata(eType, ecameraid, width, height, bmpdata, isize);
|
|
|
+
|
|
|
+ return iret;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static unsigned int __stdcall start_wsserver(void *arg)
|
|
|
+{
|
|
|
+ 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;
|
|
|
+ liveness_entity->GetWsServer()->Init_WsServer(&t_callback, &t_param, liveness_entity->GetWsPort());
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void CLivenessDetectionEntity::OnStarted()
|
|
|
+{
|
|
|
+ LOG_FUNCTION();
|
|
|
+ if (Error_Succeed == GetEntityConfigure()){
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[LivenessDetectionFSM] Get Entity Configure Success!");
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[LivenessDetectionFSM] Get Entity Configure Failed!");
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 success.");
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void CLivenessDetectionEntity::OnPreClose( EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> 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<IEntityFunction> spFunction = GetFunction();
|
|
|
+ CSystemStaticInfo stStaticinfo;
|
|
|
+ spFunction->GetSystemStaticInfo(stStaticinfo);
|
|
|
+ if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
|
|
|
+ {
|
|
|
+ if (stricmp(stStaticinfo.strSite,"CMB.FLB")==0)
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is mobile pad");
|
|
|
+ m_eDeviceType = eMobilePadType;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is pad");
|
|
|
+ m_eDeviceType = ePadtype;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (stricmp(stStaticinfo.strMachineType,"RPM.Stand1S")==0)
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is rpm.stand1s");
|
|
|
+ m_eDeviceType = eRpm1sType;
|
|
|
+ }
|
|
|
+ else if (stricmp(stStaticinfo.strMachineType,"RVC.Desk2S")==0)
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is Desk2S");
|
|
|
+ m_eDeviceType = eDesk2SType;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the type is standard");
|
|
|
+ m_eDeviceType = eStand2sType;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (preOperationError != Error_Succeed)
|
|
|
+ return preOperationError;
|
|
|
+
|
|
|
+ ErrorCodeEnum Error = Error_Succeed;
|
|
|
+ nActiveCamera = CAMERA_TYPE_ENV;
|
|
|
+ m_iCameraState = 'N';
|
|
|
+ BOOL bRet = FALSE;
|
|
|
+
|
|
|
+ if (ePadtype==m_eDeviceType||eMobilePadType==m_eDeviceType||eDesk2SType==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);
|
|
|
+ }
|
|
|
+
|
|
|
+ int i = 0;
|
|
|
+ m_arrListener.Init(2);
|
|
|
+ GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_BEGIN_RECORD, NULL, false);
|
|
|
+ GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_END_RECORD, 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<IEntityFunction> spFunction = GetFunction();
|
|
|
+ for (int i = 0; i < m_arrListener.GetCount(); ++i)
|
|
|
+ {
|
|
|
+ spFunction->UnsubscribeLog(m_arrListener[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Error_Succeed;
|
|
|
+}
|
|
|
+
|
|
|
+void CLivenessDetectionEntity::Debug( const char *fmt, ... )
|
|
|
+{
|
|
|
+ va_list arg;
|
|
|
+ va_start(arg, fmt);
|
|
|
+
|
|
|
+ int n = _vscprintf(fmt, arg);
|
|
|
+ if (n >= 512) {
|
|
|
+ char* buf = (char*)malloc((size_t)(n + 1));
|
|
|
+ _vsnprintf(buf, n + 1, fmt, arg);
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
|
|
|
+ free(buf);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ char strlog[512] = {0};
|
|
|
+ _vsnprintf(strlog, 512, fmt, arg);
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
|
|
|
+ }
|
|
|
+ va_end(arg);
|
|
|
+}
|
|
|
+
|
|
|
+int CLivenessDetectionEntity::GetActiveCamera()
|
|
|
+{
|
|
|
+ //Debug("get camera = %d",nActiveCamera);
|
|
|
+ return nActiveCamera;
|
|
|
+}
|
|
|
+
|
|
|
+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)
|
|
|
+{
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[dbg] dwUserCode=0x%08x", dwUserCode);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+void CLivenessDetectionEntity::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
|
|
|
+{
|
|
|
+ if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
|
|
|
+ {
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("camera state from : %c to %c", pszOldValue[0], pszValue[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;
|
|
|
+ //m_pFsm->NotifyCameraFault(); // 摄像头故障,停止捕获
|
|
|
+ //m_pCapturer->NotifyCameraFault(); // 摄像头故障,停止捕获
|
|
|
+ }
|
|
|
+ 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<ITransactionContext> pTransactionContext )
|
|
|
+{
|
|
|
+ if (Test_ShakeHand == eTestType)
|
|
|
+ {
|
|
|
+ pTransactionContext->SendAnswer(Error_Succeed);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+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;
|
|
|
+ if (eCamera_Env == ecameraid && 1 == m_iCapType){
|
|
|
+ iPreviewflag = 1;
|
|
|
+ }
|
|
|
+ bRet = m_pFaceVideo->GetPreViewVideoFrame((int)ecameraid, &qvframe, iPreviewflag);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ int iCapflag = 2;
|
|
|
+ if (eCamera_Env == ecameraid && 1 == m_iCapType){
|
|
|
+ iCapflag = 0;
|
|
|
+ }
|
|
|
+ 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<IConfigInfo> 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);
|
|
|
+ //table.AddEntryInt("MediaController", "VideoCapFrameType", m_iCapType, 0);
|
|
|
+ eErrDev = table.Load(spConfig);
|
|
|
+
|
|
|
+ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("center setting web socket port is %d, and video cap type is %d.", m_iWsPort, m_iCapType);
|
|
|
+
|
|
|
+ return eErrDev;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+SP_BEGIN_ENTITY_MAP()
|
|
|
+SP_ENTITY(CLivenessDetectionEntity)
|
|
|
+SP_END_ENTITY_MAP()
|