Ver Fonte

#IQRV #comment mod_livenessdetection 编译通过

80374374 há 1 ano atrás
pai
commit
315adf1aba

+ 1 - 1
Module/CMakeLists.txt

@@ -218,7 +218,7 @@ add_subdirectory(mod_alarm)
 add_subdirectory(mod_RomoteController)
 add_subdirectory(mod_ResourceWatcher)
 #zhaohu
-#add_subdirectory(mod_livenessdetection)
+add_subdirectory(mod_livenessdetection)
 add_subdirectory(mod_vtmloader)
 
 #below should be compiled succesufully.

+ 34 - 5
Module/mod_livenessdetection/CMakeLists.txt

@@ -1,5 +1,9 @@
 define_module("livenessdetection")
 
+if(MSVC)
+add_definitions(-D__STDC_LIMIT_MACROS)
+endif(MSVC)
+
 if(MSVC)
     set(WIN_SRC 
 	LivenessDetectionFSM.h
@@ -15,49 +19,74 @@ endif(MSVC)
 set(${MODULE_PREFIX}_SRCS
 	Event.h
 	mod_livenessdetection.h
-	mod_livenessdetection.cpp
+	${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_PLAFORM_SUBDIR}/mod_livenessdetection.cpp
 	RvcFaceVideo.cpp
 	RvcFaceVideo.h
 	RvcWsServer.cpp
 	RvcWsServer.h
 )
 
-
 set(MOD_VERSION_STRING "0.0.1-dev1")
 add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
 
-if(MSVC)
-#add_precompiled_header(${MODULE_NAME} stdafx.h SOURCE_CXX stdafx.cpp FORCEINCLUDE)
-endif(MSVC)
 
 
+if(MSVC)
 target_include_directories(${MODULE_NAME} PRIVATE
 	${RVC_FRAMEWORK_INCLUDES_DIR}
 	${RVC_COMMON_INCLUDE_DIR}
+	${CMAKE_CURRENT_SOURCE_DIR}
 	${CONAN_RVCFRAMEWORK_ROOT}/include/libtoolkit
 	${CONAN_INCLUDE_DIRS_FFMPEG}
 	${OTHER_LIB_PLATFORM_BASE_DIR}/libvideoframework
 	${OTHER_LIB_PLATFORM_BASE_DIR}/rvcmediacommon
 	${OTHER_LIB_PLATFORM_BASE_DIR}/libvideoqueue
+	${MODULE_BASE_DIR}
+	${MODULE_BASE_DIR}/include
+	${ThirdPartyHeadRoot}/websocketpp
+	${CONAN_INCLUDE_DIRS_OPENSSL}
+	${CONAN_INCLUDE_DIRS_JPEG}
+	${CONAN_INCLUDE_DIRS_BOOST}/boost-1_69
+)
+else()
+target_include_directories(${MODULE_NAME} PRIVATE
+	${RVC_FRAMEWORK_INCLUDES_DIR}
+	${RVC_COMMON_INCLUDE_DIR}
+	${CMAKE_CURRENT_SOURCE_DIR}
+	${CONAN_RVCFRAMEWORK_ROOT}/include/libtoolkit
+	${CONAN_INCLUDE_DIRS_FFMPEG}
+	${OTHER_LIB_PLATFORM_BASE_DIR}/libvideoframework
+	${OTHER_LIB_PLATFORM_BASE_DIR}/rvcmediacommon
+	${OTHER_LIB_PLATFORM_BASE_DIR}/libvideoqueue
+	${MODULE_BASE_DIR}
 	${MODULE_BASE_DIR}/include
 	${ThirdPartyHeadRoot}/websocketpp
 	${ThirdPartyHeadRoot}/libjpeg
 	${CONAN_BOOST_ROOT}
 )
+endif(MSVC)
 
 
 target_link_directories(${MODULE_NAME} PRIVATE
 	${RVC_FRAMEWORK_LIBRARIES_DIR}
 	${CONAN_LIB_DIRS_BOOST}
+	${CONAN_LIB_DIRS_OPENSSL}
 	${CONAN_LIB_DIRS_LIBJPEG}
+	${CONAN_LIB_DIRS_JPEG}
 )
 
 
 # 添加实体需要依赖的其他共享库(包括系统库)
+message(STATUS "OPENCV_DYNAMIC_LIBS ${OPENCV_DYNAMIC_LIBS}")
+message(STATUS "CONAN_PKG_LIBS_OPENSSL ${CONAN_PKG_LIBS_OPENSSL}")
+
 if(WIN32)
 set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS} 
