Skip to content

Commit

Permalink
tconfig: add config which to prefer H264 vs RFX
Browse files Browse the repository at this point in the history
  • Loading branch information
metalefty committed Aug 23, 2024
1 parent 8bf02e1 commit dff0713
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 20 deletions.
8 changes: 7 additions & 1 deletion tests/xrdp/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ 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_only.toml

TESTS = test_xrdp
check_PROGRAMS = test_xrdp
Expand Down
18 changes: 18 additions & 0 deletions tests/xrdp/gfx/gfx_codec_h264_only.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[codec]
order = [ "H264" ]

[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 changes: 18 additions & 0 deletions tests/xrdp/gfx/gfx_codec_h264_preferred.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[codec]
order = [ "H264", "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 changes: 18 additions & 0 deletions tests/xrdp/gfx/gfx_codec_order_undefined.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tests/xrdp/gfx/gfx_codec_rfx_only.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tests/xrdp/gfx/gfx_codec_rfx_preferred.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[codec]
order = [ "RFX", "H264" ]

[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]
35 changes: 35 additions & 0 deletions tests/xrdp/test_tconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,40 @@ 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("./gfx/gfx_codec_h264_preferred.toml", &gfxconfig);
ck_assert_int_gt(gfxconfig.codec.h264_idx, -1);
ck_assert_int_gt(gfxconfig.codec.rfx_idx, -1);
ck_assert_int_lt(gfxconfig.codec.h264_idx, gfxconfig.codec.rfx_idx);

/* H264 only */
tconfig_load_gfx("./gfx/gfx_codec_h264_only.toml", &gfxconfig);
ck_assert_int_gt(gfxconfig.codec.h264_idx, -1);
ck_assert_int_eq(gfxconfig.codec.rfx_idx, -1);

/* RFX earlier */
tconfig_load_gfx("./gfx/gfx_codec_rfx_preferred.toml", &gfxconfig);
ck_assert_int_gt(gfxconfig.codec.h264_idx, -1);
ck_assert_int_gt(gfxconfig.codec.rfx_idx, -1);
ck_assert_int_lt(gfxconfig.codec.rfx_idx, gfxconfig.codec.h264_idx);

/* RFX only */
tconfig_load_gfx("./gfx/gfx_codec_rfx_only.toml", &gfxconfig);
ck_assert_int_eq(gfxconfig.codec.h264_idx, -1);
ck_assert_int_gt(gfxconfig.codec.rfx_idx, -1);

/* RFX is preferred if order undefined */
tconfig_load_gfx("./gfx/gfx_codec_order_undefined.toml", &gfxconfig);
ck_assert_int_gt(gfxconfig.codec.h264_idx, -1);
ck_assert_int_gt(gfxconfig.codec.rfx_idx, -1);
ck_assert_int_lt(gfxconfig.codec.h264_idx, gfxconfig.codec.rfx_idx);
}
END_TEST

/******************************************************************************/
Suite *
make_suite_tconfig_load_gfx(void)
Expand All @@ -43,6 +77,7 @@ 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);

suite_add_tcase(s, tc_tconfig_load_gfx);

Expand Down
3 changes: 3 additions & 0 deletions xrdp/gfx.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[codec]
order = [ "H264", "RFX" ]

