mod_snapshot.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpIni.h"
  4. #include "Event.h"
  5. #include "..\\mod_mediacontroller\\Event.h"
  6. #include "..\mod_assistantchannel\AssistantChannel_client_g.h"
  7. using namespace AssistantChannel;
  8. #include "..\mod_Assistantchannel\chan_protocol.h"
  9. #include "rec_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. #define LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE 0x50500001 //协助通道重启
  17. class CPhotoCaptureEntity;
  18. class ChannelClient : public ChannelService_ClientBase
  19. {
  20. public:
  21. ChannelClient(CPhotoCaptureEntity *pEntity);
  22. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData);
  23. };
  24. // id: 0x905
  25. class CPhotoCaptureEntity : public CEntityBase, public ITimerListener, public ILogListener
  26. {
  27. public:
  28. CPhotoCaptureEntity() : m_video_env_q(NULL), m_video_opt_q(NULL), m_dwCapture(0) {}
  29. virtual ~CPhotoCaptureEntity() {}
  30. virtual const char *GetEntityName() const { return "Snapshot"; }
  31. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  32. {
  33. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  34. pTransactionContext->SendAnswer(Error);
  35. }
  36. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  37. {
  38. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  39. pTransactionContext->SendAnswer(Error);
  40. }
  41. ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
  42. {
  43. LOG_FUNCTION();
  44. if (preOperationError != Error_Succeed)
  45. return preOperationError;
  46. //is Pad Version
  47. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  48. CSystemStaticInfo stStaticinfo;
  49. spFunction->GetSystemStaticInfo(stStaticinfo);
  50. if (stricmp(stStaticinfo.strMachineType,"RVC.PAD")==0)
  51. {
  52. if (stricmp(stStaticinfo.strSite,"CMB.FLB")==0)
  53. {
  54. LOG_TRACE("the type is mobile pad");
  55. m_eDeviceType = eMobilePadType;
  56. }
  57. else
  58. {
  59. LOG_TRACE("the type is pad");
  60. m_eDeviceType = ePadtype;
  61. }
  62. }
  63. else if (stricmp(stStaticinfo.strMachineType,"RVC.Desk2S")==0)
  64. {
  65. LOG_TRACE("the type is Desk2S");
  66. m_eDeviceType = eDesk2SType;
  67. }
  68. else if (stricmp(stStaticinfo.strMachineType,"RPM.Stand1S")==0)
  69. {
  70. LOG_TRACE("the type is RPM.Stand1S");
  71. m_eDeviceType = eRpm1sType;
  72. }
  73. else
  74. {
  75. LOG_TRACE("the type is standard");
  76. m_eDeviceType = eStand2sType;
  77. }
  78. ErrorCodeEnum Error;
  79. //int nCameraCount = 0;
  80. //ErrorCodeEnum Error;
  81. //Error = DecideCameraCount(nCameraCount);
  82. //if (Error != Error_Succeed || nCameraCount < 0 || nCameraCount > 2) {
  83. // LOG_TRACE("decide camera count failed!");
  84. // return Error;
  85. //}
  86. if ((ePadtype == m_eDeviceType)||(eMobilePadType == m_eDeviceType)||(eDesk2SType == m_eDeviceType) )
  87. {
  88. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  89. }
  90. else
  91. { // == 2
  92. m_video_env_q = new Clibvideoqueue(REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE);
  93. m_video_opt_q = new Clibvideoqueue(REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE);
  94. }
  95. m_pChannelClient = new ChannelClient(this);
  96. Error = m_pChannelClient->Connect();
  97. if (Error != Error_Succeed) {
  98. m_pChannelClient->SafeDelete();
  99. return Error;
  100. }
  101. ChannelService_BeginRecv_Sub Sub;
  102. Sub.type = ACM_TYPE_PHT;
  103. Error = m_pChannelClient->BeginRecv(Sub);
  104. if (Error != Error_Succeed) {
  105. m_pChannelClient->GetFunction()->CloseSession();
  106. m_pChannelClient->SafeDelete();
  107. m_pChannelClient = NULL;
  108. return Error;
  109. }
  110. CSmartPointer<IEntityFunction> spFunc = GetFunction();
  111. int i = 0;
  112. m_arrListener.Init(4);
  113. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV);
  114. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_OPT);
  115. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT);
  116. spFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE,NULL,false);
  117. return Error;
  118. }
  119. ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
  120. {
  121. LOG_FUNCTION();
  122. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  123. for (int i = 0; i < m_arrListener.GetCount(); ++i)
  124. {
  125. spFunction->UnsubscribeLog(m_arrListener[i]);
  126. }
  127. if (preOperationError != Error_Succeed)
  128. return preOperationError;
  129. if (m_pChannelClient) {
  130. m_pChannelClient->GetFunction()->CloseSession();
  131. m_pChannelClient->SafeDelete();
  132. m_pChannelClient = NULL;
  133. }
  134. delete m_video_env_q;
  135. delete m_video_opt_q;
  136. return Error_Succeed;
  137. }
  138. void WriteStamp(video_frame *srcfrm)
  139. {
  140. __try {
  141. CImageFrame frm;
  142. frm.data = srcfrm->data[0];
  143. frm.width = srcfrm->width;
  144. frm.height = srcfrm->height;
  145. frm.framesize = srcfrm->width * srcfrm->height * 3;
  146. if (!SnapShot(&frm)) {
  147. Dbg("write stamp failed!");
  148. }
  149. } __except(EXCEPTION_EXECUTE_HANDLER) {
  150. Dbg("snapshot throw windows exception!");
  151. }
  152. }
  153. void Capture(int rc)
  154. {
  155. video_frame *frm = NULL;
  156. if((rc == 0)||(rc==Error_TimeOut))
  157. {
  158. if (m_video_env_q && m_video_opt_q)
  159. {
  160. int combine_width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  161. int combine_height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH + REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  162. frm = video_frame_new(combine_width, combine_height, VIDEO_FORMAT_RGB24);
  163. video_frame_fill_black(frm);
  164. // get env snapshot
  165. {
  166. video_frame tmp_frm = {0};
  167. tmp_frm.data[0] = frm->data[0];
  168. tmp_frm.linesize[0] = frm->linesize[0];
  169. tmp_frm.format = frm->format;
  170. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  171. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  172. DWORD time = m_video_env_q->GetLastFrameTime();
  173. if ((y2k_time_now()-time) < 15)
  174. {
  175. m_video_env_q->GetVideo2(&tmp_frm, 0);
  176. }
  177. else
  178. {
  179. Dbg("the env snapshot videoqueque image timeout!");
  180. }
  181. }
  182. // get opt snapshot
  183. {
  184. video_frame tmp_frm = {0};
  185. 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;
  186. tmp_frm.linesize[0] = frm->linesize[0];
  187. tmp_frm.format = frm->format;
  188. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  189. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  190. DWORD time = m_video_opt_q->GetLastFrameTime();
  191. if ((y2k_time_now()-time) < 10)
  192. {
  193. m_video_opt_q->GetVideo2(&tmp_frm, 0);
  194. }
  195. else
  196. {
  197. Dbg("the opt snapshot videoqueque image timeout!");
  198. }
  199. }
  200. }
  201. else if (m_video_env_q)
  202. {
  203. frm = video_frame_new(REC_COMMON_VIDEO_SNAPSHOT_WIDTH, REC_COMMON_VIDEO_SNAPSHOT_HEIGHT, VIDEO_FORMAT_RGB24);
  204. video_frame_fill_black(frm);
  205. video_frame tmp_frm = {0};
  206. tmp_frm.data[0] = frm->data[0];
  207. tmp_frm.linesize[0] = frm->linesize[0];
  208. tmp_frm.format = frm->format;
  209. tmp_frm.width = REC_COMMON_VIDEO_SNAPSHOT_WIDTH;
  210. tmp_frm.height = REC_COMMON_VIDEO_SNAPSHOT_HEIGHT;
  211. DWORD time = m_video_env_q->GetLastFrameTime();
  212. if ((y2k_time_now()-time) < 15)
  213. {
  214. m_video_env_q->GetVideo2(&tmp_frm, 0);
  215. }
  216. else
  217. {
  218. Dbg("the env snapshot videoqueque image timeout!");
  219. }
  220. }
  221. else
  222. {
  223. //assert(0); // not go here
  224. rc = -1;
  225. }
  226. }
  227. jpeg2k_coded_image codec_image = {0};
  228. if((rc == 0)||(rc==Error_TimeOut))
  229. {
  230. WriteStamp(frm);
  231. jpeg2k_raw_image raw_image;
  232. raw_image.data = frm->data[0];
  233. raw_image.width = frm->width;
  234. raw_image.height = frm->height;
  235. raw_image.len = raw_image.width * raw_image.height * 3;
  236. rc = jpeg2k_encode(&raw_image, &codec_image, 10);
  237. }
  238. if ((rc == 0)||(rc==Error_TimeOut))
  239. {
  240. ChannelService_Send_Info Info;
  241. Info.compress = false;
  242. Info.encrypt = false;
  243. Info.type = ACM_TYPE_PHT;
  244. Info.id = 0;
  245. Info.sub_type = ACM_PHT_ANS | ACM_PHT_SNAPSHOT;
  246. Info.data.m_pData = codec_image.data;
  247. Info.data.m_iLength = codec_image.len;
  248. m_pChannelClient->Send(Info);
  249. jpeg2k_encode_free(&codec_image);
  250. }
  251. else
  252. {
  253. ChannelService_Send_Info Info;
  254. Info.compress = false;
  255. Info.encrypt = false;
  256. Info.type = ACM_TYPE_PHT;
  257. Info.id = 0;
  258. Info.sub_type = ACM_PHT_ANS | ACM_PHT_SNAPSHOT;
  259. Info.data.m_pData = &rc;
  260. Info.data.m_iLength = sizeof(rc);
  261. m_pChannelClient->Send(Info);
  262. }
  263. if (frm)
  264. video_frame_delete(frm);
  265. }
  266. ErrorCodeEnum StartCapture(int id)
  267. {
  268. if (!m_video_env_q && !m_video_opt_q) {
  269. Dbg("cannot start capture!"); // never go here
  270. return Error_Unexpect;
  271. }
  272. if (m_dwCapture) {
  273. LOG_TRACE("already start capture!");
  274. return Error_Duplication;
  275. }
  276. //触发对应的摄像头进行图像采集
  277. if (m_video_env_q && m_video_opt_q)
  278. {
  279. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_ENVOPT, "agent start capture env and opt camera picture!");
  280. }
  281. else if (m_video_env_q)
  282. {
  283. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_ENV, "agent start capture env camera picture!");
  284. }
  285. else if (m_video_opt_q)
  286. {
  287. LogEvent(Severity_Middle, MOD_EVENT_SNAPSHOT_START_CAPTURE_OPT, "agent start capture opt camera picture!");
  288. }
  289. m_dwCapture = GetTickCount();
  290. GetFunction()->SetTimer(1, this, 2000);
  291. return Error_Succeed;
  292. }
  293. void StopCapture()
  294. {
  295. GetFunction()->KillTimer(1);
  296. m_dwCapture = 0;
  297. }
  298. virtual void OnTimeout(DWORD dwTimerID)
  299. {
  300. Capture(Error_TimeOut);
  301. Dbg("timeout!");
  302. GetFunction()->KillTimer(dwTimerID);
  303. m_dwCapture = 0;
  304. }
  305. virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  306. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  307. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage)
  308. {
  309. if (dwUserCode == MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENVOPT ||
  310. dwUserCode == MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_OPT ||
  311. dwUserCode == MOD_EVENT_MEDIACONTROLLER_FINISHED_CAPTURE_ENV)
  312. {
  313. DWORD dwNow = GetTickCount();
  314. LOG_TRACE("capture duration:%dms", dwNow - m_dwCapture);
  315. Capture(Error_Succeed);
  316. StopCapture();
  317. }
  318. else if (dwUserCode == LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE)
  319. {
  320. Dbg("recv LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE");
  321. if (m_pChannelClient != NULL)
  322. {
  323. m_pChannelClient->GetFunction()->CloseSession();
  324. m_pChannelClient->SafeDelete();
  325. m_pChannelClient = NULL;
  326. Dbg("Close AssistChannel Session ");
  327. }
  328. if (m_pChannelClient == NULL)
  329. {
  330. Dbg("ReConnection AssistChannel Session");
  331. m_pChannelClient = new ChannelClient(this);
  332. ErrorCodeEnum Error = m_pChannelClient->Connect();
  333. if (Error != Error_Succeed)
  334. {
  335. m_pChannelClient->SafeDelete();
  336. m_pChannelClient = NULL;
  337. Dbg("AssistChannelClient connect fail!");
  338. }
  339. if (Error == Error_Succeed)
  340. {
  341. ChannelService_BeginRecv_Sub Sub;
  342. Sub.type = ACM_TYPE_PHT;
  343. Error = m_pChannelClient->BeginRecv(Sub);
  344. if (Error != Error_Succeed)
  345. {
  346. m_pChannelClient->GetFunction()->CloseSession();
  347. m_pChannelClient->SafeDelete();
  348. m_pChannelClient = NULL;
  349. }
  350. }
  351. }
  352. }
  353. }
  354. private:
  355. // we use root.ini Video section config to decide camera count
  356. ErrorCodeEnum DecideCameraCount(int &nCount)
  357. {
  358. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  359. CSmartPointer<IConfigInfo> spConfig;
  360. ErrorCodeEnum Error = spFunction->OpenConfig(Config_Root, spConfig);
  361. if (Error == Error_Succeed)
  362. {
  363. CSimpleStringA strVideoEnv;
  364. CSimpleStringA strVideoOpt;
  365. SpIniMappingTable table;
  366. nCount = 0;
  367. table.AddEntryString("Video", "EnvCamera", strVideoEnv, "$");
  368. table.AddEntryString("Video", "OptCamera", strVideoOpt, "$");
  369. Error = table.Load(spConfig);
  370. if (Error == Error_Succeed)
  371. {
  372. if (strVideoEnv.GetLength() > 1)
  373. nCount++;
  374. if (strVideoOpt.GetLength() > 1)
  375. nCount++;
  376. }
  377. }
  378. return Error;
  379. }
  380. private:
  381. Clibvideoqueue *m_video_env_q;
  382. Clibvideoqueue *m_video_opt_q;
  383. ChannelClient *m_pChannelClient;
  384. CUUID m_uuidCaptureTimer;
  385. DWORD m_dwCapture;
  386. DeviceTypeEnum m_eDeviceType;
  387. CAutoArray<CUUID> m_arrListener;
  388. };
  389. void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
  390. {
  391. LOG_FUNCTION();
  392. if (Error == Error_Succeed) {
  393. CPhotoCaptureEntity *pEntity = static_cast<CPhotoCaptureEntity*>(m_pEntityBase);
  394. int cat = ACM_PHT_CAT(Msg.sub_type);
  395. if (cat == ACM_PHT_REQ)
  396. {
  397. Error = pEntity->StartCapture(Msg.id);
  398. if (Error)
  399. {
  400. pEntity->Capture(Error);
  401. }
  402. }
  403. else
  404. {
  405. _ASSERT(0);
  406. }
  407. }
  408. }
  409. ChannelClient::ChannelClient( CPhotoCaptureEntity *pEntity ) : ChannelService_ClientBase(pEntity)
  410. {
  411. }
  412. SP_BEGIN_ENTITY_MAP()
  413. SP_ENTITY(CPhotoCaptureEntity)
  414. SP_END_ENTITY_MAP()