Merge pull request #587 from llyzs/rfx
Add RemoteFX Frame Acknowledge feature
This commit is contained in:
commit
26dea949e1
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user