Merge pull request #587 from llyzs/rfx

Add RemoteFX Frame Acknowledge feature
This commit is contained in:
Vic Lee 2012-05-11 09:01:14 -07:00
commit 26dea949e1
11 changed files with 87 additions and 12 deletions

View File

@ -67,6 +67,8 @@ struct rdp_freerdp_peer
psPeerSendChannelData SendChannelData;
psPeerReceiveChannelData ReceiveChannelData;
uint32 ack_frame_id;
};
FREERDP_API void freerdp_peer_context_new(freerdp_peer* client);

View File

@ -391,7 +391,7 @@ struct rdp_settings
ALIGN64 uint32 rfx_codec_id; /* 282 */
ALIGN64 uint32 ns_codec_id; /* 283 */
ALIGN64 uint32 rfx_codec_mode; /* 284 */
ALIGN64 boolean frame_acknowledge; /* 285 */
ALIGN64 uint32 frame_acknowledge; /* 285 */
ALIGN64 uint64 paddingM[296 - 286]; /* 286 */
/* Recording */

View File

@ -123,6 +123,12 @@ struct _SURFACE_FRAME_MARKER
};
typedef struct _SURFACE_FRAME_MARKER SURFACE_FRAME_MARKER;
enum SURFCMD_FRAMEACTION
{
SURFACECMD_FRAMEACTION_BEGIN = 0x0000,
SURFACECMD_FRAMEACTION_END = 0x0001
};
/* Update Interface */
typedef void (*pBeginPaint)(rdpContext* context);

View File

@ -1613,7 +1613,14 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
{
stream_seek_uint32(s); /* (4 bytes) */
if (settings->server_mode)
{
stream_read_uint32(s, settings->frame_acknowledge); /* (4 bytes) */
}
else
{
stream_seek_uint32(s); /* (4 bytes) */
}
}
/**
@ -1628,7 +1635,7 @@ void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings
header = rdp_capability_set_start(s);
stream_write_uint32(s, 2); /* (4 bytes) */
stream_write_uint32(s, settings->frame_acknowledge); /* (4 bytes) */
rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
}
@ -1873,7 +1880,7 @@ void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
stream_seek_uint16(s); /* numberCapabilities (2 bytes) */
stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */
numberCapabilities = 13;
numberCapabilities = 14;
rdp_write_general_capability_set(s, settings);
rdp_write_bitmap_capability_set(s, settings);
rdp_write_order_capability_set(s, settings);
@ -1887,6 +1894,7 @@ void rdp_write_demand_active(STREAM* s, rdpSettings* settings)
rdp_write_desktop_composition_capability_set(s, settings);
rdp_write_surface_commands_capability_set(s, settings);
rdp_write_bitmap_codecs_capability_set(s, settings);
rdp_write_frame_acknowledge_capability_set(s, settings);
if (settings->persistent_bitmap_cache)
{
@ -2068,7 +2076,7 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
{
if (settings->frame_acknowledge)
if (settings->frame_acknowledge > 0)
{
numberCapabilities++;
rdp_write_frame_acknowledge_capability_set(s, settings);

View File

@ -25,6 +25,7 @@
static boolean freerdp_peer_initialize(freerdp_peer* client)
{
client->context->rdp->settings->server_mode = true;
client->context->rdp->settings->frame_acknowledge = 0;
client->context->rdp->state = CONNECTION_STATE_INITIAL;
if (client->context->rdp->settings->rdp_key_file != NULL)
@ -120,6 +121,10 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs);
return false;
case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE:
stream_read_uint32(s, client->ack_frame_id);
break;
default:
printf("Data PDU type %d\n", type);
break;

View File

@ -104,6 +104,7 @@
#define DATA_PDU_TYPE_ARC_STATUS 0x32
#define DATA_PDU_TYPE_STATUS_INFO 0x36
#define DATA_PDU_TYPE_MONITOR_LAYOUT 0x37
#define DATA_PDU_TYPE_FRAME_ACKNOWLEDGE 0x38
/* Stream Identifiers */
#define STREAM_UNDEFINED 0x00

View File

@ -171,6 +171,8 @@ rdpSettings* settings_new(void* instance)
settings->fastpath_input = true;
settings->fastpath_output = true;
settings->frame_acknowledge = 2;
settings->uniconv = freerdp_uniconv_new();
gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1);
settings->mouse_motion = true;

View File

@ -46,6 +46,15 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s)
return 20 + cmd->bitmapDataLength;
}
static void update_send_frame_acknowledge(rdpRdp* rdp, uint32 frameId)
{
STREAM* s;
s = rdp_data_pdu_init(rdp);
stream_write_uint32(s, frameId);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
}
static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
{
SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker;
@ -55,6 +64,11 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
IFCALL(update->SurfaceFrameMarker, update->context, marker);
if (update->context->rdp->settings->frame_acknowledge > 0 && marker->frameAction == SURFACECMD_FRAMEACTION_END)
{
update_send_frame_acknowledge(update->context->rdp, marker->frameId);
}
return 6;
}

