diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 8428ab6a9..f0c5b4541 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -147,8 +147,9 @@ typedef void (*pRefreshRect)(rdpContext* context, BYTE count, RECTANGLE_16* area typedef void (*pSuppressOutput)(rdpContext* context, BYTE allow, RECTANGLE_16* area); typedef void (*pSurfaceCommand)(rdpContext* context, wStream* s); -typedef void (*pSurfaceBits)(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command); -typedef void (*pSurfaceFrameMarker)(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker); +typedef void (*pSurfaceBits)(rdpContext* context, SURFACE_BITS_COMMAND* surfaceBitsCommand); +typedef void (*pSurfaceFrameMarker)(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker); +typedef void (*pSurfaceFrameBits)(rdpContext* context, SURFACE_BITS_COMMAND* cmd, BOOL first, BOOL last, UINT32 frameId); typedef void (*pSurfaceFrameAcknowledge)(rdpContext* context, UINT32 frameId); struct rdp_update @@ -180,8 +181,9 @@ struct rdp_update pSurfaceCommand SurfaceCommand; /* 64 */ pSurfaceBits SurfaceBits; /* 65 */ pSurfaceFrameMarker SurfaceFrameMarker; /* 66 */ - pSurfaceFrameAcknowledge SurfaceFrameAcknowledge; /* 67 */ - UINT32 paddingE[80 - 68]; /* 68 */ + pSurfaceFrameBits SurfaceFrameBits; /* 67 */ + pSurfaceFrameAcknowledge SurfaceFrameAcknowledge; /* 68 */ + UINT32 paddingE[80 - 69]; /* 69 */ /* internal */ diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index daeef3f29..f3ec6fe80 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -867,7 +867,7 @@ static void update_send_surface_command(rdpContext* context, wStream* s) Stream_Release(update); } -static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surfaceBitsCommand) { wStream* s; rdpRdp* rdp = context->rdp; @@ -875,9 +875,9 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* update_force_flush(context); s = fastpath_update_pdu_init(rdp->fastpath); - Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength); - update_write_surfcmd_surface_bits_header(s, surface_bits_command); - Stream_Write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surfaceBitsCommand->bitmapDataLength); + update_write_surfcmd_surface_bits_header(s, surfaceBitsCommand); + Stream_Write(s, surfaceBitsCommand->bitmapData, surfaceBitsCommand->bitmapDataLength); fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); update_force_flush(context); @@ -885,7 +885,7 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* Stream_Release(s); } -static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker) { wStream* s; rdpRdp* rdp = context->rdp; @@ -893,7 +893,34 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_ update_force_flush(context); s = fastpath_update_pdu_init(rdp->fastpath); - update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId); + update_write_surfcmd_frame_marker(s, surfaceFrameMarker->frameAction, surfaceFrameMarker->frameId); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); + + update_force_flush(context); + + Stream_Release(s); +} + +static void update_send_surface_frame_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd, BOOL first, BOOL last, UINT32 frameId) +{ + wStream* s; + rdpRdp* rdp = context->rdp; + + update_force_flush(context); + + s = fastpath_update_pdu_init(rdp->fastpath); + Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) cmd->bitmapDataLength + 16); + + if (first) + update_write_surfcmd_frame_marker(s, SURFACECMD_FRAMEACTION_BEGIN, frameId); + + update_write_surfcmd_surface_bits_header(s, cmd); + Stream_Write(s, cmd->bitmapData, cmd->bitmapDataLength); + + + if (last) + update_write_surfcmd_frame_marker(s, SURFACECMD_FRAMEACTION_END, frameId); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); update_force_flush(context); @@ -1596,6 +1623,7 @@ void update_register_server_callbacks(rdpUpdate* update) update->SurfaceBits = update_send_surface_bits; update->SurfaceFrameMarker = update_send_surface_frame_marker; update->SurfaceCommand = update_send_surface_command; + update->SurfaceFrameBits = update_send_surface_frame_bits; update->PlaySound = update_send_play_sound; update->primary->DstBlt = update_send_dstblt; update->primary->PatBlt = update_send_patblt; diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 6038bfeec..96aea63a9 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -287,6 +287,8 @@ int shadow_client_send_surface_frame_marker(rdpShadowClient* client, UINT32 acti int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight) { int i; + BOOL first; + BOOL last; wStream* s; int nSrcStep; BYTE* pSrcData; @@ -325,10 +327,7 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s } if (encoder->frameAck) - { frameId = (UINT32) shadow_encoder_create_frame_id(encoder); - shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_BEGIN, frameId); - } if (settings->RemoteFxCodec) { @@ -366,7 +365,13 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); - IFCALL(update->SurfaceBits, update->context, &cmd); + first = (i == 0) ? TRUE : FALSE; + last = ((i + 1) == numMessages) ? TRUE : FALSE; + + if (!encoder->frameAck) + IFCALL(update->SurfaceBits, update->context, &cmd); + else + IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId); } free(messages); @@ -401,17 +406,18 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s cmd.bitmapDataLength = Stream_GetPosition(s); cmd.bitmapData = Stream_Buffer(s); - IFCALL(update->SurfaceBits, update->context, &cmd); + first = (i == 0) ? TRUE : FALSE; + last = ((i + 1) == numMessages) ? TRUE : FALSE; + + if (!encoder->frameAck) + IFCALL(update->SurfaceBits, update->context, &cmd); + else + IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId); } free(messages); } - if (encoder->frameAck) - { - shadow_client_send_surface_frame_marker(client, SURFACECMD_FRAMEACTION_END, frameId); - } - return 1; }