+	legacy_stdio_definitions
+	${CONAN_PKG_LIBS_OPENSSL}
 	${SPBASE_LIB}
 	videoqueue
+	${CONAN_PKG_LIBS_JPEG}
 )
 else(WIN32)
 set(${MODULE_PREFIX}_LIBS  ${MODULE_BASE_LIBS} 

+ 2 - 1
Module/mod_livenessdetection/Event.h

@@ -28,4 +28,5 @@
 #define LOG_EVT_STARTVIDEOTRANS				0x31480001				//开始视频传输
 #define LOG_EVT_STOPVIDEOTRANS				0x31480002				//停止视频传输
 #define LOG_EVT_STARTVIDEOCAPTURE			0x31480003				//开始视频抓拍
-#define LOG_EVT_AUTO_FACE_FAILED			0x31480004				//自动人脸失败
+#define LOG_EVT_AUTO_FACE_FAILED			0x31480004				//自动人脸失败
+#define LOG_EVT_AUTO_FACE_TIMEOUT			0x31480005				//自动人脸超时

+ 9 - 4
Module/mod_livenessdetection/RvcFaceVideo.cpp

@@ -1,6 +1,11 @@
 #include "stdafx.h"
+#include <stdint.h>
 #include "RvcFaceVideo.h"
 
+#if defined(RVC_OS_LINUX)
+#define _snprintf snprintf
+#endif //RVC_OS_LINUX
+
 RvcFaceVideo::RvcFaceVideo(void)
 {
 	memset(m_env_videoname, 0, MAX_PATH);
@@ -68,19 +73,19 @@ int RvcFaceVideo::InitVideoQueue(const char* strenvqueue, const char* stroptqueu
 {
 	int iRet = -1;
 	if (NULL != strenvqueue){
-		snprintf(m_env_videoname, MAX_PATH, "%s", strenvqueue);
+		_snprintf(m_env_videoname, MAX_PATH, "%s", strenvqueue);
 	}
 
 	if (NULL != stroptqueue){
-		snprintf(m_opt_videoname, MAX_PATH, "%s", stroptqueue);
+		_snprintf(m_opt_videoname, MAX_PATH, "%s", stroptqueue);
 	}
 
 	if (NULL != strpreview_envqueue){
-		snprintf(m_preview_env_videoname, MAX_PATH, "%s", strpreview_envqueue);
+		_snprintf(m_preview_env_videoname, MAX_PATH, "%s", strpreview_envqueue);
 	}
 
 	if (NULL != strpreview_optqueue){
-		snprintf(m_preview_opt_videoname, MAX_PATH, "%s", strpreview_optqueue);
+		_snprintf(m_preview_opt_videoname, MAX_PATH, "%s", strpreview_optqueue);
 	}
 
 	if (strlen(m_env_videoname)){

+ 91 - 21
Module/mod_livenessdetection/RvcWsServer.cpp

@@ -1,4 +1,5 @@
 #include "stdafx.h"
+#include <stdint.h>
 #include "RvcWsServer.h"
 #include <boost/thread/thread.hpp>
 #include <vector>
@@ -94,29 +95,28 @@ static int gbr2jpg(const unsigned char *pRgbData, const int width, const int hei
     cinfo.err = jpeg_std_error(&jerr);
 
     jpeg_create_compress(&cinfo);
- 
-    jpeg_mem_dest(&cinfo, (unsigned char **)&pDest, (unsigned long *)pSize);
+
+	jpeg_mem_dest(&cinfo, (unsigned char**)&pDest, (unsigned long*)pSize);
 
 	unsigned char* prgb = new unsigned char[width*height*3]; //获取的原始数据是bgr格式
 
 	bgr2rgb(pRgbData, width, height, prgb);
 
+#if defined(RVC_OS_WIN)
+	rgb2jpg_action(&cinfo, prgb, width, height);
+#else
 	unsigned char* reversePrgb = new unsigned char[width * height * 3];
-	
+
 	if (reverseFlag == 0) //上下翻转
 	{
-		for (int i = 0; i < height; i++)
-		{
+		for (int i = 0; i < height; i++) {
 			memcpy(reversePrgb + (i * width * 3),
 				prgb + (3 * width * (height - (i + 1))), width * 3);
 		}
-	}
-	else if(reverseFlag == 1) //左右翻转
+	} else if (reverseFlag == 1) //左右翻转
 	{
-		for (int i = 0; i < height; i++)
-		{
-			for (int j = 0; j < width; j++)
-			{
+		for (int i = 0; i < height; i++) {
+			for (int j = 0; j < width; j++) {
 				memcpy(reversePrgb + (3 * ((width * i) + j)),
 					prgb + (3 * ((width * i) + (width - (j + 1)))), 3);
 			}
@@ -125,11 +125,14 @@ static int gbr2jpg(const unsigned char *pRgbData, const int width, const int hei
 
 	rgb2jpg_action(&cinfo, reversePrgb, width, height);
 
+	delete reversePrgb;
+	reversePrgb = NULL;
+#endif //RVC_OS_WIN
+
 	delete prgb;
 	prgb = NULL;
 
-	delete reversePrgb;
-	reversePrgb = NULL;
+
 
 
     return 0;
@@ -155,14 +158,17 @@ static int on_send(RvcWsServer *webserver, eVideoType eType)
 			unsigned long  size = RVC_MAX_JPEG_SIZE;
 			if (ePreview_Type == eType){
 				pDest[0] = 0x01;
+#if defined(RVC_OS_WIN)
+				gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size);
+#else
 				if (webserver->m_ecameraid == 0) //上摄像头
 				{
 					gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size, 0); //上下翻转
-				}
-				else if(webserver->m_ecameraid == 1) //下摄像头
+				} else if (webserver->m_ecameraid == 1) //下摄像头
 				{
 					gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size, 1); //左右翻转
 				}
+#endif //RVC_OS_WIN
 
 			}
 			else{
@@ -220,7 +226,11 @@ static void process(RvcWsServer *webserver)
 }
 
 
+#if defined(RVC_OS_WIN)
+static unsigned int __stdcall work_proc(void* arg)
+#else
 static void* work_proc(void* arg)
+#endif //RVC_OS_WIN
 {
 	RvcWsServer *webserver = (RvcWsServer *)arg;
 
@@ -238,7 +248,11 @@ RvcWsServer::RvcWsServer(void):m_wsserver()
 	m_bconnected = false;
 	m_struuid = "";
 	m_bstarttrans = false;
+#if defined(RVC_OS_WIN)
+	m_work_thread = NULL;
+#else
 	m_work_threadid = 0;
+#endif //RVC_OS_WIN
 	m_cameraid = 0;
 	m_fps = RVC_DEFAULT_FPS;
 	m_buffer = NULL;
@@ -255,7 +269,11 @@ RvcWsServer::~RvcWsServer(void)
 	m_bconnected = false;
 	m_struuid = "";
 	m_bstarttrans = false;
+#if defined(RVC_OS_WIN)
+	m_work_thread = NULL;
+#else
 	m_work_threadid = 0;
+#endif //RVC_OS_WIN
 	m_cameraid = 0;
 	m_fps = RVC_DEFAULT_FPS; 
 	if (NULL != m_buffer){
@@ -407,6 +425,23 @@ void RvcWsServer::on_close(websocketpp::connection_hdl hdl)
 		m_bstarttrans = false;
 		char strmsg[MAX_PATH] = {0};
 		unsigned int utranstime = y2k_time_now() - m_utranstime;
+
+#if defined(RVC_OS_WIN)
+		_snprintf(strmsg, MAX_PATH, "stop video trans for session close, and transmit time is %us.", utranstime);
+		LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
+
+		if (RVC_MIN_VIDEO_TRANS_TIME >= utranstime) {
+			char strinfo[MAX_PATH] = { 0 };
+			_snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
+			LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
+		}
+
+		if (RVC_MAX_VIDEO_TRANS_TIME <= utranstime) {
+			char strmessage[MAX_PATH] = { 0 };
+			_snprintf(strmessage, MAX_PATH, "auto face timeout and transmit time is %us.", utranstime);
+			LogWarn(Severity_Low, Error_Debug, LOG_EVT_AUTO_FACE_TIMEOUT, strmessage);
+		}
+#else
 		snprintf(strmsg, MAX_PATH, "stop video trans for session close, and transmit time is %us.", utranstime);
 		LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
 
@@ -415,6 +450,9 @@ void RvcWsServer::on_close(websocketpp::connection_hdl hdl)
 			snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
 			LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
 		}
+#endif //RVC_OS_WIN
+
+
 	}
 }
  
@@ -491,10 +529,15 @@ int RvcWsServer::StartVideoTransmit()
 {
 	int iRet = -1;
 
+#if defined(RVC_OS_WIN)
+	m_work_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, this, 0, NULL);
+	if (!m_work_thread)
+#else
 	if (0 == pthread_create(&m_work_threadid, NULL, work_proc, (void*)this)) {
 		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create start video transmit thread and thread id is %u.", m_work_threadid);
-	}
-	else {
+	} else
+#endif //RVC_OS_WIN
+	 {
 		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create start video transmit thread failed.");
 		return iRet;
 	}
@@ -510,7 +553,34 @@ int RvcWsServer::StopVideoTransmit()
 {
 	int iRet = -1;
 
-	if (m_bconnected && m_bstarttrans){
+	if (m_bconnected && m_bstarttrans) {
+#if defined(RVC_OS_WIN)
+		SetEvent(m_evt);
+
+		if (NULL != m_work_thread) {
+			WaitForSingleObject(m_work_thread, INFINITE);
+			CloseHandle(m_work_thread);
+			m_work_thread = NULL;
+		}
+
+		char strmsg[MAX_PATH] = { 0 };
+		unsigned int utranstime = y2k_time_now() - m_utranstime;
+
+		_snprintf(strmsg, MAX_PATH, "stop video trans for user operation, and transmit time is %us.", utranstime);
+		LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
+
+		if (RVC_MIN_VIDEO_TRANS_TIME >= utranstime) {
+			char strinfo[MAX_PATH] = { 0 };
+			_snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
+			LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
+		}
+
+		if (RVC_MAX_VIDEO_TRANS_TIME <= utranstime) {
+			char strmessage[MAX_PATH] = { 0 };
+			_snprintf(strmessage, MAX_PATH, "auto face timeout and transmit time is %us.", utranstime);
+			LogWarn(Severity_Low, Error_Debug, LOG_EVT_AUTO_FACE_TIMEOUT, strmessage);
+	}
+#else
 		sem_post(&m_semt);
 
 		DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("in stop func");
@@ -518,12 +588,11 @@ int RvcWsServer::StopVideoTransmit()
 		if (0 == pthread_join(m_work_threadid, NULL)) {
 			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join video transmit thread %u success!", m_work_threadid);
 			m_work_threadid = 0;
-		}
-		else {
+		} else {
 			DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join video transmit thread failed!");
 		}
 
-		char strmsg[MAX_PATH] = {0};
+		char strmsg[MAX_PATH] = { 0 };
 		unsigned int utranstime = y2k_time_now() - m_utranstime;
 
 		snprintf(strmsg, MAX_PATH, "stop video trans for user operation, and transmit time is %us.", utranstime);
@@ -534,6 +603,7 @@ int RvcWsServer::StopVideoTransmit()
 			snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
 			LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
 		}
+#endif //RVC_OS_WIN
 
 		iRet = 0;
 	}

+ 7 - 0
Module/mod_livenessdetection/RvcWsServer.h

@@ -8,7 +8,9 @@
 #include <functional>
 #include <memory>
 #include <vector>
+#if defined(RVC_OS_LINUX)
 #include <semaphore.h>
+#endif //RVC_OS_LINUX
 
 
 #ifndef RVC_LIVENESS_WS_PORT
@@ -113,8 +115,13 @@ public:
 	volatile bool m_bconnected;			// connect flag
 	volatile bool m_bstarttrans;		// start transmit
 	volatile eCameraType m_ecameraid;			// camera id
+#if defined(RVC_OS_WIN)
+	HANDLE m_work_thread;
+	HANDLE m_evt;
+#else
 	pthread_t m_work_threadid;
 	sem_t m_semt;
+#endif //RVC_OS_WIN
 	websocket_callback_t m_callback;
 	server m_wsserver;					// websocket server,用于和业务层传输视频流,默认端口9100
 	websocketpp::connection_hdl m_hdl;

+ 70 - 0
Module/mod_livenessdetection/SingleTimer.cpp

@@ -0,0 +1,70 @@
+#include "stdafx.h"
+#include "SingleTimer.h"
+
+UINT WINAPI TimerWaitThread(LPVOID pM);
+HANDLE hWaitEvent = NULL;
+
+SingleTimer::SingleTimer() 
+{
+	m_isRunning = false;
+	hWaitEvent = CreateEventA(NULL, TRUE, FALSE, 0); //手动设置,初始状态为无信号
+	
+	m_hWaitThread = NULL;
+	m_waitMS = 3000;
+}
+
+SingleTimer:: ~SingleTimer()
+{
+	if (hWaitEvent)
+	{
+		CloseHandle(hWaitEvent);
+		hWaitEvent = NULL;
+	}
+	if (m_hWaitThread)
+	{
+		WaitForSingleObject(m_hWaitThread, INFINITE); //等待线程执行完
+		CloseHandle(m_hWaitThread);
+		m_hWaitThread = NULL;
+	}
+}
+
+void SingleTimer::start()
+{
+	if(isRunning())
+		return;
+
+	m_isRunning = TRUE;
+	m_hWaitThread = (HANDLE)_beginthreadex(NULL, 0, TimerWaitThread, this, 0, NULL);
+}
+
+void SingleTimer::stop()
+{
+	m_isRunning = FALSE;
+}
+
+bool SingleTimer::isRunning() const
+{
+	return m_isRunning;
+}
+
+void SingleTimer::setWaitTime(int wTime)
+{
+	m_waitMS = wTime;
+}
+
+int SingleTimer::waitTime() const
+{
+	return m_waitMS;
+}
+
+//等待线程
+UINT WINAPI TimerWaitThread(LPVOID pM)
+{
+	SingleTimer *timer = (SingleTimer*)pM;
+
+	DWORD dwRet = WaitForSingleObject(hWaitEvent, timer->waitTime()); //挂起线程
+	
+	timer->stop();
+	
+	return 0;
+}

+ 24 - 0
Module/mod_livenessdetection/SingleTimer.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "stdafx.h"
+
+class SingleTimer
+{
+private:
+	DWORD dwTimerId;
+	bool m_isRunning;
+	HANDLE m_hWaitThread;
+
+	int m_waitMS;
+
+public:
+	SingleTimer();
+	virtual ~SingleTimer();
+
+	void start();
+	void stop();
+	bool isRunning() const;
+
+	void setWaitTime(int wTime);
+	int waitTime() const;
+};

+ 21 - 6
Module/mod_livenessdetection/mod_livenessdetection.h

@@ -9,16 +9,20 @@
 #include "SpIni.h"
 #include "rvc_media_common.h"
 #include "Event.h"
-//#include "sysvar.h"
-#include "../mod_mediacontroller/Event.h"
-#include "../mod_facetracking/sysvar.h"
+#include "mod_customeraware/Event.h"
+#include "mod_mediacontroller/Event.h"
+#include "mod_facetracking/sysvar.h"
+
+#include "LivenessDetection_def_g.h"
+#include "LivenessDetection_msg_g.h"
+#include "LivenessDetection_server_g.h"
 
 #include <assert.h>
 #include "EventCode.h"
 
 #include "RvcWsServer.h"
 #include "RvcFaceVideo.h"
-#include "LivenessDetection_server_g.h"
+
 
 using namespace LivenessDetection;
 
@@ -46,6 +50,11 @@ public:
 
 	virtual void OnStarted();
 
+#if defined(RVC_OS_WIN)
+	// CAviHostAPI
+	virtual void Debug(const char* fmt, ...);
+#endif //RVC_OS_WIN
+
 	virtual int GetActiveCamera();
 
 	ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError);
@@ -59,7 +68,7 @@ public:
 	virtual bool IsService() const { return true; }
 	virtual bool IsMultiThread() const { return false; }
 
-	// ʵÌå·þÎñ»¯
+	// 实体�务化
 	virtual CServerSessionBase* OnNewSession(const char*, const char*)
 	{
 		return new LivenessDetectionServerSession(this);
@@ -81,7 +90,9 @@ private:
 
 	virtual void OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext);
 	
-	ErrorCodeEnum DecideCameraCount(int &nCount);
+#if defined(RVC_OS_LINUX)
+	ErrorCodeEnum DecideCameraCount(int& nCount);
+#endif //RVC_OS_LINUX
 
 	DeviceTypeEnum m_eDeviceType;
 	int nActiveCamera;
@@ -95,7 +106,11 @@ private:
 	RvcWsServer* m_WsServer;
 	RvcFaceVideo* m_pFaceVideo;
 	 
+#if defined(RVC_OS_WIN)
+	HANDLE m_hWsServerThread;
+#else
 	pthread_t m_hWsServerThreadId;
+#endif //RVC_OS_WIN
 	int m_iWsPort;
 	int m_iCapType;
 };

BIN
Module/mod_livenessdetection/mod_livenessdetection.rc


+ 0 - 0
Module/mod_livenessdetection/mod_livenessdetection.cpp → Module/mod_livenessdetection/unix/mod_livenessdetection.cpp


+ 366 - 0
Module/mod_livenessdetection/win/mod_livenessdetection.cpp

@@ -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()

+ 1 - 1
addin/cmake/DependencyConanFiles.cmake

@@ -65,8 +65,8 @@ if(MSVC)
 			speex/1.2.1@LR04.02_ThirdParty/testing
 			#libvideoframework
 			libyuv/17.88@LR04.02_ThirdParty/testing
+			jpeg/9.2@LR04.02_ThirdParty/testing
 			)
-
 			
 	if(TRUE) #todo
 		list(APPEND CONAN_CURPLATFORM_LIB_NAMES cefclient_const/1.0@LR04.02_ThirdParty/testing)