wfreerdp-server: refactoring and delaying of initialization of encoder

This commit is contained in:
Marc-André Moreau 2012-09-07 06:01:16 +02:00
parent 651b8a4e55
commit 947e9bead7
8 changed files with 127 additions and 131 deletions

View File

@ -126,6 +126,32 @@ wfInfo* wf_info_get_instance()
return wfInfoInstance;
}
void wf_update_encoder_init(wfInfo* wfi)
{
wfi->rfx_context = rfx_context_new();
wfi->rfx_context->mode = RLGR3;
wfi->rfx_context->width = wfi->width;
wfi->rfx_context->height = wfi->height;
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
wfi->s = stream_new(0xFFFF);
}
void wf_update_encoder_uninit(wfInfo* wfi)
{
if (wfi->rfx_context != NULL)
{
rfx_context_free(wfi->rfx_context);
wfi->rfx_context = NULL;
stream_free(wfi->s);
}
}
void wf_update_encoder_reinit(wfInfo* wfi)
{
wf_update_encoder_uninit(wfi);
wf_update_encoder_init(wfi);
}
void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
{
if (wf_info_lock(wfi) > 0)
@ -134,20 +160,15 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
if (wfi->peerCount < 1)
{
wf_check_disp_devices(wfi);
wf_disp_device_set_attach_mode(wfi, TRUE);
wf_update_mirror_drv(wfi, 0);
wf_map_mirror_mem(wfi);
wf_mirror_driver_find_display_device(wfi);
wf_mirror_driver_display_device_attach(wfi, 1);
wf_mirror_driver_update(wfi, FALSE);
wf_mirror_driver_map_memory(wfi);
wfi->rfx_context = rfx_context_new();
wfi->rfx_context->mode = RLGR3;
wfi->rfx_context->width = wfi->width;
wfi->rfx_context->height = wfi->height;
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
wfi->s = stream_new(65536);
//wf_update_encoder_init(wfi);
}
wf_update_encoder_reinit(wfi);
wfi->peers[wfi->peerCount++] = context;
wf_info_unlock(wfi);
@ -162,12 +183,11 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
{
wfi->peers[--(wfi->peerCount)] = NULL;
wf_mirror_cleanup(wfi);
wf_disp_device_set_attach_mode(context->info, FALSE);
wf_update_mirror_drv(wfi, 1);
wf_mirror_driver_cleanup(wfi);
wf_mirror_driver_display_device_attach(wfi, 0);
wf_mirror_driver_update(wfi, 1);
stream_free(wfi->s);
rfx_context_free(wfi->rfx_context);
//wf_update_encoder_uninit(wfi);
}
else
{

View File

@ -31,10 +31,9 @@ struct wf_info
STREAM* s;
int width;
int height;
int bitsPerPix;
int bitsPerPixel;
HDC driverDC;
int peerCount;
int threadCount;
BOOL activated;
void* changeBuffer;
LPTSTR deviceKey;
@ -45,6 +44,7 @@ struct wf_info
HANDLE mutex;
BOOL updatePending;
HANDLE updateEvent;
HANDLE updateThread;
RFX_CONTEXT* rfx_context;
unsigned long lastUpdate;
unsigned long nextUpdate;

View File

@ -29,7 +29,7 @@ the mirror device we want to load. If found, it will then copy the registry
key corresponding to the device to the context and returns true. Otherwise
the function returns false.
*/
BOOL wf_check_disp_devices(wfInfo* context)
BOOL wf_mirror_driver_find_display_device(wfInfo* context)
{
BOOL result;
BOOL devFound;
@ -78,7 +78,7 @@ BOOL wf_check_disp_devices(wfInfo* context)
* false.
*/
BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode)
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode)
{
HKEY hKey;
LONG status;
@ -114,7 +114,7 @@ BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode)
return TRUE;
}
void wf_disp_change_print_status(LONG status)
void wf_mirror_driver_print_display_change_status(LONG status)
{
TCHAR disp_change[64];
@ -170,16 +170,13 @@ void wf_disp_change_print_status(LONG status)
* If unload is nonzero then the the driver will be asked to remove itself.
*/
BOOL wf_update_mirror_drv(wfInfo* context, int unload)
BOOL wf_mirror_driver_update(wfInfo* context, int unload)
{
HDC dc;
BOOL status;
DWORD* extHdr;
WORD drvExtraSaved;
DEVMODE* deviceMode;
int currentScreenBPP;
int currentScreenPixHeight;
int currentScreenPixWidth;
LONG disp_change_status;
DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE;
@ -189,22 +186,16 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
* Will have to come back to this for supporting non primary displays and multimonitor setups
*/
dc = GetDC(NULL);
currentScreenPixHeight = GetDeviceCaps(dc, VERTRES);
currentScreenPixWidth = GetDeviceCaps(dc, HORZRES);
currentScreenBPP = GetDeviceCaps(dc, BITSPIXEL);
context->width = GetDeviceCaps(dc, HORZRES);
context->height = GetDeviceCaps(dc, VERTRES);
context->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
ReleaseDC(NULL, dc);
context->height = currentScreenPixHeight;
context->width = currentScreenPixWidth;
context->bitsPerPix = currentScreenBPP;
_tprintf(_T("Detected current screen settings: %dx%dx%d\n"), currentScreenPixHeight, currentScreenPixWidth, currentScreenBPP);
}
else
{
currentScreenPixHeight = 0;
currentScreenPixWidth = 0;
currentScreenBPP = 0;
context->width = 0;
context->height = 0;
context->bitsPerPixel = 0;
}
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
@ -219,9 +210,9 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
deviceMode->dmSize = sizeof(DEVMODE);
deviceMode->dmDriverExtra = drvExtraSaved;
deviceMode->dmPelsWidth = currentScreenPixWidth;
deviceMode->dmPelsHeight = currentScreenPixHeight;
deviceMode->dmBitsPerPel = currentScreenBPP;
deviceMode->dmPelsWidth = context->width;
deviceMode->dmPelsHeight = context->height;
deviceMode->dmBitsPerPel = context->bitsPerPixel;
deviceMode->dmPosition.x = 0;
deviceMode->dmPosition.y = 0;
@ -234,12 +225,12 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
if (!status)
wf_disp_change_print_status(disp_change_status);
wf_mirror_driver_print_display_change_status(disp_change_status);
return status;
}
BOOL wf_map_mirror_mem(wfInfo* context)
BOOL wf_mirror_driver_map_memory(wfInfo* context)
{
int status;
GETCHANGESBUF* b;
@ -269,7 +260,7 @@ BOOL wf_map_mirror_mem(wfInfo* context)
/* Unmap the shared memory and release the DC */
BOOL wf_mirror_cleanup(wfInfo* context)
BOOL wf_mirror_driver_cleanup(wfInfo* context)
{
int status;

View File

@ -200,10 +200,10 @@ typedef struct
ULONG nColorBmPalEntries;
} Esc_dmf_pointer_shape_get_OUT;
BOOL wf_check_disp_devices(wfInfo* context);
BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode);
BOOL wf_update_mirror_drv(wfInfo* context, int unload);
BOOL wf_map_mirror_mem(wfInfo* context);
BOOL wf_mirror_cleanup(wfInfo* context);
BOOL wf_mirror_driver_find_display_device(wfInfo* context);
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode);
BOOL wf_mirror_driver_update(wfInfo* context, int unload);
BOOL wf_mirror_driver_map_memory(wfInfo* context);
BOOL wf_mirror_driver_cleanup(wfInfo* context);
#endif /* WF_MIRAGE_H */

