mod_snapshot.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "Event.h"
  5. #include "mod_mediacontroller/Event.h"
  6. #include "AssistantChannel_client_g.h"
  7. using namespace AssistantChannel;
  8. #include "chan_protocol.h"
  9. #include "rvc_media_common.h"
  10. #include "libvideoqueue.h"
  11. #include "libfacecapture.h"
  12. #include "jpeg2k.h"
  13. #include "videoutil.h"
  14. #include "y2k_time.h"
  15. #include "EventCode.h"
  16. #include "CommEntityUtil.hpp"
  17. #include "cv.h"
  18. #include "highgui.h"
  19. #include "../mod_interactivecontrol/Event.h"
  20. #ifdef RVC_OS_WIN
  21. #define ENV_CAP_TIMEOUT 15
  22. #define OPT_CAP_TIMEOUT 10
  23. #else
  24. #define ENV_CAP_TIMEOUT 150
  25. #define OPT_CAP_TIMEOUT 100
  26. #endif
  27. #ifndef RVC_SAFE_DELETE
  28. #define RVC_SAFE_DELETE(p) { if(p){ (p)->SafeDelete(); (p)=NULL;} }
  29. #endif //RVC_SAFE_DELETE
  30. #ifndef MAX_PATH
  31. #define MAX_PATH 260
  32. #endif
  33. class CPhotoCaptureEntity;
  34. class ChannelClient : public ChannelService_ClientBase
  35. {
  36. public:
  37. ChannelClient(CPhotoCaptureEntity *pEntity);
  38. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData);
  39. };
  40. int RotationDown(unsigned char* src, int srcW, int srcH, int channel)
  41. {
  42. unsigned char* tempSrc = NULL;
  43. int mSize = srcW * srcH * sizeof(char) * channel;
  44. int i = 0;
  45. int j = 0;
  46. int k = 0;
  47. int desW = 0;
  48. int desH = 0;
  49. desW = srcW;
  50. desH = srcH;
  51. tempSrc = (unsigned char*)malloc(sizeof(char) * srcW * srcH * channel);
  52. memcpy(tempSrc, src, mSize);
  53. for (i = 0; i < desH; i++)
  54. {
  55. for (j = 0; j < desW; j++)
  56. {
  57. for (k = 0; k < channel; k++)
  58. {
  59. //src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + srcW - 1 - j) * channel + k];
  60. src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + j) * channel + k];
  61. }
  62. }
  63. }
  64. free(tempSrc);
  65. return 0;
  66. }
  67. // id: 0x905
  68. class CPhotoCaptureEntity : public CEntityBase, public ITimerListener, public ILogListener
  69. {
  70. public:
  71. CPhotoCaptureEntity() : m_video_env_q(NULL), m_video_opt_q(NULL), m_dwCapture(0), m_bConnectAssist(false) {
  72. m_pChannelClient = NULL;
  73. }
  74. virtual ~CPhotoCaptureEntity() {}
  75. virtual const char *GetEntityName() const { return "Snapshot"; }
  76. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  77. {
  78. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  79. pTransactionContext->SendAnswer(Error);
  80. }
  81. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  82. {
  83. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  84. pTransactionContext->SendAnswer(Error);
  85. }
  86. ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
  87. {
  88. if (preOperationError != Error_Succeed) {
  89. return preOperationError;
  90. }
  91. //is Pad Version
  92. m_eDeviceType = RvcGetDeviceType();
  93. if (eStand1SPlusType == m_eDeviceType)
  94. {
  95. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  96. }
  97. else
  98. { // == 2
  99. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  100. m_video_opt_q = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE);
  101. }
  102. CSmartPointer<IEntityFunction> spFunc = GetFunction();
  103. int i = 0;
  104. m_arrListener.Init(4);
  105. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV);
  106. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_OPT);
  107. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT);
  108. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS,NULL,false);
  109. return Error_Succeed;
  110. }
  111. void OnStarted()
  112. {
  113. m_pChannelClient = new ChannelClient(this);
  114. if (Error_Succeed == ConnectAssistChannel()) {
  115. m_bConnectAssist = true;
  116. }
  117. else {
  118. GetFunction()->SetTimer(2, this, 3370);
  119. }
  120. }
  121. ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
  122. {
  123. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  124. for (int i = 0; i < m_arrListener.GetCount(); ++i)
  125. {
  126. spFunction->UnsubscribeLog(m_arrListener[i]);
  127. }
  128. if (preOperationError != Error_Succeed)
  129. return preOperationError;
  130. if (m_pChannelClient) {
  131. m_pChannelClient->GetFunction()->CloseSession();
  132. m_pChannelClient = NULL;
  133. }
  134. if (NULL != m_video_env_q) {
  135. delete m_video_env_q;
  136. m_video_env_q = NULL;
  137. }
  138. if (NULL != m_video_opt_q) {
  139. delete m_video_opt_q;
  140. m_video_opt_q = NULL;
  141. }
  142. return Error_Succeed;
  143. }
  144. void WriteStamp(video_frame *srcfrm)
  145. {
  146. CImageFrame frm;
  147. frm.data = srcfrm->data[0];
  148. frm.width = srcfrm->width;
  149. frm.height = srcfrm->height;
  150. frm.framesize = srcfrm->width * srcfrm->height * 3;
  151. if (!SnapShot(&frm)) {
  152. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("write stamp failed!");
  153. }
  154. }
  155. void Capture(int rc)
  156. {
  157. video_frame *frm = NULL;
  158. if((rc == 0)||(rc==Error_TimeOut))
  159. {
  160. if (m_video_env_q && m_video_opt_q)
  161. {
  162. int combine_width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  163. int combine_height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH + REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  164. frm = video_frame_new(combine_width, combine_height, VIDEO_FORMAT_RGB24);
  165. video_frame_fill_black(frm);
  166. // get env snapshot
  167. {
  168. video_frame tmp_frm = {0};
  169. tmp_frm.data[0] = frm->data[0];
  170. tmp_frm.linesize[0] = frm->linesize[0];
  171. tmp_frm.format = frm->format;
  172. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  173. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  174. DWORD time = m_video_env_q->GetLastFrameTime();
  175. if ((y2k_time_now() - time) < ENV_CAP_TIMEOUT)
  176. {
  177. m_video_env_q->GetVideo2(&tmp_frm, 0);
  178. }
  179. else
  180. {
  181. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the env snapshot videoqueque image timeout!");
  182. }
  183. }
  184. // get opt snapshot
  185. {
  186. video_frame tmp_frm = {0};
  187. tmp_frm.data[0] = frm->data[0] + frm->linesize[0] * REC_COMMON_VIDEO_SNAPSHOT_HEIGHT+(REC_COMMON_VIDEO_SNAPSHOT_WIDTH-REC_COMMON_VIDEO_SNAPSHOT_HEIGHT)/2*3;
  188. tmp_frm.linesize[0] = frm->linesize[0];
  189. tmp_frm.format = frm->format;
  190. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  191. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  192. DWORD time = m_video_opt_q->GetLastFrameTime();
  193. if ((y2k_time_now() - time) < OPT_CAP_TIMEOUT)
  194. {
  195. m_video_opt_q->GetVideo2(&tmp_frm, 0);
  196. }
  197. else
  198. {
  199. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the opt snapshot video queque image timeout!");
  200. }
  201. }
  202. }
  203. else if (m_video_env_q)
  204. {
  205. frm = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, VIDEO_FORMAT_RGB24);
  206. video_frame_fill_black(frm);
  207. video_frame tmp_frm = {0};
  208. tmp_frm.data[0] = frm->data[0];
  209. tmp_frm.linesize[0] = frm->linesize[0];
  210. tmp_frm.format = frm->format;
  211. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  212. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  213. DWORD time = m_video_env_q->GetLastFrameTime();
  214. if ((y2k_time_now() - time) < ENV_CAP_TIMEOUT)
  215. {
  216. m_video_env_q->GetVideo2(&tmp_frm, 0);
  217. }
  218. else
  219. {
  220. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("the env snapshot video queque image timeout!");
  221. }
  222. }
  223. else
  224. {
  225. //assert(0); // not go here
  226. rc = -1;
  227. }
  228. #ifndef RVC_OS_WIN
  229. {
  230. int size = frm->linesize[0] * frm->height;
  231. RotationDown(frm->data[0], frm->width, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, 3);
  232. }
  233. #endif
  234. }
  235. jpeg2k_coded_image codec_image = {0};
  236. if((rc == 0)||(rc==Error_TimeOut))
  237. {
  238. WriteStamp(frm);
  239. jpeg2k_raw_image raw_image;
  240. raw_image.data = frm->data[0];
  241. raw_image.width = frm->width;
  242. raw_image.height = frm->height;
  243. raw_image.len = raw_image.width * raw_image.height * 3;
  244. rc = jpeg2k_encode(&raw_image, &codec_image, 10);
  245. }
  246. if ((rc == 0)||(rc==Error_TimeOut))
  247. {
  248. ChannelService_Send_Info Info;
  249. Info.compress = false;
  250. Info.encrypt = false;
  251. Info.type = ACM_TYPE_PHT;
  252. Info.id = 0;
  253. Info.sub_type = ACM_PHT_ANS | ACM_PHT_SNAPSHOT;
  254. Info.data.m_pData = (char*)codec_image.data;
  255. Info.data.m_iLength = codec_image.len;
  256. (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info);
  257. jpeg2k_encode_free(&codec_image);
  258. }
  259. else
  260. {
  261. ChannelService_Send_Info Info;
  262. Info.compress = false;
  263. Info.encrypt = false;
  264. Info.type = ACM_TYPE_PHT;
  265. Info.id = 0;
  266. Info.sub_type = ACM_PHT_ANS | ACM_PHT_SNAPSHOT;
  267. Info.data.m_pData = (char *)&rc;
  268. Info.data.m_iLength = sizeof(rc);
  269. (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info);
  270. }
  271. if (frm) {
  272. video_frame_delete(frm);
  273. }
  274. }
  275. ErrorCodeEnum StartCapture(int id)
  276. {
  277. #if defined(RVC_OS_LINUX)
  278. if (eStand1SPlusType == m_eDeviceType) {
  279. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  280. }
  281. else { // == 2
  282. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  283. m_video_opt_q = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE);
  284. }
  285. #endif //RVC_OS_LINUX
  286. if (!m_video_env_q && !m_video_opt_q) {
  287. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cannot start capture!"); // never go here
  288. return Error_Unexpect;
  289. }
  290. if (m_dwCapture) {
  291. return Error_Duplication;
  292. }
  293. //触发对应的摄像头进行图像采集
  294. if (m_video_env_q && m_video_opt_q)
  295. {
  296. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_ENVOPT, "agent start capture env and opt camera picture!");
  297. }
  298. else if (m_video_env_q)
  299. {
  300. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_ENV, "agent start capture env camera picture!");
  301. }
  302. else if (m_video_opt_q)
  303. {
  304. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_OPT, "agent start capture opt camera picture!");
  305. }
  306. m_dwCapture = SP::Module::Comm::RVCGetTickCount();
  307. GetFunction()->SetTimer(1, this, 2000);
  308. return Error_Succeed;
  309. }
  310. void StopCapture()
  311. {
  312. GetFunction()->KillTimer(1);
  313. m_dwCapture = 0;
  314. }
  315. DeviceTypeEnum RvcGetDeviceType()
  316. {
  317. DeviceTypeEnum eType = eStand2sType;
  318. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  319. CSystemStaticInfo stStaticinfo;
  320. spFunction->GetSystemStaticInfo(stStaticinfo);
  321. if (_stricmp(stStaticinfo.strMachineType, "RVC.Stand1SPlus") == 0) {
  322. eType = eStand1SPlusType;
  323. }
  324. else if (stricmp(stStaticinfo.strMachineType, "RVC.CardStore") == 0 || stricmp(stStaticinfo.strMachineType, "RVC.CardPrinter") == 0) {
  325. eType = eCardStore;
  326. }
  327. else {
  328. eType = eStand2sType;
  329. }
  330. if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) {
  331. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]);
  332. }
  333. return eType;
  334. }
  335. virtual void OnTimeout(DWORD dwTimerID)
  336. {
  337. if (1 == dwTimerID) {
  338. Capture(Error_TimeOut);
  339. GetFunction()->KillTimer(dwTimerID);
  340. m_dwCapture = 0;
  341. }
  342. else if (2 == dwTimerID) {
  343. if (false == m_bConnectAssist) {
  344. if (Error_Succeed == ConnectAssistChannel()) {
  345. m_bConnectAssist = true;
  346. }
  347. }
  348. if (true == m_bConnectAssist) {
  349. GetFunction()->KillTimer(2);
  350. }
  351. }
  352. }
  353. virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  354. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  355. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
  356. {
  357. switch (dwUserCode)
  358. {
  359. case MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT:
  360. case MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_OPT:
  361. case MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV:
  362. {
  363. DWORD dwNow = SP::Module::Comm::RVCGetTickCount();
  364. Capture(Error_Succeed);
  365. StopCapture();
  366. }
  367. break;
  368. case LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS:
  369. {
  370. Sleep(975);
  371. if (m_pChannelClient != NULL) {
  372. m_pChannelClient->GetFunction()->CloseSession();
  373. m_pChannelClient = NULL;
  374. m_bConnectAssist = false;
  375. }
  376. if (Error_Succeed == ConnectAssistChannel()) {
  377. m_bConnectAssist = true;
  378. }
  379. else {
  380. GetFunction()->SetTimer(2, this, 3370);
  381. }
  382. }
  383. break;
  384. default:
  385. {
  386. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown dwUserCode = 0x%08x.", dwUserCode);
  387. }
  388. break;
  389. }
  390. }
  391. private:
  392. ErrorCodeEnum ConnectAssistChannel()
  393. {
  394. if (m_pChannelClient == NULL){
  395. m_pChannelClient = new ChannelClient(this);
  396. }
  397. ErrorCodeEnum Error = m_pChannelClient->Connect();
  398. if (Error_Succeed != Error){
  399. m_pChannelClient = NULL;
  400. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("AssistChannelClient connect fail!");
  401. return Error;
  402. }
  403. if (Error_Succeed == Error){
  404. ChannelService_BeginRecv_Sub Sub;
  405. Sub.type = ACM_TYPE_PHT;
  406. Error = (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->BeginRecv(Sub);
  407. if (Error_Succeed != Error){
  408. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("BeginRecv ACM_TYPE_PHT fail!");
  409. m_pChannelClient->GetFunction()->CloseSession();
  410. m_pChannelClient = NULL;
  411. return Error;
  412. }
  413. }
  414. return Error;
  415. }
  416. private:
  417. Clibvideoqueue *m_video_env_q;
  418. Clibvideoqueue *m_video_opt_q;
  419. ChannelClient *m_pChannelClient;
  420. CUUID m_uuidCaptureTimer;
  421. DWORD m_dwCapture;
  422. DeviceTypeEnum m_eDeviceType;
  423. CAutoArray<CUUID> m_arrListener;
  424. bool m_bConnectAssist;
  425. };
  426. void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
  427. {
  428. if (Error == Error_Succeed) {
  429. CPhotoCaptureEntity *pEntity = static_cast<CPhotoCaptureEntity*>(m_pEntityBase);
  430. int cat = ACM_PHT_CAT(Msg.sub_type);
  431. if (cat == ACM_PHT_REQ)
  432. {
  433. Error = pEntity->StartCapture(Msg.id);
  434. if (Error)
  435. {
  436. pEntity->Capture(Error);
  437. }
  438. }
  439. else
  440. {
  441. _ASSERT(0);
  442. }
  443. }
  444. }
  445. ChannelClient::ChannelClient( CPhotoCaptureEntity *pEntity ) : ChannelService_ClientBase(pEntity)
  446. {
  447. }
  448. SP_BEGIN_ENTITY_MAP()
  449. SP_ENTITY(CPhotoCaptureEntity)
  450. SP_END_ENTITY_MAP()