From 07e4e23c7b3e8b8c436c6e61d3c1e1e25943fec1 Mon Sep 17 00:00:00 2001 From: Koichiro Iwao Date: Fri, 23 Aug 2024 16:53:30 +0900 Subject: [PATCH] tconfig: add config which to prefer H264 vs RFX --- tests/xrdp/Makefile.am | 10 ++- tests/xrdp/gfx/gfx.toml | 40 +++++++++++ tests/xrdp/gfx/gfx_codec_h264_only.toml | 18 +++++ tests/xrdp/gfx/gfx_codec_h264_preferred.toml | 18 +++++ tests/xrdp/gfx/gfx_codec_order_undefined.toml | 18 +++++ tests/xrdp/gfx/gfx_codec_rfx_only.toml | 18 +++++ tests/xrdp/gfx/gfx_codec_rfx_preferred.toml | 18 +++++ .../xrdp/gfx/gfx_codec_rfx_preferred_odd.toml | 18 +++++ tests/xrdp/test_tconfig.c | 45 +++++++++++- xrdp/gfx.toml | 3 + xrdp/xrdp_tconfig.c | 70 +++++++++++++++++++ xrdp/xrdp_tconfig.h | 7 ++ 12 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 tests/xrdp/gfx/gfx.toml create mode 100644 tests/xrdp/gfx/gfx_codec_h264_only.toml create mode 100644 tests/xrdp/gfx/gfx_codec_h264_preferred.toml create mode 100644 tests/xrdp/gfx/gfx_codec_order_undefined.toml create mode 100644 tests/xrdp/gfx/gfx_codec_rfx_only.toml create mode 100644 tests/xrdp/gfx/gfx_codec_rfx_preferred.toml create mode 100644 tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml diff --git a/tests/xrdp/Makefile.am b/tests/xrdp/Makefile.am index 02f8b3e2..e9fab447 100644 --- a/tests/xrdp/Makefile.am +++ b/tests/xrdp/Makefile.am @@ -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 diff --git a/tests/xrdp/gfx/gfx.toml b/tests/xrdp/gfx/gfx.toml new file mode 100644 index 00000000..af3fcf86 --- /dev/null +++ b/tests/xrdp/gfx/gfx.toml @@ -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 diff --git a/tests/xrdp/gfx/gfx_codec_h264_only.toml b/tests/xrdp/gfx/gfx_codec_h264_only.toml new file mode 100644 index 00000000..86fa7d70 --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_h264_only.toml @@ -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] diff --git a/tests/xrdp/gfx/gfx_codec_h264_preferred.toml b/tests/xrdp/gfx/gfx_codec_h264_preferred.toml new file mode 100644 index 00000000..7d5b11ad --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_h264_preferred.toml @@ -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] diff --git a/tests/xrdp/gfx/gfx_codec_order_undefined.toml b/tests/xrdp/gfx/gfx_codec_order_undefined.toml new file mode 100644 index 00000000..7432cb97 --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_order_undefined.toml @@ -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] diff --git a/tests/xrdp/gfx/gfx_codec_rfx_only.toml b/tests/xrdp/gfx/gfx_codec_rfx_only.toml new file mode 100644 index 00000000..9ab14ea2 --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_rfx_only.toml @@ -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] diff --git a/tests/xrdp/gfx/gfx_codec_rfx_preferred.toml b/tests/xrdp/gfx/gfx_codec_rfx_preferred.toml new file mode 100644 index 00000000..c09d029b --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_rfx_preferred.toml @@ -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] diff --git a/tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml b/tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml new file mode 100644 index 00000000..ff5c7015 --- /dev/null +++ b/tests/xrdp/gfx/gfx_codec_rfx_preferred_odd.toml @@ -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] diff --git a/tests/xrdp/test_tconfig.c b/tests/xrdp/test_tconfig.c index 586278eb..5219b267 100644 --- a/tests/xrdp/test_tconfig.c +++ b/tests/xrdp/test_tconfig.c @@ -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,46 @@ 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_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(GFXCONF_STUBDIR "/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(GFXCONF_STUBDIR "/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 appears twice like: RFX, H264, RFX */ + tconfig_load_gfx(GFXCONF_STUBDIR "/gfx_codec_rfx_preferred_odd.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(GFXCONF_STUBDIR "/gfx_codec_rfx_only.toml", &gfxconfig); + ck_assert_int_eq(gfxconfig.codec.h264_idx, -1); + ck_assert_int_gt(gfxconfig.codec.rfx_idx, -1); + + /* H264 is preferred if order undefined */ + tconfig_load_gfx(GFXCONF_STUBDIR "/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) @@ -43,6 +85,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); diff --git a/xrdp/gfx.toml b/xrdp/gfx.toml index 5b7f27c4..af3fcf86 100644 --- a/xrdp/gfx.toml +++ b/xrdp/gfx.toml @@ -1,3 +1,6 @@ +[codec] +order = [ "H.264", "RFX" ] + [x264.default] preset = "ultrafast" tune = "zerolatency" diff --git a/xrdp/xrdp_tconfig.c b/xrdp/xrdp_tconfig.c index d16a0f4a..19ad4194 100644 --- a/xrdp/xrdp_tconfig.c +++ b/xrdp/xrdp_tconfig.c @@ -199,6 +199,73 @@ 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) +{ + /* + * 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_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.h264_idx = i; + } + if (rfx_found == 0 && + 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) { @@ -225,6 +292,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); diff --git a/xrdp/xrdp_tconfig.h b/xrdp/xrdp_tconfig.h index 6a5ba970..8364dcd8 100644 --- a/xrdp/xrdp_tconfig.h +++ b/xrdp/xrdp_tconfig.h @@ -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]; };