View File

@ -33,12 +33,6 @@ enum SURFCMD_CMDTYPE
CMDTYPE_STREAM_SURFACE_BITS = 0x0006
};
enum SURFCMD_FRAMEACTION
{
SURFACECMD_FRAMEACTION_BEGIN = 0x0000,
SURFACECMD_FRAMEACTION_END = 0x0001
};
boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s);
void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);

View File

@ -89,6 +89,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
" --plugin: load a virtual channel plugin\n"
" --rfx: enable RemoteFX\n"
" --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n"
" --frame-ack: number of frames pending to be acknowledged, default is 2 (disable with 0)\n"
" --nsc: enable NSCodec (experimental)\n"
" --disable-wallpaper: disables wallpaper\n"
" --composition: enable desktop composition\n"
@ -352,7 +353,6 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
settings->rfx_codec = true;
settings->fastpath_output = true;
settings->color_depth = 32;
settings->frame_acknowledge = false;
settings->performance_flags = PERF_FLAG_NONE;
settings->large_pointer = true;
}
@ -378,6 +378,16 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
return FREERDP_ARGS_PARSE_FAILURE;
}
}
else if (strcmp("--frame-ack", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing frame acknowledge number\n");
return FREERDP_ARGS_PARSE_FAILURE;
}
settings->frame_acknowledge = atoi(argv[index]);
}
else if (strcmp("--nsc", argv[index]) == 0)
{
settings->ns_codec = true;

View File

@ -60,6 +60,7 @@ struct test_peer_context
WTSVirtualChannelManager* vcm;
void* debug_channel;
freerdp_thread* debug_channel_thread;
uint32 frame_id;
};
typedef struct test_peer_context testPeerContext;
@ -120,6 +121,30 @@ static STREAM* test_peer_stream_init(testPeerContext* context)
return context->s;
}
static void test_peer_begin_frame(freerdp_peer* client)
{
rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER* fm = &update->surface_frame_marker;
testPeerContext* context = (testPeerContext*) client->context;
fm->frameAction = SURFACECMD_FRAMEACTION_BEGIN;
fm->frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, fm);
}
static void test_peer_end_frame(freerdp_peer* client)
{
rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER* fm = &update->surface_frame_marker;
testPeerContext* context = (testPeerContext*) client->context;
fm->frameAction = SURFACECMD_FRAMEACTION_END;
fm->frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, fm);
context->frame_id++;
}
static void test_peer_draw_background(freerdp_peer* client)
{
testPeerContext* context = (testPeerContext*) client->context;
@ -133,6 +158,8 @@ static void test_peer_draw_background(freerdp_peer* client)
if (!client->settings->rfx_codec && !client->settings->ns_codec)
return;
test_peer_begin_frame(client);
s = test_peer_stream_init(context);
rect.x = 0;
@ -169,6 +196,8 @@ static void test_peer_draw_background(freerdp_peer* client)
update->SurfaceBits(update->context, cmd);
xfree(rgb_data);
test_peer_end_frame(client);
}
static void test_peer_load_icon(freerdp_peer* client)
@ -229,6 +258,8 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
if (context->icon_width < 1 || !context->activated)
return;
test_peer_begin_frame(client);
rect.x = 0;
rect.y = 0;
rect.width = context->icon_width;
@ -289,6 +320,8 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
context->icon_x = x;
context->icon_y = y;
test_peer_end_frame(client);
}
static boolean test_sleep_tsdiff(uint32 *old_sec, uint32 *old_usec, uint32 new_sec, uint32 new_usec)