mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-23 18:03:30 +08:00
Added GFX planar and rfx encoder to shadow
This commit is contained in:
parent
bd256b91bc
commit
6deb65175f
@ -94,6 +94,7 @@ struct rdp_shadow_client
|
||||
|
||||
HANDLE thread;
|
||||
BOOL activated;
|
||||
BOOL first_frame;
|
||||
BOOL inLobby;
|
||||
BOOL mayView;
|
||||
BOOL mayInteract;
|
||||
|
@ -862,6 +862,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_GfxSendQoeAck (3846)
|
||||
#define FreeRDP_GfxAVC444v2 (3847)
|
||||
#define FreeRDP_GfxCapsFilter (3848)
|
||||
#define FreeRDP_GfxPlanar (3849)
|
||||
#define FreeRDP_BitmapCacheV3CodecId (3904)
|
||||
#define FreeRDP_DrawNineGridEnabled (3968)
|
||||
#define FreeRDP_DrawNineGridCacheSize (3969)
|
||||
@ -1475,7 +1476,8 @@ struct rdp_settings
|
||||
ALIGN64 BOOL GfxSendQoeAck; /* 3846 */
|
||||
ALIGN64 BOOL GfxAVC444v2; /* 3847 */
|
||||
ALIGN64 UINT32 GfxCapsFilter; /* 3848 */
|
||||
UINT64 padding3904[3904 - 3849]; /* 3849 */
|
||||
ALIGN64 BOOL GfxPlanar; /* 3849 */
|
||||
UINT64 padding3904[3904 - 3850]; /* 3850 */
|
||||
|
||||
/**
|
||||
* Caches
|
||||
|
@ -943,7 +943,7 @@ BOOL planar_decompress(BITMAP_PLANAR_CONTEXT* planar, const BYTE* pSrcData, UINT
|
||||
static INLINE BOOL freerdp_split_color_planes(const BYTE* data, UINT32 format, UINT32 width,
|
||||
UINT32 height, UINT32 scanline, BYTE* planes[4])
|
||||
{
|
||||
INT32 i, j, k;
|
||||
INT64 i, j, k;
|
||||
if ((width > INT32_MAX) || (height > INT32_MAX) || (scanline > INT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
@ -952,11 +952,11 @@ static INLINE BOOL freerdp_split_color_planes(const BYTE* data, UINT32 format, U
|
||||
if (scanline == 0)
|
||||
scanline = width * GetBytesPerPixel(format);
|
||||
|
||||
for (i = (INT32)height - 1; i >= 0; i--)
|
||||
for (i = (INT64)height - 1; i >= 0; i--)
|
||||
{
|
||||
const BYTE* pixel = &data[(INT32)scanline * i];
|
||||
const BYTE* pixel = &data[scanline * (UINT32)i];
|
||||
|
||||
for (j = 0; j < (INT32)width; j++)
|
||||
for (j = 0; j < (INT64)width; j++)
|
||||
{
|
||||
const UINT32 color = ReadColor(pixel, format);
|
||||
pixel += GetBytesPerPixel(format);
|
||||
|
@ -234,6 +234,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id)
|
||||
case FreeRDP_GfxH264:
|
||||
return settings->GfxH264;
|
||||
|
||||
case FreeRDP_GfxPlanar:
|
||||
return settings->GfxPlanar;
|
||||
|
||||
case FreeRDP_GfxProgressive:
|
||||
return settings->GfxProgressive;
|
||||
|
||||
@ -820,6 +823,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val)
|
||||
settings->GfxH264 = val;
|
||||
break;
|
||||
|
||||
case FreeRDP_GfxPlanar:
|
||||
settings->GfxPlanar = val;
|
||||
break;
|
||||
|
||||
case FreeRDP_GfxProgressive:
|
||||
settings->GfxProgressive = val;
|
||||
break;
|
||||
|
@ -83,6 +83,7 @@ static const struct settings_str_entry settings_map[] = {
|
||||
{ FreeRDP_GfxAVC444, 0, "FreeRDP_GfxAVC444" },
|
||||
{ FreeRDP_GfxAVC444v2, 0, "FreeRDP_GfxAVC444v2" },
|
||||
{ FreeRDP_GfxH264, 0, "FreeRDP_GfxH264" },
|
||||
{ FreeRDP_GfxPlanar, 0, "FreeRDP_GfxPlanar" },
|
||||
{ FreeRDP_GfxProgressive, 0, "FreeRDP_GfxProgressive" },
|
||||
{ FreeRDP_GfxProgressiveV2, 0, "FreeRDP_GfxProgressiveV2" },
|
||||
{ FreeRDP_GfxSendQoeAck, 0, "FreeRDP_GfxSendQoeAck" },
|
||||
|
@ -558,6 +558,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxSmallCache, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxProgressive, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxProgressiveV2, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxPlanar, TRUE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxH264, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxAVC444, FALSE) ||
|
||||
!freerdp_settings_set_bool(settings, FreeRDP_GfxSendQoeAck, FALSE))
|
||||
|
@ -72,6 +72,7 @@ static const size_t bool_list_indices[] = {
|
||||
FreeRDP_GfxAVC444,
|
||||
FreeRDP_GfxAVC444v2,
|
||||
FreeRDP_GfxH264,
|
||||
FreeRDP_GfxPlanar,
|
||||
FreeRDP_GfxProgressive,
|
||||
FreeRDP_GfxProgressiveV2,
|
||||
FreeRDP_GfxSendQoeAck,
|
||||
|
@ -81,6 +81,10 @@ int main(int argc, char** argv)
|
||||
"NTLM SAM file for NLA authentication" },
|
||||
{ "gfx-progressive", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
"Allow GFX progressive codec" },
|
||||
{ "gfx-rfx", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
"Allow GFX RFX codec" },
|
||||
{ "gfx-planar", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
"Allow GFX planar codec" },
|
||||
{ "gfx-avc420", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
"Allow GFX AVC420 codec" },
|
||||
{ "gfx-avc444", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
|
||||
@ -114,6 +118,7 @@ int main(int argc, char** argv)
|
||||
/* By default allow all GFX modes.
|
||||
* This can be changed with command line flags [+|-]gfx-CODEC
|
||||
*/
|
||||
freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec, TRUE);
|
||||
freerdp_settings_set_bool(settings, FreeRDP_GfxH264, TRUE);
|
||||
freerdp_settings_set_bool(settings, FreeRDP_GfxAVC444, TRUE);
|
||||
freerdp_settings_set_bool(settings, FreeRDP_GfxAVC444v2, TRUE);
|
||||
|
@ -138,6 +138,7 @@ static INLINE BOOL shadow_client_rdpgfx_reset_graphic(rdpShadowClient* client)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
client->first_frame = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -797,6 +798,8 @@ static BOOL shadow_client_caps_test_version(RdpgfxServerContext* context, rdpSha
|
||||
if (currentCaps->version == capsVersion)
|
||||
{
|
||||
UINT32 flags;
|
||||
BOOL planar = FALSE;
|
||||
BOOL rfx = FALSE;
|
||||
BOOL avc444v2 = FALSE;
|
||||
BOOL avc444 = FALSE;
|
||||
BOOL avc420 = FALSE;
|
||||
@ -825,6 +828,12 @@ static BOOL shadow_client_caps_test_version(RdpgfxServerContext* context, rdpSha
|
||||
progressive = freerdp_settings_get_bool(srvSettings, FreeRDP_GfxProgressiveV2);
|
||||
freerdp_settings_set_bool(clientSettings, FreeRDP_GfxProgressiveV2, progressive);
|
||||
|
||||
rfx = freerdp_settings_get_bool(srvSettings, FreeRDP_RemoteFxCodec);
|
||||
freerdp_settings_set_bool(clientSettings, FreeRDP_RemoteFxCodec, rfx);
|
||||
|
||||
planar = freerdp_settings_get_bool(srvSettings, FreeRDP_GfxPlanar);
|
||||
freerdp_settings_set_bool(clientSettings, FreeRDP_GfxPlanar, planar);
|
||||
|
||||
if (!avc444v2 && !avc444 && !avc420)
|
||||
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
|
||||
|
||||
@ -994,10 +1003,11 @@ static INLINE UINT32 rdpgfx_estimate_h264_avc420(RDPGFX_AVC420_BITMAP_STREAM* ha
|
||||
*
|
||||
* @return TRUE on success
|
||||
*/
|
||||
static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const BYTE* pSrcData,
|
||||
static BOOL shadow_client_send_surface_gfx(rdpShadowClient* client, const BYTE* pSrcData,
|
||||
UINT32 nSrcStep, UINT32 SrcFormat, UINT16 nXSrc,
|
||||
UINT16 nYSrc, UINT16 nWidth, UINT16 nHeight)
|
||||
{
|
||||
UINT32 id;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
const rdpContext* context = (const rdpContext*)client;
|
||||
const rdpSettings* settings;
|
||||
@ -1016,6 +1026,12 @@ static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const
|
||||
if (!settings || !encoder)
|
||||
return FALSE;
|
||||
|
||||
if (client->first_frame)
|
||||
{
|
||||
rfx_context_reset(encoder->rfx, nWidth, nHeight);
|
||||
client->first_frame = FALSE;
|
||||
}
|
||||
|
||||
cmdstart.frameId = shadow_encoder_create_frame_id(encoder);
|
||||
GetSystemTime(&sTime);
|
||||
cmdstart.timestamp = (UINT32)(sTime.wHour << 22U | sTime.wMinute << 16U | sTime.wSecond << 10U |
|
||||
@ -1035,6 +1051,7 @@ static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const
|
||||
cmd.data = NULL;
|
||||
cmd.extra = NULL;
|
||||
|
||||
id = freerdp_settings_get_uint32(settings, FreeRDP_RemoteFxCodecId);
|
||||
if (settings->GfxAVC444 || settings->GfxAVC444v2)
|
||||
{
|
||||
INT32 rc;
|
||||
@ -1130,6 +1147,57 @@ static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (freerdp_settings_get_bool(settings, FreeRDP_RemoteFxCodec) && (id != 0))
|
||||
{
|
||||
BOOL rc;
|
||||
wStream* s;
|
||||
RECTANGLE_16 rect;
|
||||
|
||||
if (shadow_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_REMOTEFX");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s = Stream_New(NULL, 1024);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
WINPR_ASSERT(cmd.left <= UINT16_MAX);
|
||||
WINPR_ASSERT(cmd.top <= UINT16_MAX);
|
||||
WINPR_ASSERT(cmd.right <= UINT16_MAX);
|
||||
WINPR_ASSERT(cmd.bottom <= UINT16_MAX);
|
||||
rect.left = (UINT16)cmd.left;
|
||||
rect.top = (UINT16)cmd.top;
|
||||
rect.right = (UINT16)cmd.right;
|
||||
rect.bottom = (UINT16)cmd.bottom;
|
||||
|
||||
rc = rfx_compose_message(encoder->rfx, s, &rect, 1, pSrcData, nWidth, nHeight, nSrcStep);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "rfx_compose_message failed");
|
||||
Stream_Free(s, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* rc > 0 means new data */
|
||||
if (rc > 0)
|
||||
{
|
||||
cmd.codecId = RDPGFX_CODECID_CAVIDEO;
|
||||
cmd.data = Stream_Buffer(s);
|
||||
cmd.length = Stream_GetPosition(s);
|
||||
|
||||
IFCALLRET(client->rdpgfx->SurfaceFrameCommand, error, client->rdpgfx, &cmd, &cmdstart,
|
||||
&cmdend);
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
if (error)
|
||||
{
|
||||
WLog_ERR(TAG, "SurfaceFrameCommand failed with error %" PRIu32 "", error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (freerdp_settings_get_bool(settings, FreeRDP_GfxProgressive))
|
||||
{
|
||||
INT32 rc;
|
||||
@ -1176,6 +1244,47 @@ static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (freerdp_settings_get_bool(settings, FreeRDP_GfxPlanar))
|
||||
{
|
||||
BOOL rc;
|
||||
const UINT32 w = cmd.right - cmd.left;
|
||||
const UINT32 h = cmd.bottom - cmd.top;
|
||||
const size_t step = w * GetBytesPerPixel(SrcFormat);
|
||||
const size_t size = step * h;
|
||||
BYTE* dst;
|
||||
|
||||
if (shadow_encoder_prepare(encoder, FREERDP_CODEC_PLANAR) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_PLANAR");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = freerdp_bitmap_planar_context_reset(encoder->planar, w, h);
|
||||
WINPR_ASSERT(rc);
|
||||
|
||||
dst = malloc(size);
|
||||
WINPR_ASSERT(dst);
|
||||
rc = freerdp_image_copy(dst, SrcFormat, step, 0, 0, w, h, pSrcData, SrcFormat, nSrcStep,
|
||||
cmd.left, cmd.top, NULL, FREERDP_FLIP_VERTICAL);
|
||||
WINPR_ASSERT(rc);
|
||||
|
||||
cmd.data = freerdp_bitmap_compress_planar(encoder->planar, dst, SrcFormat, w, h, step, NULL,
|
||||
&cmd.length);
|
||||
WINPR_ASSERT(cmd.data || (cmd.length == 0));
|
||||
|
||||
free(dst);
|
||||
|
||||
cmd.codecId = RDPGFX_CODECID_PLANAR;
|
||||
|
||||
IFCALLRET(client->rdpgfx->SurfaceFrameCommand, error, client->rdpgfx, &cmd, &cmdstart,
|
||||
&cmdend);
|
||||
free(cmd.data);
|
||||
if (error)
|
||||
{
|
||||
WLog_ERR(TAG, "SurfaceFrameCommand failed with error %" PRIu32 "", error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL rc;
|
||||
@ -1183,10 +1292,10 @@ static BOOL shadow_client_send_surface_gfx(const rdpShadowClient* client, const
|
||||
const UINT32 h = cmd.bottom - cmd.top;
|
||||
const UINT32 length = w * 4 * h;
|
||||
BYTE* data = malloc(length);
|
||||
if (!data)
|
||||
return FALSE;
|
||||
|
||||
rc = freerdp_image_copy(data, PIXEL_FORMAT_BGRA32, w * 4, 0, 0, w, h, pSrcData, SrcFormat,
|
||||
WINPR_ASSERT(data);
|
||||
|
||||
rc = freerdp_image_copy(data, PIXEL_FORMAT_BGRA32, 0, 0, 0, w, h, pSrcData, SrcFormat,
|
||||
nSrcStep, cmd.left, cmd.top, NULL, 0);
|
||||
WINPR_ASSERT(rc);
|
||||
|
||||
@ -1501,6 +1610,7 @@ static BOOL shadow_client_send_bitmap_update(rdpShadowClient* client, BYTE* pSrc
|
||||
UINT32 dstSize;
|
||||
buffer = encoder->grid[k];
|
||||
data = &pSrcData[(bitmap->destTop * nSrcStep) + (bitmap->destLeft * 4)];
|
||||
|
||||
buffer =
|
||||
freerdp_bitmap_compress_planar(encoder->planar, data, SrcFormat, bitmap->width,
|
||||
bitmap->height, nSrcStep, buffer, &dstSize);
|
||||
|
@ -371,6 +371,17 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
||||
arg->Value ? TRUE : FALSE))
|
||||
return COMMAND_LINE_ERROR;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gfx-rfx")
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RemoteFxCodec,
|
||||
arg->Value ? TRUE : FALSE))
|
||||
return COMMAND_LINE_ERROR;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gfx-planar")
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_GfxPlanar, arg->Value ? TRUE : FALSE))
|
||||
return COMMAND_LINE_ERROR;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gfx-avc420")
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_GfxH264, arg->Value ? TRUE : FALSE))
|
||||
|
Loading…
Reference in New Issue
Block a user