{\r
_tprintf(_T("CreateMutex error: %d\n"), GetLastError());\r
}\r
+\r
+ wfInfoSingleton->encodeMutex = CreateMutex( \r
+ NULL, // default security attributes\r
+ FALSE, // initially not owned\r
+ NULL); // unnamed mutex\r
+\r
+ if (wfInfoSingleton->encodeMutex == NULL) \r
+ {\r
+ _tprintf(_T("CreateMutex error: %d\n"), GetLastError());\r
+ }\r
}\r
\r
dRes = WaitForSingleObject( \r
\r
void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)\r
{\r
+ \r
if (context && (wfInfoSingleton->subscribers == 1))\r
{\r
+ --wfInfoSingleton->subscribers;\r
//only the last peer needs to call this\r
wf_mirror_cleanup(context->wfInfo);\r
wf_disp_device_set_attatch(context->wfInfo, 0);\r
\r
stream_free(context->s);\r
rfx_context_free(context->rfx_context);\r
+ } \r
+ else\r
+ {\r
+ --wfInfoSingleton->subscribers;\r
}\r
-\r
- --wfInfoSingleton->subscribers;\r
}\r
\r
static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)\r
{\r
DWORD dRes;\r
+ DWORD start, end, diff;\r
GETCHANGESBUF* buf;\r
freerdp_peer* client;\r
+ unsigned long i;\r
\r
client = (freerdp_peer*)lpParam;\r
buf = (GETCHANGESBUF*)wfInfoSingleton->changeBuffer;\r
while(1)\r
{\r
\r
+ start = GetTickCount();\r
dRes = WaitForSingleObject(\r
wfInfoSingleton->mutex, // handle to mutex\r
INFINITE); // no time-out interval\r
case WAIT_OBJECT_0:\r
if(wfInfoSingleton->subscribers > 0)\r
{\r
- _tprintf(_T("Count = %lu\n"), buf->buffer->counter);\r
- //wf_peer_rfx_update(client, 0, 0, wfInfoSingleton->width, wfInfoSingleton->height);\r
+ wfInfoSingleton->nextUpdate = buf->buffer->counter;\r
+ //_tprintf(_T("Count = %lu\n"), wfInfoSingleton->nextUpdate);\r
+\r
+\r
+ //todo: modulus\r
+ //need to go through the "queue"\r
+ for(i = wfInfoSingleton->lastUpdate; i <= wfInfoSingleton->nextUpdate; ++i)\r
+ {\r
+ wfInfoSingleton->invalid_x1 = min(wfInfoSingleton->invalid_x1, buf->buffer->pointrect[i].rect.left);\r
+ wfInfoSingleton->invalid_x2 = max(wfInfoSingleton->invalid_x2, buf->buffer->pointrect[i].rect.right);\r
+ wfInfoSingleton->invalid_y1 = min(wfInfoSingleton->invalid_y1, buf->buffer->pointrect[i].rect.top);\r
+ wfInfoSingleton->invalid_y2 = max(wfInfoSingleton->invalid_y2, buf->buffer->pointrect[i].rect.bottom);\r
+ }\r
+\r
+ wf_rfx_encode(client);\r
}\r
\r
if (! ReleaseMutex(wfInfoSingleton->mutex)) \r
_tprintf(_T("Error waiting for mutex: %d\n"), dRes);\r
}\r
\r
+ end = GetTickCount();\r
+ diff = end - start;\r
+ if(diff < 42)\r
+ {\r
+ Sleep(42 - diff);\r
+ }\r
+ \r
\r
- freerdp_sleep(1);\r
+ //Sleep(42);\r
+ //freerdp_usleep(41667);\r
+ \r
}\r
\r
_tprintf(_T("monitor thread terminating...\n"));\r
return 0;\r
}\r
\r
+/*\r
void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height)\r
{\r
STREAM* s;\r
wfPeerContext* wfp;\r
SURFACE_BITS_COMMAND* cmd;\r
GETCHANGESBUF* buf;\r
-\r
- printf("encode\n");\r
\r
update = client->update;\r
wfp = (wfPeerContext*) client->context;\r
wfi = wfp->wfInfo;\r
buf = (GETCHANGESBUF*)wfi->changeBuffer;\r
\r
- if (width * height <= 0)\r
+ if( (wfp->activated == false) ||\r
+ ( (wfi->nextUpdate - wfi->lastUpdate) == 0) )\r
+ return;\r
+\r
+ printf("encode %d\n", wfi->nextUpdate - wfi->lastUpdate);\r
+ printf("\tinvlaid region = (%d, %d), (%d, %d)\n", wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2);\r
+ wfi->lastUpdate = wfi->nextUpdate;\r
+\r
+ if ( (wfi->invalid_x1 >= wfi->invalid_x2) ||\r
+ (wfi->invalid_y1 >= wfi->invalid_y2) )\r
return;\r
\r
stream_clear(wfp->s);\r
stream_set_pos(wfp->s, 0);\r
s = wfp->s;\r
\r
- rect.x = 0;\r
- rect.y = 0;\r
- rect.width = width;\r
- rect.height = height;\r
+ rect.x = wfi->invalid_x1;\r
+ rect.y = wfi->invalid_y1;\r
+ rect.width = wfi->invalid_x2;\r
+ rect.height = wfi->invalid_y2;\r
+\r
+ wfi->invalid_x1 = wfi->width;\r
+ wfi->invalid_x2 = 0;\r
+ wfi->invalid_y1 = wfi->height;\r
+ wfi->invalid_y2 = 0;\r
\r
rfx_compose_message(wfp->rfx_context, s, &rect, 1,\r
(uint8*) buf->Userbuffer, width, height, width * 4);\r
cmd->bitmapDataLength = stream_get_length(s);\r
cmd->bitmapData = stream_get_head(s);\r
\r
- //update->SurfaceBits(update->context, cmd);\r
+ update->SurfaceBits(update->context, cmd);\r
+}\r
+*/\r
+\r
+void wf_rfx_encode(freerdp_peer* client)\r
+{\r
+ STREAM* s;\r
+ wfInfo* wfi;\r
+ RFX_RECT rect;\r
+ rdpUpdate* update;\r
+ wfPeerContext* wfp;\r
+ SURFACE_BITS_COMMAND* cmd;\r
+ GETCHANGESBUF* buf;\r
+ long height, width;\r
+ \r
+ update = client->update;\r
+ wfp = (wfPeerContext*) client->context;\r
+ cmd = &update->surface_bits_command;\r
+ wfi = wfp->wfInfo;\r
+ buf = (GETCHANGESBUF*)wfi->changeBuffer;\r
+\r
+ \r
+ if( (wfp->activated == false) )//|| ( (wfi->nextUpdate - wfi->lastUpdate) == 0) )\r
+ return;\r
+\r
+ /*\r
+ printf("encode %d\n", wfi->nextUpdate - wfi->lastUpdate);\r
+ printf("\tinvlaid region = (%d, %d), (%d, %d)\n", wfi->invalid_x1, wfi->invalid_y1, wfi->invalid_x2, wfi->invalid_y2);\r
+ wfi->lastUpdate = wfi->nextUpdate;\r
+ */\r
+ if ( (wfi->invalid_x1 >= wfi->invalid_x2) ||\r
+ (wfi->invalid_y1 >= wfi->invalid_y2) )\r
+ return;\r
+\r
+ width = wfi->invalid_x2 - wfi->invalid_x1;\r
+ height = wfi->invalid_y2 - wfi->invalid_y1;\r
+\r
+ stream_clear(wfp->s);\r
+ stream_set_pos(wfp->s, 0);\r
+ s = wfp->s;\r
+ \r
+ rect.x = wfi->invalid_x1;\r
+ rect.y = wfi->invalid_y1;\r
+ rect.width = width;\r
+ rect.height = width;\r
+\r
+\r
+ rfx_compose_message(wfp->rfx_context, s, &rect, 1,\r
+ (uint8*) buf->Userbuffer, width, height, width * 4);\r
+\r
+ cmd->destLeft = wfi->invalid_x1;\r
+ cmd->destTop = wfi->invalid_y1;\r
+ cmd->destRight = wfi->invalid_x1 + width;\r
+ cmd->destBottom = wfi->invalid_y1 + height;\r
+\r
+\r
+ cmd->bpp = 32;\r
+ cmd->codecID = client->settings->rfx_codec_id;\r
+ cmd->width = width;\r
+ cmd->height = height;\r
+ cmd->bitmapDataLength = stream_get_length(s);\r
+ cmd->bitmapData = stream_get_head(s);\r
+\r
}\r
\r
void wf_peer_init(freerdp_peer* client)\r
\r
static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)\r
{\r
+ int dRes;\r
int rcount;\r
void* rfds[32];\r
wfPeerContext* context;\r
}\r
\r
if(wfInfoSingleton)\r
- wf_peer_rfx_update(client, 0, 0, wfInfoSingleton->width, wfInfoSingleton->height);\r
+ {\r
+ //wf_peer_rfx_update(client, 0, 0, wfInfoSingleton->width, wfInfoSingleton->height);\r
+ \r
+ dRes = WaitForSingleObject(\r
+ wfInfoSingleton->encodeMutex, // handle to mutex\r
+ 0); // dont wait\r
+\r
+ switch(dRes)\r
+ {\r
+ case WAIT_OBJECT_0:\r
+\r
+ if( ( ((wfPeerContext*)client->context)->activated == false) || ( (wfInfoSingleton->nextUpdate - wfInfoSingleton->lastUpdate) == 0) )\r
+ {\r
+ break;\r
+ }\r
+ \r
+ //printf("send %d\n", stream_get_length(((wfPeerContext*) client->context)->s));\r
+ client->update->SurfaceBits(client->update->context, &client->update->surface_bits_command);\r
+\r
+ wfInfoSingleton->lastUpdate = wfInfoSingleton->nextUpdate;\r
+ wfInfoSingleton->invalid_x1 = wfInfoSingleton->width;\r
+ wfInfoSingleton->invalid_x2 = 0;\r
+ wfInfoSingleton->invalid_y1 = wfInfoSingleton->height;\r
+ wfInfoSingleton->invalid_y2 = 0;\r
+\r
+ if (! ReleaseMutex(wfInfoSingleton->encodeMutex)) \r
+ { \r
+ _tprintf(_T("Error releasing mutex\n"));\r
+ } \r
+\r
+ break;\r
+\r
+ case WAIT_TIMEOUT:\r
+ break;\r
+\r
+ default:\r
+ _tprintf(_T("Error waiting for mutex: %d\n"), dRes);\r
+ }\r
+ }\r
}\r
\r
printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);\r