View File

@ -46,93 +46,41 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
wf_info_peer_unregister(context->info, context);
}
static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)
void wf_peer_start_encoder_thread(freerdp_peer* client)
{
DWORD fps;
wfInfo* wfi;
DWORD beg, end;
DWORD diff, rate;
freerdp_peer* client;
wfPeerContext* context;
fps = 24;
rate = 1000 / fps;
client = (freerdp_peer*) lpParam;
context = (wfPeerContext*) client->context;
wfi = context->info;
while (1)
{
beg = GetTickCount();
wfi = ((wfPeerContext*) client->context)->info;
if (wf_info_lock(wfi) > 0)
{
if (wfi->peerCount > 0)
{
wf_info_update_changes(wfi);
if (wf_info_have_updates(wfi))
{
wf_update_encode(wfi);
SetEvent(wfi->updateEvent);
}
}
wf_info_unlock(wfi);
}
end = GetTickCount();
diff = end - beg;
if (diff < rate)
{
Sleep(rate - diff);
}
}
wf_info_lock(wfi);
wfi->threadCount--;
wf_info_unlock(wfi);
return 0;
wfi->updateThread = CreateThread(NULL, 0, wf_update_thread, wfi, 0, NULL);
if (!wfi->updateThread)
{
_tprintf(_T("Failed to create update thread\n"));
}
wf_info_unlock(wfi);
}
void wf_peer_init(freerdp_peer* client)
{
wfInfo* wfi;
client->context_size = sizeof(wfPeerContext);
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
freerdp_peer_context_new(client);
wfi = ((wfPeerContext*) client->context)->info;
wf_info_lock(wfi);
if (wfi->threadCount < 1)
{
if (CreateThread(NULL, 0, wf_peer_mirror_monitor, client, 0, NULL) != 0)
{
wfi->threadCount++;
printf("started monitor thread\n");
}
else
{
_tprintf(_T("failed to create monitor thread\n"));
}
}
wf_info_unlock(wfi);
}
boolean wf_peer_post_connect(freerdp_peer* client)
{
wfInfo* wfi;
rdpSettings* settings;
wfPeerContext* context = (wfPeerContext*) client->context;
wfi = context->info;
settings = client->settings;
/**
* This callback is called when the entire connection sequence is done, i.e. we've received the
@ -141,28 +89,19 @@ boolean wf_peer_post_connect(freerdp_peer* client)
* callback returns.
*/
printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
client->settings->os_major_type, client->settings->os_minor_type);
if (client->settings->autologon)
if ((settings->width != wfi->width) || (settings->height != wfi->height))
{
printf(" and wants to login automatically as %s\\%s",
client->settings->domain ? client->settings->domain : "",
client->settings->username);
printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
settings->width, settings->height, wfi->width, wfi->height);
/* A real server may perform OS login here if NLA is not executed previously. */
settings->width = wfi->width;
settings->height = wfi->height;
settings->color_depth = wfi->bitsPerPixel;
client->update->DesktopResize(client->update->context);
}
printf("\n");
printf("Client requested desktop: %dx%dx%d\n",
client->settings->width, client->settings->height, client->settings->color_depth);
printf("But we will try resizing to %dx%d\n", wfi->width, wfi->height);
client->settings->width = wfi->width;
client->settings->height = wfi->height;
client->update->DesktopResize(client->update->context);
wf_peer_start_encoder_thread(client);
return true;
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#include <winpr/windows.h>
#include <freerdp/freerdp.h>
#include <freerdp/listener.h>
@ -29,6 +31,49 @@
#include "wf_update.h"
DWORD WINAPI wf_update_thread(LPVOID lpParam)
{
DWORD fps;
wfInfo* wfi;
DWORD beg, end;
DWORD diff, rate;
fps = 24;
rate = 1000 / fps;
wfi = (wfInfo*) lpParam;
while (1)
{
beg = GetTickCount();
if (wf_info_lock(wfi) > 0)
{
if (wfi->peerCount > 0)
{
wf_info_update_changes(wfi);
if (wf_info_have_updates(wfi))
{
wf_update_encode(wfi);
SetEvent(wfi->updateEvent);
}
}
wf_info_unlock(wfi);
}
end = GetTickCount();
diff = end - beg;
if (diff < rate)
{
Sleep(rate - diff);
}
}
return 0;
}
void wf_update_encode(wfInfo* wfi)
{
long offset;

View File

@ -25,4 +25,6 @@
void wf_update_encode(wfInfo* wfi);
void wf_update_send(wfInfo* wfi);
DWORD WINAPI wf_update_thread(LPVOID lpParam);
#endif /* WF_UPDATE_H */

View File

@ -81,7 +81,6 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
FD_SET(fds, &rfds_set);
}
if (max_fds == 0)
break;