123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- #include "stdafx.h"
- #include "SpBase.h"
- #include "screencapture.h"
- #include <screencodec.h>
- #include "../..//Other/libvideoframework/videoutil.h"
- #include "../../Other/rvcmediacommon/rvc_media_common.h"
- #include "mod_assistantchannel/AssistantChannel_client_g.h"
- using namespace AssistantChannel;
- #include "mod_assistantchannel/chan_protocol.h"
- #include "mod_assistantchannel/VideoDesc.h"
- // add by ly 20150514
- #include "jpeg2k.h"
- #include "ScreenShot_server_g.h"
- #include "cv.h"
- #include "highgui.h"
- #include "cxcore.h"
- #include "CommEntityUtil.hpp"
- using namespace ScreenShot;
- #define LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE 0x50500001 //协助通道重启
- // step 1 screen capture
- // step 2 compress using libpng
- // step 3 split to 56k each chunk to send out
- // future improvement:
- // 1. adding 8bit depth color options
- // 2. adding business zone options
- class CScreenCaptureEntity;
- // add by ly 20150514
- class CScreenShotSession: public ScreenShotService_ServerSessionBase
- {
- public:
- CScreenShotSession(CScreenCaptureEntity* pEntity, int id) : m_id(id), m_pEntity(pEntity)
- {
- }
- virtual void Handle_StartScreenShot(SpReqAnsContext<ScreenShotService_StartScreenShot_Req, ScreenShotService_StartScreenShot_Ans>::Pointer ctx);
-
- virtual void OnClose( ErrorCodeEnum eErrorCode );
- private:
- int m_id;
- CScreenCaptureEntity* m_pEntity;
- };
- class ChannelClient : public ChannelService_ClientBase
- {
- public:
- ChannelClient(CScreenCaptureEntity *pEntity);
- virtual void OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData);
- virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData);
- };
- // 旋转180度
- int RotationDown(unsigned char* src, int srcW, int srcH, int channel)
- {
- unsigned char* tempSrc = NULL;
- int mSize = srcW * srcH * sizeof(char) * channel;
- int i = 0;
- int j = 0;
- int k = 0;
- int desW = 0;
- int desH = 0;
- desW = srcW;
- desH = srcH;
- tempSrc = (unsigned char*)malloc(sizeof(char) * srcW * srcH * channel);
- memcpy(tempSrc, src, mSize);
- for (i = 0; i < desH; i++)
- {
- for (j = 0; j < desW; j++)
- {
- for (k = 0; k < channel; k++)
- {
- //src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + srcW - 1 - j) * channel + k];
- src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - i) * srcW + j) * channel + k];
- }
- }
- }
- free(tempSrc);
- return 0;
- }
- class CScreenCaptureEntity : public CEntityBase,public ILogListener
- {
- public:
- CScreenCaptureEntity() : m_enc_session(NULL), m_id_seq(0) {}
- virtual ~CScreenCaptureEntity() {}
- virtual const char *GetEntityName() const { return "ScreenShot"; }
- // add by ly 20150514
- virtual bool IsService() const { return true; }
- // add by ly 20150514
- virtual CServerSessionBase *OnNewSession(const char* pszRemoteEntityName, const char * pszClass)
- {
- LOG_FUNCTION();
- LOG_TRACE("%s connected class = %s!", pszRemoteEntityName, pszClass);
- return new CScreenShotSession(this, m_id_seq++);
- }
- virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
- {
- ErrorCodeEnum Error = __OnStart(Error_Succeed);
- pTransactionContext->SendAnswer(Error);
- }
- virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
- {
- ErrorCodeEnum Error = __OnClose(Error_Succeed);
- pTransactionContext->SendAnswer(Error);
- }
- virtual void 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)
- {
- if (dwUserCode == LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE)
- {
- Dbg("recv LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE");
- if (m_pChannelClient!=NULL)
- {
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- Dbg("Close AssistChannel Session ");
- }
- if (m_pChannelClient == NULL)
- {
- Dbg("ReConnection AssistChannel Session");
- m_pChannelClient = new ChannelClient(this);
- ErrorCodeEnum Error = m_pChannelClient->Connect();
- if (Error != Error_Succeed)
- {
- m_pChannelClient->SafeDelete();
- m_pChannelClient = NULL;
- Dbg("AssistChannelClient connect fail!");
- }
- if (Error == Error_Succeed)
- {
- ChannelService_BeginRecv_Sub Sub;
- Sub.type = ACM_TYPE_SRN;
- Error = m_pChannelClient->BeginRecv(Sub);
- if (Error != Error_Succeed)
- {
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- }
- }
- if (Error == Error_Succeed)
- {
- ChannelService_BeginState_Sub Sub;
- Error = m_pChannelClient->BeginState(Sub);
- if (Error != Error_Succeed)
- {
- LOG_TRACE("BeginState biz channel failed!");
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- }
- }
- }
- }
- }
- virtual void OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
- {
- if (Test_ShakeHand == eTestType)
- {
- pTransactionContext->SendAnswer(Error_Succeed);
- }
- }
- ErrorCodeEnum __OnStart(ErrorCodeEnum preOperationError)
- {
- LOG_FUNCTION();
- CSmartPointer<IEntityFunction> pFunc = GetFunction();
- int i = 0;
- m_arrListener.Init(1);
- pFunc->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE,NULL,false);
- if (preOperationError != Error_Succeed)
- return preOperationError;
- //is Pad Version
- CSmartPointer<IEntityFunction> spFunction = GetFunction();
- CSystemStaticInfo stStaticinfo;
- spFunction->GetSystemStaticInfo(stStaticinfo);
- if (stricmp(stStaticinfo.strMachineType,"RVC.WALL")==0)
- {
- m_bIsWallMachine = TRUE;
- Dbg("the machine type is rvc.wall");
- }
- else
- {
- m_bIsWallMachine = FALSE;
- }
- ErrorCodeEnum Error;
- m_pChannelClient = new ChannelClient(this);
- Error = m_pChannelClient->Connect();
- if (Error != Error_Succeed) {
- m_pChannelClient->SafeDelete();
- return Error;
- }
- if (Error == Error_Succeed) {
- ChannelService_BeginRecv_Sub Sub;
- Sub.type = ACM_TYPE_SRN;
- Error = m_pChannelClient->BeginRecv(Sub);
- if (Error != Error_Succeed) {
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- return Error;
- }
- }
- if (Error == Error_Succeed) {
- ChannelService_BeginState_Sub Sub;
- Error = m_pChannelClient->BeginState(Sub);
- if (Error != Error_Succeed) {
- LOG_TRACE("BeginState biz channel failed!");
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- }
- }
- return Error;
- }
- ErrorCodeEnum __OnClose(ErrorCodeEnum preOperationError)
- {
- LOG_FUNCTION();
- CSmartPointer<IEntityFunction> spFunction = GetFunction();
- for (int i = 0; i < m_arrListener.GetCount(); ++i)
- {
- spFunction->UnsubscribeLog(m_arrListener[i]);
- }
- if (preOperationError != Error_Succeed)
- return preOperationError;
- m_pChannelClient->GetFunction()->CloseSession();
- m_pChannelClient = NULL;
- return Error_Succeed;
- }
- void DumpCaptureDat(const char *buf, int n)
- {
- char tmp[MAX_PATH];
- static int seq = 0;
- sprintf(tmp, ".%scapture_%08d.dat", SPLIT_SLASH_STR, seq++);
- FILE *fp = fopen(tmp, "wb");
- if (fp)
- {
- fwrite(buf,1,n, fp);
- fclose(fp);
- }
- }
- ErrorCodeEnum InitCapture()
- {
- if (m_enc_session) {
- screen_encoder_session_destroy(m_enc_session);
- m_enc_session = NULL;
- }
- #ifdef RVC_OS_WIN
- int cx = GetSystemMetrics(SM_CXSCREEN);
- int cy = GetSystemMetrics(SM_CYSCREEN);
- #else
- int cx, cy;
- getScreenSize(&cx, &cy);
- #endif
- if (m_bIsWallMachine)
- {
- cy = cy-640;
- }
- screen_encoder_session_create(cx, cy, &m_enc_session);
- return Error_Succeed;
- }
- void ExitCapture()
- {
- if (m_enc_session) {
- screen_encoder_session_destroy(m_enc_session);
- m_enc_session = NULL;
- }
- }
- void Capture(int id)
- {
- CSystemStaticInfo SysInfo;
- #ifdef RVC_OS_WIN
- int cx = GetSystemMetrics(SM_CXSCREEN);
- int cy = GetSystemMetrics(SM_CYSCREEN);
- #else
- int cx, cy;
- getScreenSize(&cx, &cy);
- #endif
- RECT rc = {0, 0, cx, cy};
- int size = 0;
- int err = screencapture_capture(&rc, NULL, &size);
- if (err != 0) {
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- Dbg("capture screen, cx: %d, cy: %d, size: %d", cx, cy, size);
- void *buf = malloc(size);
- err = screencapture_capture(&rc, buf, &size);
- if (err != 0) {
- free(buf);
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- if((SysInfo.eScreen == 1)&&!m_bIsWallMachine)
- {
- CSimpleStringA strValue;
- ErrorCodeEnum Error = GetFunction()->GetSysVar("VideoWindowInitializeParam", strValue);
- if (Error == Error_Succeed)
- {
- int local_view_x;
- int local_view_y;
- int local_view_cx;
- int local_view_cy;
- int remote_view_x;
- int remote_view_y;
- int remote_view_cx;
- int remote_view_cy;
- ParseVideoViewParam((LPCSTR)strValue, local_view_x, local_view_y, local_view_cx, local_view_cy,
- remote_view_x, remote_view_y, remote_view_cx, remote_view_cy);
- RECT rcs[] = {
- {local_view_x, cy - local_view_y - local_view_cy, local_view_x+local_view_cx, cy - local_view_y},
- {remote_view_x, cy - remote_view_y - remote_view_cy, remote_view_x+remote_view_cx, cy - remote_view_y},
- };
- screencapture_clipoff(cx, cy, buf, 2, rcs);
- }
- }
- #ifndef RVC_OS_WIN
- {
- //linux需翻转图像
- int width = rc.right - rc.left;
- int height = rc.bottom - rc.top;
- Dbg("size = %d, 3*width*height= %d", size, 3 * width * height);
- RotationDown((unsigned char*)buf, width, height, 3);
- }
- #endif
- ChannelService_Send_Info Info;
- Info.compress = false;
- Info.encrypt = false;
- Info.type = ACM_TYPE_SRN;
- Info.id = id;
- Info.sub_type = ACM_SRN_ANS | ACM_SRN_SNAPSHOT;
- if (m_bIsWallMachine)
- {
- int width = rc.right - rc.left;
- int height = rc.bottom - 640;
- int linesize = (width * 3 + 3) & 0xfffffffc;
- int newsize = linesize * height;
- Info.data.Alloc(newsize);
- Dbg("width = %d,height = %d,linesize = %d,newsize = %d",width,height,linesize,newsize);
- void *buftmp = malloc(newsize);
- memcpy(buftmp,buf,newsize);
- screen_encoder_session_encode(m_enc_session, buftmp, Info.data.m_pData, &Info.data.m_iLength);
- m_pChannelClient->Send(Info);
- free(buftmp);
- }
- else
- {
- Info.data.Alloc(size);
- screen_encoder_session_encode(m_enc_session, buf, Info.data.m_pData, &Info.data.m_iLength);
- m_pChannelClient->Send(Info);
- }
- #if 0
- int linesize = size / cy;
- video_frame tmp_frame;
- video_frame_alloc(linesize/3, cy, VIDEO_FORMAT_RGB24, &tmp_frame);
- video_frame_fill_black(&tmp_frame);
- memcpy(tmp_frame.data[0], buf, size);
- video_frame_save_bmpfile("screenshot_abc.bmp", &tmp_frame);
- video_frame_free(&tmp_frame);
- //video_frame_save_bmpfile("d:\\ab.bmp", &rtp_frame);
- Dbg("capture screen, linesize: %d.", linesize);
- #endif
- free(buf);
- LOG_TRACE("encode size = %d Bytes, time = %d", Info.data.m_iLength, SP::Module::Comm::RVCGetTickCount());
- }
- void Capture1(int id)
- {
- CSystemStaticInfo SysInfo;
- #ifdef RVC_OS_WIN
- int cx = GetSystemMetrics(SM_CXSCREEN);
- int cy = GetSystemMetrics(SM_CYSCREEN);
- #else
- int cx, cy;
- getScreenSize(&cx, &cy);
- #endif
- RECT rc = {0, 0, cx, cy};
- int size = 0;
- int err = screencapture_capture(&rc, NULL, &size);
- if (err != 0) {
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- void *buf = malloc(size);
- err = screencapture_capture(&rc, buf, &size);
- if (err != 0) {
- free(buf);
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- if (SysInfo.eScreen == 1) {
- CSimpleStringA strValue;
- ErrorCodeEnum Error = GetFunction()->GetSysVar("VideoWindowInitializeParam", strValue);
- if (Error == Error_Succeed) {
- int local_view_x;
- int local_view_y;
- int local_view_cx;
- int local_view_cy;
- int remote_view_x;
- int remote_view_y;
- int remote_view_cx;
- int remote_view_cy;
- ParseVideoViewParam((LPCSTR)strValue, local_view_x, local_view_y, local_view_cx, local_view_cy,
- remote_view_x, remote_view_y, remote_view_cx, remote_view_cy);
- RECT rcs[] = {
- {local_view_x, cy - local_view_y - local_view_cy, local_view_x+local_view_cx, cy - local_view_y},
- {remote_view_x, cy - remote_view_y - remote_view_cy, remote_view_x+remote_view_cx, cy - remote_view_y},
- };
- screencapture_clipoff(cx, cy, buf, 2, rcs);
- }
- }
- #ifndef RVC_OS_WIN
- //linux需翻转图像
- int width = rc.right - rc.left;
- int height = rc.bottom - rc.top;
- Dbg("size = %d, 3*width*height= %d", size, 3 * width * height);
- RotationDown((unsigned char*)buf, width, height, 3);
- #endif
- ChannelService_Send_Info Info;
- Info.compress = false;
- Info.encrypt = false;
- Info.type = ACM_TYPE_SRN;
- Info.id = id;
- Info.sub_type = ACM_SRN_ANS | ACM_SRN_SNAPSHOT;
- Info.data.Alloc(size);
- screencapture_encode(cx, cy, buf, Info.data.m_pData, &Info.data.m_iLength);
- //DumpCaptureDat((const char*)Info.data.m_pData, Info.data.m_iLength);
- m_pChannelClient->Send(Info);
- free(buf);
- LOG_TRACE("encode size = %d Bytes, time = %d", Info.data.m_iLength, SP::Module::Comm::RVCGetTickCount());
- }
- void Capture2(RECT *lprc, CBlob &image)
- {
- int width = lprc->right-lprc->left;
- int height = lprc->bottom-lprc->top;
- int size = 0;
- int err = screencapture_capture(lprc, NULL, &size);
- if (err != 0) {
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- void *buf = malloc(size);
- err = screencapture_capture(lprc, buf, &size);
- if (err != 0) {
- free(buf);
- LOG_TRACE("capture screen failed! %d", err);
- return;
- }
- #ifndef RVC_OS_WIN
- //linux需翻转图像
- Dbg("size = %d, 3*width*height= %d", size, 3*width*height);
- RotationDown((unsigned char*)buf, width, height, 3);
- #endif
- // encode with jpeg2k
- jpeg2k_coded_image codec_image = {0};
- jpeg2k_raw_image raw_image;
- raw_image.data = (BYTE*)buf;
- raw_image.width = width;
- raw_image.height = height;
- raw_image.len = raw_image.width * raw_image.height * 3;
- int nRet = jpeg2k_encode(&raw_image, &codec_image, 30); // ratio越小质量越好
- if (nRet == 0 || nRet == Error_TimeOut)
- {
- size = codec_image.len;
- image.Alloc(size);
- memmove(image.m_pData, codec_image.data, size);
- //char tmp[MAX_PATH];
- //static int seq = 0;
- //sprintf(tmp, ".\\jietu_%08d.jp2", seq++);
- //FILE *fp = fopen(tmp, "wb");
- //if (fp) {
- // fwrite(codec_image.data,1,size, fp);
- // fclose(fp);
- //}
- image.Resize(size);
- jpeg2k_encode_free(&codec_image);
- }
-
- free(buf);
- }
- private:
- screen_encoder_session_t *m_enc_session;
- ChannelClient *m_pChannelClient;
- CAutoArray<CUUID> m_arrListener;
- // add by ly 20150514
- int m_id_seq;
- BOOL m_bIsWallMachine;
- };
- // add by ly 20150514
- void CScreenShotSession::Handle_StartScreenShot(SpReqAnsContext<ScreenShotService_StartScreenShot_Req, ScreenShotService_StartScreenShot_Ans>::Pointer ctx)
- {
- Dbg("accepted params: %d, %d, %d, %d", ctx->Req.Left, ctx->Req.Top, ctx->Req.Width, ctx->Req.Height);
-
- #ifdef RVC_OS_WIN
- int cx = GetSystemMetrics(SM_CXSCREEN);
- int cy = GetSystemMetrics(SM_CYSCREEN);
- #else
- int cx, cy;
- getScreenSize(&cx, &cy);
- #endif
- if (ctx->Req.Left < 0 || ctx->Req.Left > cx || ctx->Req.Width <= 0 || ctx->Req.Width > cx ||
- ctx->Req.Top < 0 || ctx->Req.Top > cy || ctx->Req.Height <= 0 || ctx->Req.Height > cy)
- {
- ctx->Answer(Error_Unexpect);
- }
- RECT rc = {ctx->Req.Left, ctx->Req.Top, ctx->Req.Left + ctx->Req.Width, ctx->Req.Top + ctx->Req.Height};
- m_pEntity->Capture2(&rc, ctx->Ans.Image);
- if (ctx->Ans.Image.m_iLength == 0)
- {
- ctx->Answer(Error_Unexpect);
- }
- else
- {
- ctx->Answer(Error_Succeed);
- }
- }
- // add by ly 20150514
- void CScreenShotSession::OnClose( ErrorCodeEnum eErrorCode )
- {
- LOG_FUNCTION();
- }
- void ChannelClient::OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData)
- {
- if (Error == Error_Succeed) {
- CScreenCaptureEntity *pEntity = static_cast<CScreenCaptureEntity*>(m_pEntityBase);
- if (Msg.state == eChannelState_Idle) {
- pEntity->ExitCapture();
- } else if (Msg.state == eChannelState_Connected) {
- pEntity->InitCapture();
- }
- }
- }
- void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
- {
- LOG_FUNCTION();
- if (Error == Error_Succeed) {
- CScreenCaptureEntity *pEntity = static_cast<CScreenCaptureEntity*>(m_pEntityBase);
- int cat = ACM_SRN_CAT(Msg.sub_type);
- if (cat == ACM_SRN_REQ) {
- //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
- pEntity->Capture(Msg.id);
- //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
- } else {
- _ASSERT(0);
- }
- }
- }
- ChannelClient::ChannelClient( CScreenCaptureEntity *pEntity ) : ChannelService_ClientBase(pEntity)
- {
- }
- SP_BEGIN_ENTITY_MAP()
- SP_ENTITY(CScreenCaptureEntity)
- SP_END_ENTITY_MAP()
|