mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #2717 from realjiangms/shadow_encoder_fps
server/shadow: shadow encoder related enhancement/fix.
This commit is contained in:
commit
ccf5ba3194
|
@ -279,6 +279,9 @@ FREERDP_API BOOL shadow_client_post_msg(rdpShadowClient* client, void* context,
|
|||
FREERDP_API int shadow_client_boardcast_msg(rdpShadowServer* server, void* context, UINT32 type, SHADOW_MSG_OUT* msg, void* lParam);
|
||||
FREERDP_API int shadow_client_boardcast_quit(rdpShadowServer* server, int nExitCode);
|
||||
|
||||
FREERDP_API int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder);
|
||||
FREERDP_API UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "../shadow_client.h"
|
||||
#include "../shadow_surface.h"
|
||||
#include "../shadow_capture.h"
|
||||
#include "../shadow_encoder.h"
|
||||
#include "../shadow_subsystem.h"
|
||||
#include "../shadow_mcevent.h"
|
||||
|
||||
|
@ -377,7 +376,7 @@ void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfa
|
|||
|
||||
if (client)
|
||||
{
|
||||
subsystem->captureFrameRate = client->encoder->fps;
|
||||
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include "../shadow_screen.h"
|
||||
#include "../shadow_client.h"
|
||||
#include "../shadow_encoder.h"
|
||||
#include "../shadow_capture.h"
|
||||
#include "../shadow_surface.h"
|
||||
#include "../shadow_subsystem.h"
|
||||
|
@ -747,7 +746,7 @@ int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
|
|||
|
||||
if (client)
|
||||
{
|
||||
subsystem->captureFrameRate = client->encoder->fps;
|
||||
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -357,17 +357,16 @@ BOOL shadow_client_activate(freerdp_peer* peer)
|
|||
|
||||
BOOL shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId)
|
||||
{
|
||||
SURFACE_FRAME* frame;
|
||||
wListDictionary* frameList;
|
||||
/*
|
||||
* Record the last client acknowledged frame id to
|
||||
* calculate how much frames are in progress.
|
||||
* Some rdp clients (win7 mstsc) skips frame ACK if it is
|
||||
* inactive, we should not expect ACK for each frame.
|
||||
* So it is OK to calculate inflight frame count according to
|
||||
* a latest acknowledged frame id.
|
||||
*/
|
||||
client->encoder->lastAckframeId = frameId;
|
||||
|
||||
frameList = client->encoder->frameList;
|
||||
frame = (SURFACE_FRAME*) ListDictionary_GetItemValue(frameList, (void*) (size_t) frameId);
|
||||
|
||||
if (frame)
|
||||
{
|
||||
ListDictionary_Remove(frameList, (void*) (size_t) frameId);
|
||||
free(frame);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -428,7 +427,7 @@ int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* s
|
|||
}
|
||||
|
||||
if (encoder->frameAck)
|
||||
frameId = (UINT32) shadow_encoder_create_frame_id(encoder);
|
||||
frameId = shadow_encoder_create_frame_id(encoder);
|
||||
|
||||
if (settings->RemoteFxCodec)
|
||||
{
|
||||
|
|
|
@ -24,15 +24,37 @@
|
|||
|
||||
#include "shadow_encoder.h"
|
||||
|
||||
int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
|
||||
int shadow_encoder_preferred_fps(rdpShadowEncoder* encoder)
|
||||
{
|
||||
/* Return preferred fps calculated according to the last
|
||||
* sent frame id and last client-acknowledged frame id.
|
||||
*/
|
||||
return encoder->fps;
|
||||
}
|
||||
|
||||
UINT32 shadow_encoder_inflight_frames(rdpShadowEncoder* encoder)
|
||||
{
|
||||
/* Return inflight frame count =
|
||||
* <last sent frame id> - <last client-acknowledged frame id>
|
||||
* Note: This function is exported so that subsystem could
|
||||
* implement its own strategy to tune fps.
|
||||
*/
|
||||
return encoder->frameId - encoder->lastAckframeId;
|
||||
}
|
||||
|
||||
UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
|
||||
{
|
||||
UINT32 frameId;
|
||||
int inFlightFrames;
|
||||
SURFACE_FRAME* frame;
|
||||
|
||||
inFlightFrames = ListDictionary_Count(encoder->frameList);
|
||||
inFlightFrames = shadow_encoder_inflight_frames(encoder);
|
||||
|
||||
if (inFlightFrames > encoder->frameAck)
|
||||
/*
|
||||
* Calculate preferred fps according to how much frames are
|
||||
* in-progress. Note that it only works when subsytem implementation
|
||||
* calls shadow_encoder_preferred_fps and takes the suggestion.
|
||||
*/
|
||||
if (inFlightFrames > 1)
|
||||
{
|
||||
encoder->fps = (100 / (inFlightFrames + 1) * encoder->maxFps) / 100;
|
||||
}
|
||||
|
@ -47,16 +69,9 @@ int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder)
|
|||
if (encoder->fps < 1)
|
||||
encoder->fps = 1;
|
||||
|
||||
frame = (SURFACE_FRAME*) malloc(sizeof(SURFACE_FRAME));
|
||||
frameId = ++encoder->frameId;
|
||||
|
||||
if (!frame)
|
||||
return -1;
|
||||
|
||||
frameId = frame->frameId = ++encoder->frameId;
|
||||
if (!ListDictionary_Add(encoder->frameList, (void*) (size_t) frame->frameId, frame))
|
||||
return -1;
|
||||
|
||||
return (int) frame->frameId;
|
||||
return frameId;
|
||||
}
|
||||
|
||||
int shadow_encoder_init_grid(rdpShadowEncoder* encoder)
|
||||
|
@ -130,16 +145,11 @@ int shadow_encoder_init_rfx(rdpShadowEncoder* encoder)
|
|||
|
||||
rfx_context_set_pixel_format(encoder->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
if (!encoder->frameList)
|
||||
{
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
encoder->frameId = 0;
|
||||
encoder->frameList = ListDictionary_New(TRUE);
|
||||
if (!encoder->frameList)
|
||||
return -1;
|
||||
encoder->frameAck = settings->SurfaceFrameMarkerEnabled;
|
||||
}
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
encoder->frameId = 0;
|
||||
encoder->lastAckframeId = 0;
|
||||
encoder->frameAck = settings->SurfaceFrameMarkerEnabled;
|
||||
|
||||
encoder->codecs |= FREERDP_CODEC_REMOTEFX;
|
||||
|
||||
|
@ -159,16 +169,11 @@ int shadow_encoder_init_nsc(rdpShadowEncoder* encoder)
|
|||
|
||||
nsc_context_set_pixel_format(encoder->nsc, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
|
||||
if (!encoder->frameList)
|
||||
{
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
encoder->frameId = 0;
|
||||
encoder->frameList = ListDictionary_New(TRUE);
|
||||
if (!encoder->frameList)
|
||||
return -1;
|
||||
encoder->frameAck = settings->SurfaceFrameMarkerEnabled;
|
||||
}
|
||||
encoder->fps = 16;
|
||||
encoder->maxFps = 32;
|
||||
encoder->frameId = 0;
|
||||
encoder->lastAckframeId = 0;
|
||||
encoder->frameAck = settings->SurfaceFrameMarkerEnabled;
|
||||
|
||||
encoder->nsc->ColorLossLevel = settings->NSCodecColorLossLevel;
|
||||
encoder->nsc->ChromaSubsamplingLevel = settings->NSCodecAllowSubsampling ? 1 : 0;
|
||||
|
@ -241,12 +246,6 @@ int shadow_encoder_uninit_rfx(rdpShadowEncoder* encoder)
|
|||
encoder->rfx = NULL;
|
||||
}
|
||||
|
||||
if (encoder->frameList)
|
||||
{
|
||||
ListDictionary_Free(encoder->frameList);
|
||||
encoder->frameList = NULL;
|
||||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_REMOTEFX;
|
||||
|
||||
return 1;
|
||||
|
@ -260,12 +259,6 @@ int shadow_encoder_uninit_nsc(rdpShadowEncoder* encoder)
|
|||
encoder->nsc = NULL;
|
||||
}
|
||||
|
||||
if (encoder->frameList)
|
||||
{
|
||||
ListDictionary_Free(encoder->frameList);
|
||||
encoder->frameList = NULL;
|
||||
}
|
||||
|
||||
encoder->codecs &= ~FREERDP_CODEC_NSCODEC;
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -54,7 +54,7 @@ struct rdp_shadow_encoder
|
|||
int maxFps;
|
||||
BOOL frameAck;
|
||||
UINT32 frameId;
|
||||
wListDictionary* frameList;
|
||||
UINT32 lastAckframeId;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -63,7 +63,7 @@ extern "C" {
|
|||
|
||||
int shadow_encoder_reset(rdpShadowEncoder* encoder);
|
||||
int shadow_encoder_prepare(rdpShadowEncoder* encoder, UINT32 codecs);
|
||||
int shadow_encoder_create_frame_id(rdpShadowEncoder* encoder);
|
||||
UINT32 shadow_encoder_create_frame_id(rdpShadowEncoder* encoder);
|
||||
|
||||
rdpShadowEncoder* shadow_encoder_new(rdpShadowClient* client);
|
||||
void shadow_encoder_free(rdpShadowEncoder* encoder);
|
||||
|
|
Loading…
Reference in New Issue