Merge pull request #3218 from metalefty/gfx_codec_order
GFX: add config which to prefer H264 vs RFX
This commit is contained in:
commit
27f0febb04
@ -1,6 +1,5 @@
|
||||
AM_CPPFLAGS = \
|
||||
-DXRDP_TOP_SRCDIR=\"$(top_srcdir)\" \
|
||||
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/xrdp \
|
||||
-I$(top_srcdir)/libxrdp \
|
||||
@ -21,7 +20,14 @@ EXTRA_DIST = \
|
||||
test_not4_8bit.bmp \
|
||||
test_not4_24bit.bmp \
|
||||
test1.jpg \
|
||||
test_alpha_blend.png
|
||||
test_alpha_blend.png \
|
||||
gfx/gfx.toml\
|
||||
gfx/gfx_codec_order_undefined.toml \
|
||||
gfx/gfx_codec_h264_preferred.toml \
|
||||
gfx/gfx_codec_h264_only.toml \
|
||||
gfx/gfx_codec_rfx_preferred.toml \
|
||||
gfx/gfx_codec_rfx_preferred_odd.toml \
|
||||
gfx/gfx_codec_rfx_only.toml
|
||||
|
||||
TESTS = test_xrdp
|
||||
check_PROGRAMS = test_xrdp
|
||||
|
40
tests/xrdp/gfx/gfx.toml
Normal file
40
tests/xrdp/gfx/gfx.toml
Normal file
@ -0,0 +1,40 @@
|
||||
[codec]
|
||||
order = [ "H.264", "RFX" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
# inherits default
|
||||
|
||||
[x264.wan]
|
||||
vbv_max_bitrate = 15000
|
||||
vbv_buffer_size = 1500
|
||||
|
||||
[x264.broadband_high]
|
||||
preset = "superfast"
|
||||
vbv_max_bitrate = 8000
|
||||
vbv_buffer_Size = 800
|
||||
|
||||
[x264.satellite]
|
||||
preset = "superfast"
|
||||
vbv_max_bitrate = 5000
|
||||
vbv_buffer_size = 500
|
||||
|
||||
[x264.broadband_low]
|
||||
preset = "veryfast"
|
||||
tune = "zerolatency"
|
||||
vbv_max_bitrate = 1600
|
||||
vbv_buffer_size = 66
|
||||
|
||||
[x264.modem]
|
||||
preset = "fast"
|
||||
tune = "zerolatency"
|
||||
vbv_max_bitrate = 1200
|
||||
vbv_buffer_size = 50
|
18
tests/xrdp/gfx/gfx_codec_h264_only.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_h264_only.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ "H.264" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
18
tests/xrdp/gfx/gfx_codec_h264_preferred.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_h264_preferred.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ "H.264", "RFX" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
18
tests/xrdp/gfx/gfx_codec_order_undefined.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_order_undefined.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
18
tests/xrdp/gfx/gfx_codec_rfx_only.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_rfx_only.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ "RFX" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
18
tests/xrdp/gfx/gfx_codec_rfx_preferred.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_rfx_preferred.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ "RFX", "H.264" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
18
tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml
Normal file
18
tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[codec]
|
||||
order = [ "RFX", "H.264", "RFX" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
profile = "main" # profile is forced to baseline if preset == ultrafast
|
||||
vbv_max_bitrate = 0
|
||||
vbv_buffer_size = 0
|
||||
fps_num = 24
|
||||
fps_den = 1
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
9
tests/xrdp/gfx/gfx_missing_h264.toml
Normal file
9
tests/xrdp/gfx/gfx_missing_h264.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[codec]
|
||||
order = [ "H.264", "RFX" ]
|
||||
|
||||
[x264.lan]
|
||||
[x264.wan]
|
||||
[x264.broadband_high]
|
||||
[x264.satellite]
|
||||
[x264.broadband_low]
|
||||
[x264.modem]
|
@ -6,6 +6,8 @@
|
||||
#include "test_xrdp.h"
|
||||
#include "xrdp.h"
|
||||
|
||||
#define GFXCONF_STUBDIR XRDP_TOP_SRCDIR "/tests/xrdp/gfx/"
|
||||
|
||||
START_TEST(test_tconfig_gfx_always_success)
|
||||
{
|
||||
ck_assert_int_eq(1, 1);
|
||||
@ -15,7 +17,7 @@ END_TEST
|
||||
START_TEST(test_tconfig_gfx_x264_load_basic)
|
||||
{
|
||||
struct xrdp_tconfig_gfx gfxconfig;
|
||||
int rv = tconfig_load_gfx(XRDP_TOP_SRCDIR "/xrdp/gfx.toml", &gfxconfig);
|
||||
int rv = tconfig_load_gfx(GFXCONF_STUBDIR "/gfx.toml", &gfxconfig);
|
||||
|
||||
ck_assert_int_eq(rv, 0);
|
||||
|
||||
@ -31,6 +33,68 @@ START_TEST(test_tconfig_gfx_x264_load_basic)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_tconfig_gfx_codec_order)
|
||||
{
|
||||
struct xrdp_tconfig_gfx gfxconfig;
|
||||
|
||||
/* H264 earlier */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_h264_preferred.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 2);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_H264);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[1], XTC_RFX);
|
||||
|
||||
/* H264 only */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_h264_only.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 1);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_H264);
|
||||
|
||||
/* RFX earlier */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_rfx_preferred.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 2);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_RFX);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[1], XTC_H264);
|
||||
|
||||
/* RFX appears twice like: RFX, H264, RFX */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_rfx_preferred_odd.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 2);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_RFX);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[1], XTC_H264);
|
||||
|
||||
/* RFX only */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_rfx_only.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 1);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_RFX);
|
||||
|
||||
/* H264 is preferred if order undefined */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_order_undefined.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 2);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_H264);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[1], XTC_RFX);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_tconfig_gfx_missing_file)
|
||||
{
|
||||
struct xrdp_tconfig_gfx gfxconfig;
|
||||
|
||||
/* Check RFX config is returned if the file doesn't exist */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/no_such_file.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 1);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_RFX);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_tconfig_gfx_missing_h264)
|
||||
{
|
||||
struct xrdp_tconfig_gfx gfxconfig;
|
||||
|
||||
/* Check RFX config only is returned if H.264 parameters are missing */
|
||||
tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_missing_h264.toml", &gfxconfig);
|
||||
ck_assert_int_eq(gfxconfig.codec.codec_count, 1);
|
||||
ck_assert_int_eq(gfxconfig.codec.codecs[0], XTC_RFX);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/******************************************************************************/
|
||||
Suite *
|
||||
make_suite_tconfig_load_gfx(void)
|
||||
@ -43,6 +107,9 @@ make_suite_tconfig_load_gfx(void)
|
||||
tc_tconfig_load_gfx = tcase_create("xrdp_tconfig_load_gfx");
|
||||
tcase_add_test(tc_tconfig_load_gfx, test_tconfig_gfx_always_success);
|
||||
tcase_add_test(tc_tconfig_load_gfx, test_tconfig_gfx_x264_load_basic);
|
||||
tcase_add_test(tc_tconfig_load_gfx, test_tconfig_gfx_codec_order);
|
||||
tcase_add_test(tc_tconfig_load_gfx, test_tconfig_gfx_missing_file);
|
||||
tcase_add_test(tc_tconfig_load_gfx, test_tconfig_gfx_missing_h264);
|
||||
|
||||
suite_add_tcase(s, tc_tconfig_load_gfx);
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
[codec]
|
||||
order = [ "H.264", "RFX" ]
|
||||
|
||||
[x264.default]
|
||||
preset = "ultrafast"
|
||||
tune = "zerolatency"
|
||||
|
@ -38,6 +38,14 @@
|
||||
#include "xrdp_client_info.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(XRDP_X264) || defined(XRDP_OPENH264) || defined(XRDP_NVENC)
|
||||
#if !defined(XRDP_H264)
|
||||
#define XRDP_H264 1
|
||||
#endif
|
||||
#else
|
||||
#undef XRDP_H264
|
||||
#endif
|
||||
|
||||
/* xrdp.c */
|
||||
long
|
||||
g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
|
||||
|
@ -1362,7 +1362,6 @@ xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
|
||||
struct xrdp_mm *self;
|
||||
struct xrdp_bitmap *screen;
|
||||
int index;
|
||||
int best_index;
|
||||
int best_h264_index;
|
||||
int best_pro_index;
|
||||
int error;
|
||||
@ -1370,6 +1369,10 @@ xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
|
||||
int flags;
|
||||
struct ver_flags_t *ver_flags;
|
||||
|
||||
#if !defined(XRDP_H264)
|
||||
UNUSED_VAR(best_h264_index);
|
||||
#endif
|
||||
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise:");
|
||||
self = (struct xrdp_mm *) user;
|
||||
screen = self->wm->screen;
|
||||
@ -1390,7 +1393,6 @@ xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
|
||||
}
|
||||
/* sort by version */
|
||||
g_qsort(ver_flags, caps_count, sizeof(struct ver_flags_t), cmpverfunc);
|
||||
best_index = -1;
|
||||
best_h264_index = -1;
|
||||
best_pro_index = -1;
|
||||
for (index = 0; index < caps_count; index++)
|
||||
@ -1437,19 +1439,34 @@ xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (best_pro_index >= 0)
|
||||
|
||||
int best_index = -1;
|
||||
struct xrdp_tconfig_gfx_codec_order *co = &self->wm->gfx_config->codec;
|
||||
char cobuff[64];
|
||||
|
||||
LOG(LOG_LEVEL_INFO, "Codec search order is %s",
|
||||
tconfig_codec_order_to_str(co, cobuff, sizeof(cobuff)));
|
||||
for (index = 0 ; index < co->codec_count ; ++index)
|
||||
{
|
||||
best_index = best_pro_index;
|
||||
self->egfx_flags = XRDP_EGFX_RFX_PRO;
|
||||
}
|
||||
/* prefer h264, todo use setting in xrdp.ini for this */
|
||||
if (best_h264_index >= 0)
|
||||
{
|
||||
#if defined(XRDP_X264) || defined(XRDP_NVENC)
|
||||
best_index = best_h264_index;
|
||||
self->egfx_flags = XRDP_EGFX_H264;
|
||||
#if defined(XRDP_H264)
|
||||
if (co->codecs[index] == XTC_H264 && best_h264_index >= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "Matched H264 mode");
|
||||
best_index = best_h264_index;
|
||||
self->egfx_flags = XRDP_EGFX_H264;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (co->codecs[index] == XTC_RFX && best_pro_index >= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, "Matched RFX mode");
|
||||
best_index = best_pro_index;
|
||||
self->egfx_flags = XRDP_EGFX_RFX_PRO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_index >= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO, " replying version 0x%8.8x flags 0x%8.8x",
|
||||
|
@ -48,6 +48,54 @@
|
||||
#define X264_DEFAULT_FPS_NUM 24
|
||||
#define X264_DEFAULT_FPS_DEN 1
|
||||
|
||||
const char *
|
||||
tconfig_codec_order_to_str(
|
||||
const struct xrdp_tconfig_gfx_codec_order *codec_order,
|
||||
char *buff,
|
||||
unsigned int bufflen)
|
||||
{
|
||||
if (bufflen < (8 * codec_order->codec_count))
|
||||
{
|
||||
snprintf(buff, bufflen, "???");
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int p = 0;
|
||||
int i;
|
||||
for (i = 0 ; i < codec_order->codec_count; ++i)
|
||||
{
|
||||
if (p > 0)
|
||||
{
|
||||
buff[p++] = ',';
|
||||
}
|
||||
|
||||
switch (codec_order->codecs[i])
|
||||
{
|
||||
case XTC_H264:
|
||||
buff[p++] = 'H';
|
||||
buff[p++] = '2';
|
||||
buff[p++] = '6';
|
||||
buff[p++] = '4';
|
||||
break;
|
||||
|
||||
case XTC_RFX:
|
||||
buff[p++] = 'R';
|
||||
buff[p++] = 'F';
|
||||
buff[p++] = 'X';
|
||||
break;
|
||||
|
||||
default:
|
||||
buff[p++] = '?';
|
||||
buff[p++] = '?';
|
||||
buff[p++] = '?';
|
||||
}
|
||||
}
|
||||
buff[p++] = '\0';
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
static int
|
||||
tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
|
||||
struct xrdp_tconfig_gfx_x264_param *param)
|
||||
@ -199,12 +247,132 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tconfig_load_gfx_order(toml_table_t *tfile, struct xrdp_tconfig_gfx *config)
|
||||
{
|
||||
char buff[64];
|
||||
|
||||
/*
|
||||
* This config loader is not responsible to check if xrdp is built with
|
||||
* H264/RFX support. Just loads configurations as-is.
|
||||
*/
|
||||
|
||||
TCLOG(LOG_LEVEL_TRACE, "[codec]");
|
||||
|
||||
int h264_found = 0;
|
||||
int rfx_found = 0;
|
||||
|
||||
config->codec.codec_count = 0;
|
||||
|
||||
toml_table_t *codec;
|
||||
toml_array_t *order;
|
||||
|
||||
if ((codec = toml_table_in(tfile, "codec")) != NULL &&
|
||||
(order = toml_array_in(codec, "order")) != NULL)
|
||||
{
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
toml_datum_t datum = toml_string_at(order, i);
|
||||
|
||||
if (datum.ok)
|
||||
{
|
||||
if (h264_found == 0 &&
|
||||
(g_strcasecmp(datum.u.s, "h264") == 0 ||
|
||||
g_strcasecmp(datum.u.s, "h.264") == 0))
|
||||
{
|
||||
h264_found = 1;
|
||||
config->codec.codecs[config->codec.codec_count] = XTC_H264;
|
||||
++config->codec.codec_count;
|
||||
}
|
||||
if (rfx_found == 0 &&
|
||||
g_strcasecmp(datum.u.s, "rfx") == 0)
|
||||
{
|
||||
rfx_found = 1;
|
||||
config->codec.codecs[config->codec.codec_count] = XTC_RFX;
|
||||
++config->codec.codec_count;
|
||||
}
|
||||
free(datum.u.s);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h264_found == 0 && rfx_found == 0)
|
||||
{
|
||||
/* prefer H264 if no priority found */
|
||||
config->codec.codecs[0] = XTC_H264;
|
||||
config->codec.codecs[1] = XTC_RFX;
|
||||
config->codec.codec_count = 2;
|
||||
|
||||
TCLOG(LOG_LEVEL_WARNING, "[codec] could not get GFX codec order, "
|
||||
"using default order %s",
|
||||
tconfig_codec_order_to_str(&config->codec, buff, sizeof(buff)));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
TCLOG(LOG_LEVEL_DEBUG, "[codec] %s",
|
||||
tconfig_codec_order_to_str(&config->codec, buff, sizeof(buff)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a codec is enabled
|
||||
* @param co Ordered codec list
|
||||
* @param code Code of codec to look for
|
||||
* @return boolean
|
||||
*/
|
||||
static int
|
||||
codec_enabled(const struct xrdp_tconfig_gfx_codec_order *co,
|
||||
enum xrdp_tconfig_codecs code)
|
||||
{
|
||||
for (unsigned short i = 0; i < co->codec_count; ++i)
|
||||
{
|
||||
if (co->codecs[i] == code)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables a Codec by removing it from the codec list
|
||||
* @param co Ordered codec list
|
||||
* @param code Code of codec to remove from list
|
||||
*
|
||||
* The order of the passed-in codec list is preserved.
|
||||
*/
|
||||
static void
|
||||
disable_codec(struct xrdp_tconfig_gfx_codec_order *co,
|
||||
enum xrdp_tconfig_codecs code)
|
||||
{
|
||||
unsigned short j = 0;
|
||||
for (unsigned short i = 0; i < co->codec_count; ++i)
|
||||
{
|
||||
if (co->codecs[i] != code)
|
||||
{
|
||||
co->codecs[j++] = co->codecs[i];
|
||||
}
|
||||
}
|
||||
co->codec_count = j;
|
||||
}
|
||||
|
||||
int
|
||||
tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config)
|
||||
{
|
||||
FILE *fp;
|
||||
char errbuf[200];
|
||||
toml_table_t *tfile;
|
||||
int rv = 0;
|
||||
|
||||
/* Default to just RFX support. in case we can't load anything */
|
||||
config->codec.codec_count = 1;
|
||||
config->codec.codecs[0] = XTC_RFX;
|
||||
memset(config->x264_param, 0, sizeof(config->x264_param));
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL)
|
||||
{
|
||||
@ -212,33 +380,45 @@ tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config)
|
||||
filename, g_get_strerror());
|
||||
return 1;
|
||||
}
|
||||
else if ((tfile = toml_parse_file(fp, errbuf, sizeof(errbuf))) == NULL)
|
||||
|
||||
if ((tfile = toml_parse_file(fp, errbuf, sizeof(errbuf))) == NULL)
|
||||
{
|
||||
TCLOG(LOG_LEVEL_ERROR, "Error in GFX config file %s - %s", filename, errbuf);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
||||
TCLOG(LOG_LEVEL_INFO, "Loading GFX config file %s", filename);
|
||||
fclose(fp);
|
||||
|
||||
/* Load GFX codec order */
|
||||
tconfig_load_gfx_order(tfile, config);
|
||||
|
||||
/* H.264 configuration */
|
||||
if (codec_enabled(&config->codec, XTC_H264))
|
||||
{
|
||||
TCLOG(LOG_LEVEL_INFO, "Loading GFX config file %s", filename);
|
||||
fclose(fp);
|
||||
|
||||
memset(config, 0, sizeof(struct xrdp_tconfig_gfx));
|
||||
|
||||
/* First of all, read the default params and override later */
|
||||
tconfig_load_gfx_x264_ct(tfile, 0, config->x264_param);
|
||||
|
||||
for (int ct = CONNECTION_TYPE_MODEM; ct < NUM_CONNECTION_TYPES; ct++)
|
||||
/* First of all, read the default params */
|
||||
if (tconfig_load_gfx_x264_ct(tfile, 0, config->x264_param) != 0)
|
||||
{
|
||||
memcpy(&config->x264_param[ct], &config->x264_param[0],
|
||||
sizeof(struct xrdp_tconfig_gfx_x264_param));
|
||||
|
||||
tconfig_load_gfx_x264_ct(tfile, ct, config->x264_param);
|
||||
/* We can't read the H.264 defaults. Disable H.264 */
|
||||
LOG(LOG_LEVEL_WARNING, "H.264 support will be disabled");
|
||||
disable_codec(&config->codec, XTC_H264);
|
||||
rv = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy default params to other connection types, and
|
||||
* then override them */
|
||||
for (int ct = CONNECTION_TYPE_MODEM; ct < NUM_CONNECTION_TYPES;
|
||||
ct++)
|
||||
{
|
||||
config->x264_param[ct] = config->x264_param[0];
|
||||
tconfig_load_gfx_x264_ct(tfile, ct, config->x264_param);
|
||||
}
|
||||
}
|
||||
|
||||
toml_free(tfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
toml_free(tfile);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,21 @@ struct xrdp_tconfig_gfx_x264_param
|
||||
int fps_den;
|
||||
};
|
||||
|
||||
enum xrdp_tconfig_codecs
|
||||
{
|
||||
XTC_H264,
|
||||
XTC_RFX
|
||||
};
|
||||
|
||||
struct xrdp_tconfig_gfx_codec_order
|
||||
{
|
||||
enum xrdp_tconfig_codecs codecs[2];
|
||||
unsigned short codec_count;
|
||||
};
|
||||
|
||||
struct xrdp_tconfig_gfx
|
||||
{
|
||||
struct xrdp_tconfig_gfx_codec_order codec;
|
||||
/* store x264 parameters for each connection type */
|
||||
struct xrdp_tconfig_gfx_x264_param x264_param[NUM_CONNECTION_TYPES];
|
||||
};
|
||||
@ -61,6 +74,31 @@ static const char *const rdpbcgr_connection_type_names[] =
|
||||
0
|
||||
};
|
||||
|
||||
int tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config);
|
||||
/**
|
||||
* Provide a string representation of a codec order
|
||||
*
|
||||
* @param codec_order Codec order struct
|
||||
* @param buff Buffer for result
|
||||
* @param bufflen Length of above
|
||||
* @return Convenience copy of buff
|
||||
*/
|
||||
const char *
|
||||
tconfig_codec_order_to_str(
|
||||
const struct xrdp_tconfig_gfx_codec_order *codec_order,
|
||||
char *buff,
|
||||
unsigned int bufflen);
|
||||
|
||||
/**
|
||||
* Loads the GFX config from the specified file
|
||||
*
|
||||
* @param filename Name of file to load
|
||||
* @param config Struct to receive result
|
||||
* @return 0 for success
|
||||
*
|
||||
* In the event of failure, an error is logged. A minimal
|
||||
* useable configuration is always returned
|
||||
*/
|
||||
int
|
||||
tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config);
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "guid.h"
|
||||
#include "scancode.h"
|
||||
#include "xrdp_client_info.h"
|
||||
#include "xrdp_tconfig.h"
|
||||
|
||||
#define MAX_NR_CHANNELS 16
|
||||
#define MAX_CHANNEL_NAME 16
|
||||
@ -581,6 +582,8 @@ struct xrdp_wm
|
||||
|
||||
/* configuration derived from xrdp.ini */
|
||||
struct xrdp_config *xrdp_config;
|
||||
/* configuration derived from gfx.toml */
|
||||
struct xrdp_tconfig_gfx *gfx_config;
|
||||
|
||||
struct xrdp_region *screen_dirty_region;
|
||||
int last_screen_draw_time;
|
||||
|
@ -115,8 +115,9 @@ xrdp_wm_create(struct xrdp_process *owner,
|
||||
self->target_surface = self->screen;
|
||||
self->current_surface_index = 0xffff; /* screen */
|
||||
|
||||
/* to store configuration from xrdp.ini */
|
||||
/* to store configuration from xrdp.ini, gfx.toml */
|
||||
self->xrdp_config = g_new0(struct xrdp_config, 1);
|
||||
self->gfx_config = g_new0(struct xrdp_tconfig_gfx, 1);
|
||||
|
||||
/* Load the channel config so libxrdp can check whether
|
||||
drdynvc is enabled or not */
|
||||
@ -163,6 +164,11 @@ xrdp_wm_delete(struct xrdp_wm *self)
|
||||
g_free(self->xrdp_config);
|
||||
}
|
||||
|
||||
if (self->gfx_config)
|
||||
{
|
||||
g_free(self->gfx_config);
|
||||
}
|
||||
|
||||
/* free self */
|
||||
g_free(self);
|
||||
}
|
||||
@ -643,6 +649,8 @@ xrdp_wm_init(struct xrdp_wm *self)
|
||||
load_xrdp_config(self->xrdp_config, self->session->xrdp_ini,
|
||||
self->screen->bpp);
|
||||
|
||||
tconfig_load_gfx(XRDP_CFG_PATH "/gfx.toml", self->gfx_config);
|
||||
|
||||
/* Remove a font loaded on the previous config */
|
||||
xrdp_font_delete(self->default_font);
|
||||
self->painter->font = NULL; /* May be set to the default_font */
|
||||
|
Loading…
Reference in New Issue
Block a user