From 25381a2984d06a6b609a22c517532ecbd661cd4b Mon Sep 17 00:00:00 2001 From: "zihao.jiang" Date: Sat, 10 Dec 2016 02:25:50 +0800 Subject: [PATCH] Server/shadow: Fix handling for gfx acknowledge according to spec: [MS-RDPEGFX]: 3.2.5.13 Processing an RDPGFX_FRAME_ACKNOWLEDGE_PDU message If the queueDepth field is less than 0xFFFFFFFF, the server MUST expect that RDPGFX_FRAME_ACKNOWLEDGE_PDU messages will continue to be sent by the client. Furthermore, if the queueDepth field is in the range 0x00000001 to 0xFFFFFFFE the server SHOULD use this value to determine how far the client is lagging in terms of graphics decoding and then attempt to throttle the graphics frame rate accordingly. If the queueDepth field is set to SUSPEND_FRAME_ACKNOWLEDGEMENT (0xFFFFFFFF), the server MUST clear the Unacknowledged Frames (section 3.2.1.2) ADM element and MUST NOT expect any further RDPGFX_FRAME_ACKNOWLEDGE_PDU messages from the client. In this mode, the server MUST NOT wait or block on unacknowledged frames (as the RDPGFX_FRAME_ACKNOWLEDGE_PDU message is not sent by the client) and MUST assume that the client is able to decode graphics data at a rate faster than it is receiving frames. On the other hand, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU SHOULD only be used for informational and debugging purposes and should not be taken into account. --- server/shadow/shadow_client.c | 18 +++++++----------- server/shadow/shadow_encoder.c | 7 +++++-- server/shadow/shadow_encoder.h | 1 + 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 2a330f763..b7d8845bd 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -594,21 +594,19 @@ static BOOL shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId) { shadow_client_common_frame_acknowledge(client, frameId); + /* + * Reset queueDepth for legacy none RDPGFX acknowledge + */ + client->encoder->queueDepth = QUEUE_DEPTH_UNAVAILABLE; return TRUE; } static UINT shadow_client_rdpgfx_frame_acknowledge(RdpgfxServerContext* context, RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge) { - shadow_client_common_frame_acknowledge((rdpShadowClient*)context->custom, - frameAcknowledge->frameId); - return CHANNEL_RC_OK; -} -static UINT shadow_client_rdpgfx_qoe_frame_acknowledge(RdpgfxServerContext* - context, RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU* qoeFrameAcknowledge) -{ - shadow_client_common_frame_acknowledge((rdpShadowClient*)context->custom, - qoeFrameAcknowledge->frameId); + rdpShadowClient* client = (rdpShadowClient*)context->custom; + shadow_client_common_frame_acknowledge(client, frameAcknowledge->frameId); + client->encoder->queueDepth = frameAcknowledge->queueDepth; return CHANNEL_RC_OK; } @@ -1594,8 +1592,6 @@ static void* shadow_client_thread(rdpShadowClient* client) !gfxstatus.gfxOpened) { client->rdpgfx->FrameAcknowledge = shadow_client_rdpgfx_frame_acknowledge; - client->rdpgfx->QoeFrameAcknowledge = - shadow_client_rdpgfx_qoe_frame_acknowledge; client->rdpgfx->CapsAdvertise = shadow_client_rdpgfx_caps_advertise; if (!client->rdpgfx->Open(client->rdpgfx)) diff --git a/server/shadow/shadow_encoder.c b/server/shadow/shadow_encoder.c index 8fc77ef27..b9d1cb55b 100644 --- a/server/shadow/shadow_encoder.c +++ b/server/shadow/shadow_encoder.c @@ -34,12 +34,15 @@ int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder) UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder) { - /* Return inflight frame count = + /* Return inflight frame count. + * If queueDepth is SUSPEND_FRAME_ACKNOWLEDGEMENT, count = 0 + * Otherwise, calculate count = * - * Note: This function is exported so that subsystem could * implement its own strategy to tune fps. */ - return encoder->frameId - encoder->lastAckframeId; + return (encoder->queueDepth == SUSPEND_FRAME_ACKNOWLEDGEMENT) ? 0 : encoder->frameId - + encoder->lastAckframeId; } UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder) diff --git a/server/shadow/shadow_encoder.h b/server/shadow/shadow_encoder.h index b2c01b908..611850d1d 100644 --- a/server/shadow/shadow_encoder.h +++ b/server/shadow/shadow_encoder.h @@ -56,6 +56,7 @@ struct rdp_shadow_encoder BOOL frameAck; UINT32 frameId; UINT32 lastAckframeId; + UINT32 queueDepth; }; #ifdef __cplusplus