[x264.default]
preset = "ultrafast"
tune = "zerolatency"
Expand Down
105 changes: 86 additions & 19 deletions xrdp/xrdp_tconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ static int
tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
struct xrdp_tconfig_gfx_x264_param *param)
{
TCLOG(LOG_LEVEL_TRACE, "[x264]");

if (connection_type > NUM_CONNECTION_TYPES)
{
TCLOG(LOG_LEVEL_ERROR, "Invalid connection type is given");
TCLOG(LOG_LEVEL_ERROR, "[x264] Invalid connection type is given");
return 1;
}

toml_table_t *x264 = toml_table_in(tfile, "x264");
if (!x264)
{
TCLOG(LOG_LEVEL_WARNING, "x264 params are not defined");
TCLOG(LOG_LEVEL_WARNING, "[x264] x264 params are not defined");
return 1;
}

Expand All @@ -88,8 +90,8 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param preset is not set for connection type [%s], "
"adopting the default value \"" X264_DEFAULT_PRESET "\"",
"[x264.%s] preset is not set, adopting the default value \""
X264_DEFAULT_PRESET "\"",
rdpbcgr_connection_type_names[connection_type]);
g_strncpy(param[connection_type].preset,
X264_DEFAULT_PRESET,
Expand All @@ -108,8 +110,8 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param tune is not set for connection type [%s], "
"adopting the default value \"" X264_DEFAULT_TUNE "\"",
"[x264.%s] tune is not set, adopting the default value \""
X264_DEFAULT_PRESET "\"",
rdpbcgr_connection_type_names[connection_type]);
g_strncpy(param[connection_type].tune,
X264_DEFAULT_TUNE,
Expand All @@ -128,8 +130,8 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param profile is not set for connection type [%s], "
"adopting the default value \"" X264_DEFAULT_PROFILE "\"",
"[x264.%s] profile is not set, adopting the default value \""
X264_DEFAULT_PRESET "\"",
rdpbcgr_connection_type_names[connection_type]);
g_strncpy(param[connection_type].profile,
X264_DEFAULT_PROFILE,
Expand All @@ -145,8 +147,7 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param vbv_max_bit_rate is not set for connection type [%s], "
"adopting the default value [0]",
"[x264.%s] vbv_max_bitrate is not set, adopting the default value [0]",
rdpbcgr_connection_type_names[connection_type]);
param[connection_type].vbv_max_bitrate = 0;
}
Expand All @@ -160,8 +161,7 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param vbv_buffer_size is not set for connection type [%s], "
"adopting the default value [0]",
"[x264.%s] vbv_buffer_size is not set, adopting the default value [0]",
rdpbcgr_connection_type_names[connection_type]);
param[connection_type].vbv_buffer_size = 0;
}
Expand All @@ -175,9 +175,9 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param fps_num is not set for connection type [%s], "
"adopting the default value [0]",
rdpbcgr_connection_type_names[connection_type]);
"[x264.%s] fps_num is not set, adopting the default value [%d]",
rdpbcgr_connection_type_names[connection_type],
X264_DEFAULT_FPS_NUM);
param[connection_type].fps_num = X264_DEFAULT_FPS_NUM;
}

Expand All @@ -190,15 +190,79 @@ tconfig_load_gfx_x264_ct(toml_table_t *tfile, const int connection_type,
else if (connection_type == 0)
{
TCLOG(LOG_LEVEL_WARNING,
"x264 param fps_den is not set for connection type [%s], "
"adopting the default value [0]",
rdpbcgr_connection_type_names[connection_type]);
param[connection_type].fps_num = X264_DEFAULT_FPS_DEN;
"[x264.%s] fps_den is not set, adopting the default value [%d]",
rdpbcgr_connection_type_names[connection_type],
X264_DEFAULT_FPS_DEN);
param[connection_type].fps_den = X264_DEFAULT_FPS_DEN;
}

return 0;
}

static int tconfig_load_gfx_order(toml_table_t *tfile, struct xrdp_tconfig_gfx *config)
{
/*
* 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.h264_idx = -1;
config->codec.rfx_idx = -1;

toml_table_t *codec = toml_table_in(tfile, "codec");
toml_array_t *order = toml_array_in(codec, "order");

if (codec && order)
{
for (int i = 0; ; i++)
{
toml_datum_t datum = toml_string_at(order, i);

if (datum.ok)
{
if (g_strcasecmp(datum.u.s, "h264") == 0 ||
g_strcasecmp(datum.u.s, "h.264") == 0)
{
h264_found = 1;
config->codec.h264_idx = i;
}
if (g_strcasecmp(datum.u.s, "rfx") == 0)
{
rfx_found = 1;
config->codec.rfx_idx = i;
}
free(datum.u.s);
}
else
{
break;
}
}
}

if (h264_found == 0 && rfx_found == 0)
{
/* prefer H264 if no priority found */
config->codec.h264_idx = 0;
config->codec.rfx_idx = 1;

TCLOG(LOG_LEVEL_WARNING, "[codec] could not get GFX codec order, using default order"
" h264_idx [%d], rfx_idx [%d]",
config->codec.h264_idx, config->codec.rfx_idx);

return 1;
}

TCLOG(LOG_LEVEL_DEBUG, "[codec] h264_idx [%d], rfx_idx [%d]",
config->codec.h264_idx, config->codec.rfx_idx);
return 0;
}

int
tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config)
{
Expand All @@ -225,6 +289,9 @@ tconfig_load_gfx(const char *filename, struct xrdp_tconfig_gfx *config)

memset(config, 0, sizeof(struct xrdp_tconfig_gfx));

/* Load GFX order */
tconfig_load_gfx_order(tfile, config);

/* First of all, read the default params and override later */
tconfig_load_gfx_x264_ct(tfile, 0, config->x264_param);

Expand Down
7 changes: 7 additions & 0 deletions xrdp/xrdp_tconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,15 @@ struct xrdp_tconfig_gfx_x264_param
int fps_den;
};

struct xrdp_tconfig_gfx_codec_order
{
int h264_idx;
int rfx_idx;
};

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];
};
Expand Down

0 comments on commit dff0713

Please sign in to comment.