RvcWsServer.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. #include "stdafx.h"
  2. #include <stdint.h>
  3. #include "RvcWsServer.h"
  4. #include <boost/thread/thread.hpp>
  5. #include <vector>
  6. #include <boost/thread/lock_guard.hpp>
  7. #include "SpBase.h"
  8. #include "jpeglib.h"
  9. #include "Event.h"
  10. #include "y2k_time.h"
  11. namespace LivenessDetection{
  12. #ifndef RVC_JPEG_QUALITY
  13. #define RVC_JPEG_QUALITY 100 //ͼƬ����
  14. #endif
  15. #ifndef RVC_COLOR_PEPTH
  16. #define RVC_COLOR_PEPTH 3
  17. #endif
  18. #ifndef RVC_MAX_JPEG_SIZE
  19. #define RVC_MAX_JPEG_SIZE 256*1024
  20. #endif
  21. #ifndef RVC_PICTURE_TYPE_LEN
  22. #define RVC_PICTURE_TYPE_LEN 1
  23. #endif
  24. #ifndef RVC_MIN_VIDEO_TRANS_TIME
  25. #define RVC_MIN_VIDEO_TRANS_TIME 2
  26. #endif
  27. #ifndef RVC_MAX_VIDEO_TRANS_TIME
  28. #define RVC_MAX_VIDEO_TRANS_TIME 15
  29. #endif
  30. static int rgb2jpg_action(struct jpeg_compress_struct* pCinfo, const unsigned char *pRgbData, const int width, const int height)
  31. {
  32. int depth = RVC_COLOR_PEPTH;
  33. JSAMPROW row_pointer[1] = {0};
  34. pCinfo->image_width = width;
  35. pCinfo->image_height = height;
  36. pCinfo->input_components = depth;
  37. pCinfo->in_color_space = JCS_RGB;
  38. jpeg_set_defaults(pCinfo);
  39. jpeg_set_quality(pCinfo, RVC_JPEG_QUALITY, true);
  40. jpeg_start_compress(pCinfo, true);
  41. int row_stride = width * depth;
  42. while (pCinfo->next_scanline < pCinfo->image_height){
  43. row_pointer[0] = (JSAMPROW)(pRgbData + pCinfo->next_scanline * row_stride);
  44. jpeg_write_scanlines(pCinfo, row_pointer, 1);
  45. }
  46. jpeg_finish_compress(pCinfo);
  47. jpeg_destroy_compress(pCinfo);
  48. return 0;
  49. }
  50. static int bgr2rgb(const unsigned char* bgr_image , const int image_width , const int image_height , unsigned char* rgb_image)
  51. {
  52. if(!bgr_image || !rgb_image) {
  53. return 1;
  54. }
  55. for(int i = 0; i < image_width * image_height; i++){
  56. unsigned char b_value = *bgr_image++;
  57. unsigned char g_value = *bgr_image++;
  58. unsigned char r_value = *bgr_image++;
  59. *rgb_image++ = r_value;
  60. *rgb_image++ = g_value;
  61. *rgb_image++ = b_value;
  62. }
  63. return 0;
  64. }
  65. static int gbr2jpg(const unsigned char *pRgbData, const int width, const int height, char* pDest, unsigned long* pSize, int reverseFlag = 0)
  66. {
  67. struct jpeg_compress_struct cinfo;
  68. struct jpeg_error_mgr jerr;
  69. cinfo.err = jpeg_std_error(&jerr);
  70. jpeg_create_compress(&cinfo);
  71. jpeg_mem_dest(&cinfo, (unsigned char**)&pDest, (unsigned long*)pSize);
  72. unsigned char* prgb = new unsigned char[width*height*3]; //��ȡ��ԭʼ������bgr��ʽ
  73. bgr2rgb(pRgbData, width, height, prgb);
  74. #if defined(RVC_OS_WIN)
  75. rgb2jpg_action(&cinfo, prgb, width, height);
  76. #else
  77. unsigned char* reversePrgb = new unsigned char[width * height * 3];
  78. if (reverseFlag == 0) //���·�ת
  79. {
  80. for (int i = 0; i < height; i++) {
  81. memcpy(reversePrgb + (i * width * 3),
  82. prgb + (3 * width * (height - (i + 1))), width * 3);
  83. }
  84. } else if (reverseFlag == 1) //���ҷ�ת
  85. {
  86. for (int i = 0; i < height; i++) {
  87. for (int j = 0; j < width; j++) {
  88. memcpy(reversePrgb + (3 * ((width * i) + j)),
  89. prgb + (3 * ((width * i) + (width - (j + 1)))), 3);
  90. }
  91. }
  92. }
  93. rgb2jpg_action(&cinfo, reversePrgb, width, height);
  94. delete reversePrgb;
  95. reversePrgb = NULL;
  96. #endif //RVC_OS_WIN
  97. delete prgb;
  98. prgb = NULL;
  99. return 0;
  100. }
  101. static int on_send(RvcWsServer *webserver, eVideoType eType)
  102. {
  103. int iwidth = 0;
  104. int iheight = 0;
  105. int isize = 0;
  106. if (webserver->m_callback.on_get_videodata){
  107. if (ePreview_Type == eType){
  108. isize = webserver->m_callback.on_get_videodata(ePreview_Type, webserver->m_ecameraid, &iwidth, &iheight, webserver->m_buffer, webserver->m_ubuffer_size, webserver->m_callback.user_data);
  109. }
  110. else{
  111. isize = webserver->m_callback.on_get_videodata(eCapture_Type, webserver->m_ecameraid, &iwidth, &iheight, webserver->m_capbuffer, webserver->m_ucapbuffer_size, webserver->m_callback.user_data);
  112. }
  113. if (isize > 0){
  114. char pDest[RVC_MAX_JPEG_SIZE] = {0};
  115. unsigned long size = RVC_MAX_JPEG_SIZE;
  116. if (ePreview_Type == eType){
  117. pDest[0] = 0x01;
  118. #if defined(RVC_OS_WIN)
  119. gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size);
  120. #else
  121. if (webserver->m_ecameraid == 0) //������ͷ
  122. {
  123. gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size, 0); //���·�ת
  124. } else if (webserver->m_ecameraid == 1) //������ͷ
  125. {
  126. gbr2jpg(webserver->m_buffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size, 1); //���ҷ�ת
  127. }
  128. #endif //RVC_OS_WIN
  129. }
  130. else{
  131. pDest[0] = 0x02;
  132. gbr2jpg(webserver->m_capbuffer, iwidth, iheight, pDest + RVC_PICTURE_TYPE_LEN, &size);
  133. }
  134. if (webserver->m_bconnected && webserver->m_bstarttrans){
  135. if (false == webserver->m_hdl.expired()){
  136. webserver->m_wsserver.send(webserver->m_hdl, (const void*)pDest, size + RVC_PICTURE_TYPE_LEN, websocketpp::frame::opcode::value::binary);
  137. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("send picture size is %u.", size+1);
  138. }
  139. }
  140. }
  141. }
  142. return 0;
  143. }
  144. static void process(RvcWsServer *webserver)
  145. {
  146. while (webserver->m_bconnected && webserver->m_bstarttrans)
  147. {
  148. #ifdef _MSC_VER
  149. DWORD dwRet = WaitForSingleObject(webserver->m_evt, 1000 / webserver->m_fps);
  150. if (dwRet == WAIT_OBJECT_0) {
  151. break;
  152. }
  153. else if (dwRet == WAIT_TIMEOUT) {
  154. if (webserver->m_bconnected && webserver->m_bstarttrans) {
  155. on_send(webserver, ePreview_Type);
  156. }
  157. }
  158. #else
  159. struct timespec ts;
  160. clock_gettime(CLOCK_REALTIME, &ts);
  161. long unsec = ts.tv_nsec + (1000 * 1000 * (1000 / webserver->m_fps)); //�߳�������ʱʱ�� 1000/webserver->m_fps ����
  162. ts.tv_sec += (unsec / 1000000000);
  163. ts.tv_nsec = (unsec % 1000000000);
  164. if (0 != sem_timedwait(&webserver->m_semt, &ts) && (ETIMEDOUT == errno)) {
  165. if (webserver->m_bconnected && webserver->m_bstarttrans) {
  166. on_send(webserver, ePreview_Type);
  167. }
  168. }
  169. else
  170. {
  171. break;
  172. }
  173. #endif // _MSC_VER
  174. }
  175. webserver->m_bstarttrans = false;
  176. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("process exit.");
  177. }
  178. #if defined(RVC_OS_WIN)
  179. static unsigned int __stdcall work_proc(void* arg)
  180. #else
  181. static void* work_proc(void* arg)
  182. #endif //RVC_OS_WIN
  183. {
  184. RvcWsServer *webserver = (RvcWsServer *)arg;
  185. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("video fps is %d.", webserver->m_fps);
  186. process(webserver);
  187. return 0;
  188. }
  189. RvcWsServer::RvcWsServer(void):m_wsserver()
  190. {
  191. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("RvcWsServer()");
  192. m_bconnected = false;
  193. m_struuid = "";
  194. m_bstarttrans = false;
  195. #if defined(RVC_OS_WIN)
  196. m_work_thread = NULL;
  197. #else
  198. m_work_threadid = 0;
  199. #endif //RVC_OS_WIN
  200. m_cameraid = 0;
  201. m_fps = RVC_DEFAULT_FPS;
  202. m_buffer = NULL;
  203. m_ubuffer_size = 0;
  204. m_capbuffer = NULL;
  205. m_ucapbuffer_size = 0;
  206. m_ecameraid = eCamera_Env;
  207. }
  208. RvcWsServer::~RvcWsServer(void)
  209. {
  210. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("~RvcWsServer()");
  211. m_bconnected = false;
  212. m_struuid = "";
  213. m_bstarttrans = false;
  214. #if defined(RVC_OS_WIN)
  215. m_work_thread = NULL;
  216. #else
  217. m_work_threadid = 0;
  218. #endif //RVC_OS_WIN
  219. m_cameraid = 0;
  220. m_fps = RVC_DEFAULT_FPS;
  221. if (NULL != m_buffer){
  222. delete m_buffer;
  223. m_buffer = NULL;
  224. }
  225. m_ubuffer_size = 0;
  226. if (NULL != m_capbuffer){
  227. delete m_capbuffer;
  228. m_capbuffer = NULL;
  229. }
  230. m_ucapbuffer_size = 0;
  231. }
  232. void on_socket_init(websocketpp::connection_hdl hdl, boost::asio::ip::tcp::socket& s)
  233. {
  234. boost::asio::ip::tcp::no_delay option(true);
  235. s.set_option(option);
  236. }
  237. int RvcWsServer::Init_WsServer(websocket_callback_t* pcallback, rvc_video_param_t* pparam, int iport)
  238. {
  239. int iret = -1;
  240. if (NULL == pcallback){
  241. return iret;
  242. }
  243. if (iport <= 0){
  244. m_listenport = RVC_LIVENESS_WS_PORT;
  245. }
  246. else{
  247. m_listenport = iport;
  248. }
  249. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("WsServer listening port is %d.", m_listenport);
  250. m_cameraid = 0;
  251. m_fps = RVC_DEFAULT_FPS;
  252. memcpy(&m_callback, pcallback, sizeof(websocket_callback_t));
  253. #ifdef _MSC_VER
  254. m_evt = CreateEventA(NULL, FALSE, FALSE, NULL); //�߳�ͬ��������
  255. #else
  256. sem_init(&m_semt, 0, 0);
  257. #endif //_MSC_VER
  258. m_ubuffer_size = pparam->iwidth*pparam->iheight*3;
  259. m_buffer = new unsigned char[m_ubuffer_size];
  260. memset(m_buffer, 0, m_ubuffer_size);
  261. m_ucapbuffer_size = pparam->icapwidth*pparam->icapheight*3;
  262. m_capbuffer = new unsigned char[m_ucapbuffer_size];
  263. memset(m_capbuffer, 0, m_ucapbuffer_size);
  264. m_ecameraid = eCamera_Env;
  265. try {
  266. // Set logging settings
  267. m_wsserver.set_access_channels(websocketpp::log::alevel::all);
  268. m_wsserver.set_error_channels(websocketpp::log::elevel::all);
  269. // Register our message handler
  270. m_wsserver.set_message_handler(websocketpp::lib::bind(&RvcWsServer::on_message, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2));
  271. m_wsserver.set_http_handler(websocketpp::lib::bind(&RvcWsServer::on_http, this, websocketpp::lib::placeholders::_1));
  272. m_wsserver.set_fail_handler(websocketpp::lib::bind(&RvcWsServer::on_fail, this, websocketpp::lib::placeholders::_1));
  273. m_wsserver.set_open_handler(websocketpp::lib::bind(&RvcWsServer::on_open, this, websocketpp::lib::placeholders::_1));
  274. m_wsserver.set_close_handler(websocketpp::lib::bind(&RvcWsServer::on_close, this, websocketpp::lib::placeholders::_1));
  275. m_wsserver.set_validate_handler(websocketpp::lib::bind(&RvcWsServer::validate, this, websocketpp::lib::placeholders::_1));
  276. // Initialize ASIO
  277. m_wsserver.init_asio();
  278. m_wsserver.set_reuse_addr(true);
  279. m_wsserver.set_socket_init_handler(&on_socket_init);
  280. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get_max_message_size is %d.", m_wsserver.get_max_message_size());
  281. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get_max_http_body_size is %d.", m_wsserver.get_max_http_body_size());
  282. m_wsserver.listen(m_listenport);
  283. // Start the server accept loop
  284. m_wsserver.start_accept();
  285. iret = 0;
  286. // Start the ASIO io_service run loop
  287. m_wsserver.run();
  288. //stop
  289. m_wsserver.stop();
  290. }
  291. catch (websocketpp::exception const & e) {
  292. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(e.what());
  293. }
  294. catch (const std::exception & e) {
  295. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)(e.what());
  296. }
  297. catch (...) {
  298. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("other exception");
  299. }
  300. return iret;
  301. }
  302. bool RvcWsServer::validate(websocketpp::connection_hdl hdl)
  303. {
  304. return true;
  305. }
  306. void RvcWsServer::on_http(websocketpp::connection_hdl hdl)
  307. {
  308. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("on_http");
  309. server::connection_ptr con = m_wsserver.get_con_from_hdl(hdl);
  310. std::string res = con->get_request_body();
  311. std::stringstream ss;
  312. ss << "got HTTP request with " << res.size() << " bytes of body data.";
  313. con->set_body(ss.str());
  314. con->set_status(websocketpp::http::status_code::ok);
  315. }
  316. void RvcWsServer::on_fail(websocketpp::connection_hdl hdl)
  317. {
  318. server::connection_ptr con = m_wsserver.get_con_from_hdl(hdl);
  319. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("fail handler: %d, %s." , con->get_ec().value(), con->get_ec().message());
  320. }
  321. void RvcWsServer::on_open(websocketpp::connection_hdl hdl)
  322. {
  323. //����websocket upgrade�ɹ�֮�󣬵���open_handler�������ص�on_open��
  324. //��������Ի�ȡhttp����ĵ�ַ��������Ϣ��
  325. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("open handler");
  326. server::connection_ptr con = m_wsserver.get_con_from_hdl(hdl);
  327. websocketpp::config::core::request_type requestClient = con->get_request();
  328. std::string strMethod = requestClient.get_method(); //���󷽷�
  329. std::string strUri = requestClient.get_uri(); //����uri��ַ�����Խ�������
  330. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("request client method is %s, uri is %s.", strMethod.c_str(), strUri.c_str());
  331. }
  332. void RvcWsServer::on_close(websocketpp::connection_hdl hdl)
  333. {
  334. m_bconnected = false;
  335. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("close handler");
  336. if (m_bstarttrans){
  337. m_bstarttrans = false;
  338. char strmsg[MAX_PATH] = {0};
  339. unsigned int utranstime = y2k_time_now() - m_utranstime;
  340. #if defined(RVC_OS_WIN)
  341. _snprintf(strmsg, MAX_PATH, "stop video trans for session close, and transmit time is %us.", utranstime);
  342. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
  343. if (RVC_MIN_VIDEO_TRANS_TIME >= utranstime) {
  344. char strinfo[MAX_PATH] = { 0 };
  345. _snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
  346. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
  347. }
  348. if (RVC_MAX_VIDEO_TRANS_TIME <= utranstime) {
  349. char strmessage[MAX_PATH] = { 0 };
  350. _snprintf(strmessage, MAX_PATH, "auto face timeout and transmit time is %us.", utranstime);
  351. LogWarn(Severity_Low, Error_Debug, LOG_EVT_AUTO_FACE_TIMEOUT, strmessage);
  352. }
  353. #else
  354. snprintf(strmsg, MAX_PATH, "stop video trans for session close, and transmit time is %us.", utranstime);
  355. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
  356. if (RVC_MIN_VIDEO_TRANS_TIME >= utranstime) {
  357. char strinfo[MAX_PATH] = { 0 };
  358. snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
  359. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
  360. }
  361. if (RVC_MAX_VIDEO_TRANS_TIME <= utranstime) {
  362. char strmessage[MAX_PATH] = { 0 };
  363. snprintf(strmessage, MAX_PATH, "auto face timeout and transmit time is %us.", utranstime);
  364. LogWarn(Severity_Low, Error_Debug, LOG_EVT_AUTO_FACE_TIMEOUT, strmessage);
  365. }
  366. #endif //RVC_OS_WIN
  367. }
  368. }
  369. // Define a callback to handle incoming messages
  370. void RvcWsServer::on_message(websocketpp::connection_hdl hdl, server::message_ptr msg)
  371. {
  372. /*
  373. hdl.lock().get() ������ӱ�ʶ
  374. msg->get_payload() ���յ�����Ϣ����
  375. msg->get_opcode() ���յ���Ϣ������ ���������ı�TEXT,������BINARY�ȵ�
  376. */
  377. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("on_message called with hdl:0x%08x, and message: %s, and opcode: %d.", hdl.lock().get(), msg->get_payload().c_str(), msg->get_opcode());
  378. try {
  379. /*
  380. ������Ϣ
  381. s->send(
  382. hdl, //����
  383. msg->get_payload(), //��Ϣ
  384. msg->get_opcode());//��Ϣ����
  385. */
  386. if (m_bconnected == false){ //��ʼ���ӿ�
  387. m_struuid = "";
  388. if (0 == msg->get_payload().compare(0, strlen(RVC_WS_INIT_STR), RVC_WS_INIT_STR)){
  389. handle_initial_instructions(hdl, msg->get_payload());
  390. }
  391. }
  392. else{
  393. if (0 == msg->get_payload().compare(0, m_struuid.length(), m_struuid)){
  394. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv client request is %s.", msg->get_payload().c_str());
  395. if (0 == msg->get_payload().compare(m_struuid.length() + strlen(RVC_WS_CONNECT_IDENTIFIER), strlen(RVC_WS_START_TRANS_STR), RVC_WS_START_TRANS_STR)){
  396. m_bstarttrans = true;
  397. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video trans.");
  398. m_hdl = hdl;
  399. if (0 == StartVideoTransmit()){
  400. //m_wsserver.send(hdl, "start video transmit success.", msg->get_opcode());
  401. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video transmit success.");
  402. }
  403. else{
  404. //m_wsserver.send(hdl, "start video transmit failed.", msg->get_opcode());
  405. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start video transmit failed.");
  406. }
  407. }
  408. else if(0 == msg->get_payload().compare(m_struuid.length() + strlen(RVC_WS_CONNECT_IDENTIFIER), strlen(RVC_WS_STOP_TRANS_STR), RVC_WS_STOP_TRANS_STR)){
  409. StopVideoTransmit();
  410. m_bstarttrans = false;
  411. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("stop video trans.");
  412. //m_wsserver.send(hdl, "stop video trans.", msg->get_opcode());
  413. }
  414. else if (0 == msg->get_payload().compare(m_struuid.length() + strlen(RVC_WS_CONNECT_IDENTIFIER), strlen(RVC_WS_CHANGE_CAMERA_STR), RVC_WS_CHANGE_CAMERA_STR)){
  415. handle_change_camera_instructions(msg->get_payload());
  416. }
  417. else if(0 == msg->get_payload().compare(m_struuid.length() + strlen(RVC_WS_CONNECT_IDENTIFIER), strlen(RVC_WS_START_CAPTURE_STR), RVC_WS_START_CAPTURE_STR)){
  418. StartVideoCapTransmit();
  419. }
  420. else
  421. {
  422. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown request.");
  423. }
  424. }
  425. else{
  426. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv invalid request is %s.", msg->get_payload().c_str());
  427. }
  428. }
  429. }
  430. catch (websocketpp::exception const & e) {
  431. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("send failed because: %s", e.what());
  432. }
  433. }
  434. int RvcWsServer::StartVideoTransmit()
  435. {
  436. int iRet = -1;
  437. #if defined(RVC_OS_WIN)
  438. m_work_thread = (HANDLE)_beginthreadex(NULL, 0, &work_proc, this, 0, NULL);
  439. if (!m_work_thread)
  440. #else
  441. if (0 == pthread_create(&m_work_threadid, NULL, work_proc, (void*)this)) {
  442. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create start video transmit thread and thread id is %u.", m_work_threadid);
  443. } else
  444. #endif //RVC_OS_WIN
  445. {
  446. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create start video transmit thread failed.");
  447. return iRet;
  448. }
  449. iRet = 0;
  450. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STARTVIDEOTRANS, "start video trans.");
  451. m_utranstime = y2k_time_now();
  452. return iRet;
  453. }
  454. int RvcWsServer::StopVideoTransmit()
  455. {
  456. int iRet = -1;
  457. if (m_bconnected && m_bstarttrans) {
  458. #if defined(RVC_OS_WIN)
  459. SetEvent(m_evt);
  460. if (NULL != m_work_thread) {
  461. WaitForSingleObject(m_work_thread, INFINITE);
  462. CloseHandle(m_work_thread);
  463. m_work_thread = NULL;
  464. }
  465. char strmsg[MAX_PATH] = { 0 };
  466. unsigned int utranstime = y2k_time_now() - m_utranstime;
  467. _snprintf(strmsg, MAX_PATH, "stop video trans for user operation, and transmit time is %us.", utranstime);
  468. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
  469. if (RVC_MIN_VIDEO_TRANS_TIME >= utranstime) {
  470. char strinfo[MAX_PATH] = { 0 };
  471. _snprintf(strinfo, MAX_PATH, "auto face failed and transmit time is %us.", utranstime);
  472. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_AUTO_FACE_FAILED, strinfo);
  473. }
  474. if (RVC_MAX_VIDEO_TRANS_TIME <= utranstime) {
  475. char strmessage[MAX_PATH] = { 0 };
  476. _snprintf(strmessage, MAX_PATH, "auto face timeout and transmit time is %us.", utranstime);
  477. LogWarn(Severity_Low, Error_Debug, LOG_EVT_AUTO_FACE_TIMEOUT, strmessage);
  478. }
  479. #else
  480. sem_post(&m_semt);
  481. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("in stop func");
  482. if (0 == pthread_join(m_work_threadid, NULL)) {
  483. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join video transmit thread %u success!", m_work_threadid);
  484. m_work_threadid = 0;
  485. } else {
  486. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("thread join video transmit thread failed!");
  487. }
  488. char strmsg[MAX_PATH] = { 0 };
  489. unsigned int utranstime = y2k_time_now() - m_utranstime;
  490. snprintf(strmsg, MAX_PATH, "stop video trans for user operation, and transmit time is %us.", utranstime);
  491. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STOPVIDEOTRANS, strmsg);
  492. #endif //RVC_OS_WIN
  493. iRet = 0;
  494. }
  495. return iRet;
  496. }
  497. int RvcWsServer::StartVideoCapTransmit()
  498. {
  499. LogWarn(Severity_Low, Error_Debug, LOG_EVT_STARTVIDEOCAPTURE, "start video capture transmit.");
  500. return on_send(this, eCapture_Type);
  501. }
  502. static bool allisnum(std::string str)
  503. {
  504. for (int i = 0; i < str.size(); i++){
  505. int tmp = (int)str[i];
  506. if (tmp >= '0' && tmp <= '9'){
  507. continue;
  508. }
  509. else
  510. {
  511. return false;
  512. }
  513. }
  514. return true;
  515. }
  516. int RvcWsServer::handle_initial_instructions(websocketpp::connection_hdl hdl, std::string strinstrut)
  517. {
  518. int iret = -1;
  519. m_bconnected = true;
  520. m_ecameraid = eCamera_Env;
  521. CUUID struuid = CUUID::Create(struuid);
  522. m_struuid = struuid.ToString();
  523. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("new connect and uuid is %s.", m_struuid.c_str());
  524. m_wsserver.send(hdl, m_struuid, websocketpp::frame::opcode::value::text);
  525. int index = strinstrut.find_first_of(RVC_WS_CONNECT_IDENTIFIER);
  526. if (std::string::npos != index){
  527. std::string strfps = strinstrut.substr(index + strlen(RVC_WS_CONNECT_IDENTIFIER));
  528. if (allisnum(strfps)){
  529. int ifps = atoi(strfps.c_str());
  530. if (ifps > RVC_MAX_FPS){
  531. ifps = RVC_MAX_FPS;
  532. }
  533. if (ifps < RVC_MIN_FPS){
  534. ifps = RVC_MIN_FPS;
  535. }
  536. m_fps = ifps;
  537. }
  538. }
  539. iret = 0;
  540. return iret;
  541. }
  542. int RvcWsServer::handle_change_camera_instructions(std::string strinstrut)
  543. {
  544. int iret = -1;
  545. if (m_bstarttrans){
  546. int index = strinstrut.find_first_of(RVC_WS_CHANGE_CAMERA_STR);
  547. if (std::string::npos != index){
  548. std::string strcamera = strinstrut.substr(index + strlen(RVC_WS_CHANGE_CAMERA_STR));
  549. index = strcamera.find_first_of(RVC_WS_CONNECT_IDENTIFIER);
  550. if (std::string::npos != index){
  551. std::string strid = strcamera.substr(index + strlen(RVC_WS_CONNECT_IDENTIFIER));
  552. if (allisnum(strid)){
  553. int icameraid = atoi(strid.c_str());
  554. if (eCamera_Env == icameraid || eCamera_Opt == icameraid){
  555. m_ecameraid = (eCameraType)icameraid;
  556. }
  557. }
  558. }
  559. }
  560. iret = 0;
  561. }
  562. else{
  563. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("current is not in data transmitting.");
  564. }
  565. return iret;
  566. }
  567. }