mod_screenshot.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "screencapture.h"
  4. #include <screencodec.h>
  5. #include "videoutil.h"
  6. #include "rvc_media_common.h"
  7. #include "mod_assistantchannel/AssistantChannel_client_g.h"
  8. using namespace AssistantChannel;
  9. #include "mod_assistantchannel/chan_protocol.h"
  10. #include "mod_assistantchannel/VideoDesc.h"
  11. // add by ly 20150514
  12. #include "jpeg2k.h"
  13. #include "ScreenShot_server_g.h"
  14. #include "cv.h"
  15. #include "highgui.h"
  16. #include "cxcore.h"
  17. #include "CommEntityUtil.hpp"
  18. #include "../include/EventCode.h"
  19. using namespace ScreenShot;
  20. // step 1 screen capture
  21. // step 2 compress using libpng
  22. // step 3 split to 56k each chunk to send out
  23. // future improvement:
  24. // 1. adding 8bit depth color options
  25. // 2. adding business zone options
  26. class CScreenCaptureEntity;
  27. class CScreenShotSession: public ScreenShotService_ServerSessionBase
  28. {
  29. public:
  30. CScreenShotSession(CScreenCaptureEntity* pEntity, int id) : m_id(id), m_pEntity(pEntity)
  31. {
  32. }
  33. virtual void Handle_StartScreenShot(SpReqAnsContext<ScreenShotService_StartScreenShot_Req, ScreenShotService_StartScreenShot_Ans>::Pointer ctx);
  34. virtual void OnClose( ErrorCodeEnum eErrorCode );
  35. private:
  36. int m_id;
  37. CScreenCaptureEntity* m_pEntity;
  38. };
  39. class ChannelClient : public ChannelService_ClientBase
  40. {
  41. public:
  42. ChannelClient(CScreenCaptureEntity *pEntity);
  43. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData);
  44. virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData);
  45. };
  46. int RotationDown(unsigned char* src, int srcW, int srcH, int channel)
  47. {
  48. unsigned char* tempSrc = NULL;
  49. int mSize = srcW * srcH * sizeof(char) * channel;
  50. int i = 0;
  51. int j = 0;
  52. int k = 0;
  53. int desW = 0;
  54. int desH = 0;
  55. desW = srcW;
  56. desH = srcH;
  57. tempSrc = (unsigned char*)malloc(sizeof(char) * srcW * srcH * channel);
  58. memcpy(tempSrc, src, mSize);
  59. for (i = 0; i < desH; i++)
  60. {
  61. for (j = 0; j < desW; j++)
  62. {
  63. for (k = 0; k < channel; k++)
  64. {
  65. //src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + srcW - 1 - j) * channel + k];
  66. src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + j) * channel + k];
  67. }
  68. }
  69. }
  70. free(tempSrc);
  71. return 0;
  72. }
  73. class CScreenCaptureEntity : public CEntityBase,public ILogListener, public ITimerListener
  74. {
  75. public:
  76. CScreenCaptureEntity() : m_enc_session(NULL), m_id_seq(0) {}
  77. virtual ~CScreenCaptureEntity() {}
  78. virtual const char *GetEntityName() const { return "ScreenShot"; }
  79. virtual bool IsService() const { return true; }
  80. virtual CServerSessionBase *OnNewSession(const char* pszRemoteEntityName, const char * pszClass)
  81. {
  82. return new CScreenShotSession(this, m_id_seq++);
  83. }
  84. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  85. {
  86. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  87. pTransactionContext->SendAnswer(Error);
  88. }
  89. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  90. {
  91. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  92. pTransactionContext->SendAnswer(Error);
  93. }
  94. virtual void OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  95. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  96. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
  97. {
  98. if (dwUserCode == LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS)
  99. {
  100. Sleep(970);
  101. if (NULL != m_pChannelClient){
  102. m_pChannelClient->GetFunction()->CloseSession();
  103. m_pChannelClient = NULL;
  104. m_bConnectAssist = false;
  105. }
  106. if (Error_Succeed == ConnectAssistChannel()) {
  107. m_bConnectAssist = true;
  108. }
  109. else {
  110. GetFunction()->SetTimer(1, this, 3370);
  111. }
  112. }
  113. }
  114. virtual void OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  115. {
  116. if (Test_ShakeHand == eTestType)
  117. {
  118. pTransactionContext->SendAnswer(Error_Succeed);
  119. }
  120. }
  121. ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
  122. {
  123. CSmartPointer<IEntityFunction> pFunc = GetFunction();
  124. int i = 0;
  125. m_arrListener.Init(1);
  126. pFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS,NULL,false);
  127. if (preOperationError != Error_Succeed)
  128. return preOperationError;
  129. //is Pad Version
  130. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  131. CSystemStaticInfo stStaticinfo;
  132. spFunction->GetSystemStaticInfo(stStaticinfo);
  133. if (stricmp(stStaticinfo.strMachineType,"RVC.WALL")==0)
  134. {
  135. m_bIsWallMachine = true;
  136. }
  137. else
  138. {
  139. m_bIsWallMachine = false;
  140. }
  141. return Error_Succeed;
  142. }
  143. void OnStarted()
  144. {
  145. m_pChannelClient = new ChannelClient(this);
  146. if (Error_Succeed == ConnectAssistChannel()) {
  147. m_bConnectAssist = true;
  148. }
  149. else {
  150. GetFunction()->SetTimer(1, this, 3370);
  151. }
  152. }
  153. ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
  154. {
  155. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  156. for (int i = 0; i < m_arrListener.GetCount(); ++i)
  157. {
  158. spFunction->UnsubscribeLog(m_arrListener[i]);
  159. }
  160. if (preOperationError != Error_Succeed)
  161. return preOperationError;
  162. m_pChannelClient->GetFunction()->CloseSession();
  163. m_pChannelClient = NULL;
  164. return Error_Succeed;
  165. }
  166. ErrorCodeEnum InitCapture()
  167. {
  168. if (m_enc_session) {
  169. screen_encoder_session_destroy(m_enc_session);
  170. m_enc_session = NULL;
  171. }
  172. #ifdef RVC_OS_WIN
  173. int cx = GetSystemMetrics(SM_CXSCREEN);
  174. int cy = GetSystemMetrics(SM_CYSCREEN);
  175. #else
  176. int cx, cy;
  177. getScreenSize(&cx, &cy);
  178. #endif
  179. if (m_bIsWallMachine)
  180. {
  181. cy = cy-640;
  182. }
  183. screen_encoder_session_create(cx, cy, &m_enc_session);
  184. return Error_Succeed;
  185. }
  186. void ExitCapture()
  187. {
  188. if (m_enc_session) {
  189. screen_encoder_session_destroy(m_enc_session);
  190. m_enc_session = NULL;
  191. }
  192. }
  193. void Capture(int id)
  194. {
  195. CSystemStaticInfo SysInfo;
  196. #ifdef RVC_OS_WIN
  197. int cx = GetSystemMetrics(SM_CXSCREEN);
  198. int cy = GetSystemMetrics(SM_CYSCREEN);
  199. #else
  200. int cx, cy;
  201. getScreenSize(&cx, &cy);
  202. #endif
  203. RECT rc = {0, 0, cx, cy};
  204. int size = 0;
  205. int err = screencapture_capture(&rc, NULL, &size);
  206. if (err != 0) {
  207. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  208. return;
  209. }
  210. void *buf = malloc(size);
  211. err = screencapture_capture(&rc, buf, &size);
  212. if (err != 0) {
  213. free(buf);
  214. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  215. return;
  216. }
  217. if((SysInfo.eScreen == 1)&&!m_bIsWallMachine)
  218. {
  219. CSimpleStringA strValue;
  220. ErrorCodeEnum Error = GetFunction()->GetSysVar("VideoWindowInitializeParam", strValue);
  221. if (Error == Error_Succeed)
  222. {
  223. int local_view_x;
  224. int local_view_y;
  225. int local_view_cx;
  226. int local_view_cy;
  227. int remote_view_x;
  228. int remote_view_y;
  229. int remote_view_cx;
  230. int remote_view_cy;
  231. ParseVideoViewParam((LPCSTR)strValue, local_view_x, local_view_y, local_view_cx, local_view_cy,
  232. remote_view_x, remote_view_y, remote_view_cx, remote_view_cy);
  233. RECT rcs[] = {
  234. {local_view_x, cy - local_view_y - local_view_cy, local_view_x+local_view_cx, cy - local_view_y},
  235. {remote_view_x, cy - remote_view_y - remote_view_cy, remote_view_x+remote_view_cx, cy - remote_view_y},
  236. };
  237. screencapture_clipoff(cx, cy, buf, 2, rcs);
  238. }
  239. }
  240. #ifndef RVC_OS_WIN
  241. {
  242. //linux需翻转图像
  243. int width = rc.right - rc.left;
  244. int height = rc.bottom - rc.top;
  245. RotationDown((unsigned char*)buf, width, height, 3);
  246. }
  247. #endif
  248. ChannelService_Send_Info Info;
  249. Info.compress = false;
  250. Info.encrypt = false;
  251. Info.type = ACM_TYPE_SRN;
  252. Info.id = id;
  253. Info.sub_type = ACM_SRN_ANS | ACM_SRN_SNAPSHOT;
  254. if (m_bIsWallMachine)
  255. {
  256. int width = rc.right - rc.left;
  257. int height = rc.bottom - 640;
  258. int linesize = (width * 3 + 3) & 0xfffffffc;
  259. int newsize = linesize * height;
  260. Info.data.Alloc(newsize);
  261. void *buftmp = malloc(newsize);
  262. memcpy(buftmp,buf,newsize);
  263. screen_encoder_session_encode(m_enc_session, buftmp, Info.data.m_pData, &Info.data.m_iLength);
  264. (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info);
  265. free(buftmp);
  266. }
  267. else
  268. {
  269. Info.data.Alloc(size);
  270. screen_encoder_session_encode(m_enc_session, buf, Info.data.m_pData, &Info.data.m_iLength);
  271. (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info);
  272. }
  273. #if 0
  274. int linesize = size / cy;
  275. video_frame tmp_frame;
  276. video_frame_alloc(linesize/3, cy, VIDEO_FORMAT_RGB24, &tmp_frame);
  277. video_frame_fill_black(&tmp_frame);
  278. memcpy(tmp_frame.data[0], buf, size);
  279. video_frame_save_bmpfile("screenshot_abc.bmp", &tmp_frame);
  280. video_frame_free(&tmp_frame);
  281. //video_frame_save_bmpfile("d:\\ab.bmp", &rtp_frame);
  282. #endif
  283. free(buf);
  284. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("encode size = %d Bytes, time = %d", Info.data.m_iLength, GetTickCount());
  285. }
  286. void Capture1(int id)
  287. {
  288. CSystemStaticInfo SysInfo;
  289. #ifdef RVC_OS_WIN
  290. int cx = GetSystemMetrics(SM_CXSCREEN);
  291. int cy = GetSystemMetrics(SM_CYSCREEN);
  292. #else
  293. int cx, cy;
  294. getScreenSize(&cx, &cy);
  295. #endif
  296. RECT rc = {0, 0, cx, cy};
  297. int size = 0;
  298. int err = screencapture_capture(&rc, NULL, &size);
  299. if (err != 0) {
  300. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  301. return;
  302. }
  303. void *buf = malloc(size);
  304. err = screencapture_capture(&rc, buf, &size);
  305. if (err != 0) {
  306. free(buf);
  307. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  308. return;
  309. }
  310. if (SysInfo.eScreen == 1) {
  311. CSimpleStringA strValue;
  312. ErrorCodeEnum Error = GetFunction()->GetSysVar("VideoWindowInitializeParam", strValue);
  313. if (Error == Error_Succeed) {
  314. int local_view_x;
  315. int local_view_y;
  316. int local_view_cx;
  317. int local_view_cy;
  318. int remote_view_x;
  319. int remote_view_y;
  320. int remote_view_cx;
  321. int remote_view_cy;
  322. ParseVideoViewParam((LPCSTR)strValue, local_view_x, local_view_y, local_view_cx, local_view_cy,
  323. remote_view_x, remote_view_y, remote_view_cx, remote_view_cy);
  324. RECT rcs[] = {
  325. {local_view_x, cy - local_view_y - local_view_cy, local_view_x+local_view_cx, cy - local_view_y},
  326. {remote_view_x, cy - remote_view_y - remote_view_cy, remote_view_x+remote_view_cx, cy - remote_view_y},
  327. };
  328. screencapture_clipoff(cx, cy, buf, 2, rcs);
  329. }
  330. }
  331. #ifndef RVC_OS_WIN
  332. //linux需翻转图像
  333. int width = rc.right - rc.left;
  334. int height = rc.bottom - rc.top;
  335. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("size = %d, 3*width*height= %d", size, 3 * width * height);
  336. RotationDown((unsigned char*)buf, width, height, 3);
  337. #endif
  338. ChannelService_Send_Info Info;
  339. Info.compress = false;
  340. Info.encrypt = false;
  341. Info.type = ACM_TYPE_SRN;
  342. Info.id = id;
  343. Info.sub_type = ACM_SRN_ANS | ACM_SRN_SNAPSHOT;
  344. Info.data.Alloc(size);
  345. screencapture_encode(cx, cy, buf, Info.data.m_pData, &Info.data.m_iLength);
  346. (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info);
  347. free(buf);
  348. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("encode size = %d Bytes, time = %d", Info.data.m_iLength, GetTickCount());
  349. }
  350. void Capture2(RECT *lprc, CBlob &image)
  351. {
  352. int width = lprc->right-lprc->left;
  353. int height = lprc->bottom-lprc->top;
  354. int size = 0;
  355. int err = screencapture_capture(lprc, NULL, &size);
  356. if (err != 0) {
  357. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  358. return;
  359. }
  360. void *buf = malloc(size);
  361. err = screencapture_capture(lprc, buf, &size);
  362. if (err != 0) {
  363. free(buf);
  364. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("capture screen failed! %d", err);
  365. return;
  366. }
  367. #ifndef RVC_OS_WIN
  368. //linux需翻转图像
  369. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("size = %d, 3*width*height= %d", size, 3*width*height);
  370. RotationDown((unsigned char*)buf, width, height, 3);
  371. #endif
  372. // encode with jpeg2k
  373. jpeg2k_coded_image codec_image = {0};
  374. jpeg2k_raw_image raw_image;
  375. raw_image.data = (BYTE*)buf;
  376. raw_image.width = width;
  377. raw_image.height = height;
  378. raw_image.len = raw_image.width * raw_image.height * 3;
  379. int nRet = jpeg2k_encode(&raw_image, &codec_image, 30); // ratio越小质量越好
  380. if (nRet == 0 || nRet == Error_TimeOut)
  381. {
  382. size = codec_image.len;
  383. image.Alloc(size);
  384. memmove(image.m_pData, codec_image.data, size);
  385. //char tmp[MAX_PATH];
  386. //static int seq = 0;
  387. //sprintf(tmp, ".\\jietu_%08d.jp2", seq++);
  388. //FILE *fp = fopen(tmp, "wb");
  389. //if (fp) {
  390. // fwrite(codec_image.data,1,size, fp);
  391. // fclose(fp);
  392. //}
  393. image.Resize(size);
  394. jpeg2k_encode_free(&codec_image);
  395. }
  396. free(buf);
  397. }
  398. private:
  399. ErrorCodeEnum ConnectAssistChannel()
  400. {
  401. if (NULL == m_pChannelClient){
  402. m_pChannelClient = new ChannelClient(this);
  403. }
  404. ErrorCodeEnum Error = m_pChannelClient->Connect();
  405. if (Error != Error_Succeed){
  406. m_pChannelClient = NULL;
  407. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("AssistChannelClient connect fail!");
  408. return Error;
  409. }
  410. if (Error == Error_Succeed){
  411. ChannelService_BeginRecv_Sub Sub;
  412. Sub.type = ACM_TYPE_SRN;
  413. Error = (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->BeginRecv(Sub);
  414. if (Error != Error_Succeed){
  415. m_pChannelClient->GetFunction()->CloseSession();
  416. m_pChannelClient = NULL;
  417. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("BeginRecv ACM_TYPE_SRN fail!");
  418. return Error;
  419. }
  420. }
  421. if (Error == Error_Succeed){
  422. ChannelService_BeginState_Sub Sub;
  423. Error = (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->BeginState(Sub);
  424. if (Error != Error_Succeed){
  425. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("BeginState biz channel failed!");
  426. m_pChannelClient->GetFunction()->CloseSession();
  427. m_pChannelClient = NULL;
  428. return Error;
  429. }
  430. }
  431. return Error;
  432. }
  433. void OnTimeout(DWORD dwTimerID)
  434. {
  435. if (1 == dwTimerID)
  436. {
  437. if (!m_bConnectAssist) {
  438. if (Error_Succeed == ConnectAssistChannel()) {
  439. m_bConnectAssist = true;
  440. }
  441. }
  442. if (m_bConnectAssist) {
  443. GetFunction()->KillTimer(1);
  444. }
  445. }
  446. }
  447. private:
  448. screen_encoder_session_t *m_enc_session;
  449. ChannelClient *m_pChannelClient;
  450. CAutoArray<CUUID> m_arrListener;
  451. int m_id_seq;
  452. bool m_bIsWallMachine;
  453. bool m_bConnectAssist;
  454. };
  455. void CScreenShotSession::Handle_StartScreenShot(SpReqAnsContext<ScreenShotService_StartScreenShot_Req, ScreenShotService_StartScreenShot_Ans>::Pointer ctx)
  456. {
  457. DbgToBeidou(ctx->link, __FUNCTION__)();
  458. #ifdef RVC_OS_WIN
  459. int cx = GetSystemMetrics(SM_CXSCREEN);
  460. int cy = GetSystemMetrics(SM_CYSCREEN);
  461. #else
  462. int cx, cy;
  463. getScreenSize(&cx, &cy);
  464. #endif
  465. if (ctx->Req.Left < 0 || ctx->Req.Left > cx || ctx->Req.Width <= 0 || ctx->Req.Width > cx ||
  466. ctx->Req.Top < 0 || ctx->Req.Top > cy || ctx->Req.Height <= 0 || ctx->Req.Height > cy)
  467. {
  468. ctx->Answer(Error_Unexpect);
  469. }
  470. RECT rc = {ctx->Req.Left, ctx->Req.Top, ctx->Req.Left + ctx->Req.Width, ctx->Req.Top + ctx->Req.Height};
  471. m_pEntity->Capture2(&rc, ctx->Ans.Image);
  472. if (ctx->Ans.Image.m_iLength == 0)
  473. {
  474. ctx->Answer(Error_Unexpect);
  475. }
  476. else
  477. {
  478. ctx->Answer(Error_Succeed);
  479. }
  480. }
  481. void CScreenShotSession::OnClose( ErrorCodeEnum eErrorCode )
  482. {
  483. }
  484. void ChannelClient::OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData)
  485. {
  486. if (Error == Error_Succeed) {
  487. CScreenCaptureEntity *pEntity = static_cast<CScreenCaptureEntity*>(m_pEntityBase);
  488. if (Msg.state == eChannelState_Idle) {
  489. pEntity->ExitCapture();
  490. } else if (Msg.state == eChannelState_Connected) {
  491. pEntity->InitCapture();
  492. }
  493. }
  494. }
  495. void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
  496. {
  497. if (Error == Error_Succeed) {
  498. CScreenCaptureEntity *pEntity = static_cast<CScreenCaptureEntity*>(m_pEntityBase);
  499. int cat = ACM_SRN_CAT(Msg.sub_type);
  500. if (cat == ACM_SRN_REQ) {
  501. //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
  502. pEntity->Capture(Msg.id);
  503. //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
  504. } else {
  505. _ASSERT(0);
  506. }
  507. }
  508. }
  509. ChannelClient::ChannelClient( CScreenCaptureEntity *pEntity ) : ChannelService_ClientBase(pEntity)
  510. {
  511. }
  512. SP_BEGIN_ENTITY_MAP()
  513. SP_ENTITY(CScreenCaptureEntity)
  514. SP_END_ENTITY_MAP()