wfreerdp-server: partly reorganized rfx encoding process
authorC-o-r-E <can.of.tuna@gmail.com>
Fri, 17 Aug 2012 20:24:56 +0000 (16:24 -0400)
committerC-o-r-E <can.of.tuna@gmail.com>
Fri, 17 Aug 2012 20:24:56 +0000 (16:24 -0400)
server/Windows/wf_peer.c
server/Windows/wf_peer.h
server/Windows/wfreerdp.c
server/Windows/wfreerdp.h

index 7b80153..b72a574 100644 (file)
@@ -47,6 +47,16 @@ void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context)
                {\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
@@ -90,8 +100,10 @@ void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context)
 \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
@@ -99,16 +111,20 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
 \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
@@ -116,6 +132,7 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)
        while(1)\r
        {\r
 \r
+               start = GetTickCount();\r
                dRes = WaitForSingleObject(\r
                        wfInfoSingleton->mutex,    // handle to mutex\r
             INFINITE);  // no time-out interval\r
@@ -124,8 +141,21 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)
                        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
@@ -139,14 +169,24 @@ static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)
                                _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
@@ -156,8 +196,6 @@ void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
        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
@@ -165,17 +203,31 @@ void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
        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
@@ -192,7 +244,69 @@ void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int heigh
        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
index 9290d24..57138d6 100644 (file)
@@ -27,7 +27,8 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context);
 \r
 void wf_peer_init(freerdp_peer* client);\r
 \r
-void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height);\r
+void wf_rfx_encode(freerdp_peer* client);\r
+//void wf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height);\r
 \r
 boolean wf_peer_post_connect(freerdp_peer* client);\r
 boolean wf_peer_activate(freerdp_peer* client);\r
index dae1131..bb95736 100644 (file)
@@ -44,6 +44,7 @@ int g_thread_count = 0;
 \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
@@ -88,7 +89,45 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
                }\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
index 2fb65c3..6e0f048 100644 (file)
@@ -36,7 +36,18 @@ struct wf_info
        int width;\r
        int bitsPerPix;\r
 \r
-       HANDLE mutex;\r
+       HANDLE mutex, encodeMutex;\r
+\r
+       unsigned long lastUpdate;\r
+       unsigned long nextUpdate;\r
+\r
+       long invalid_x1;\r
+       long invalid_y1;\r
+\r
+       long invalid_x2;\r
+       long invalid_y2;\r
+\r
+       \r
 };\r
 typedef struct wf_info wfInfo;\r
 \r