From 261df79fa7201a7d4ed87e7e25f3ee6ef114ea1a Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Tue, 17 Feb 2026 09:26:10 +0100 Subject: [PATCH] add Spout semi-weekly test + vcap/spout hook this should have catched the: and check also for its regression + added get_spout (vcap/spout) Doxy --- .github/scripts/run_scheduled_tests.sh | 12 ++++++++++ .github/scripts/run_scheduled_tests_data.sh | 1 + src/video_capture/spout.cpp | 26 +++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/.github/scripts/run_scheduled_tests.sh b/.github/scripts/run_scheduled_tests.sh index 810bdba14..6ee283343 100755 --- a/.github/scripts/run_scheduled_tests.sh +++ b/.github/scripts/run_scheduled_tests.sh @@ -65,6 +65,12 @@ prepare ## - should_timeout - the command is expected to keep running ## (will be terminated by timeout) ## - run_reflector - instead of uv, pass the args to hd-rum-transcode +## - Linux_only - run just in Linux runner +## - Windows_only - " " " Windows " +## - macOS_only - " " " macOS " +## +## More platforms with "_only" suffix can be specified, however, eg. +## Linux_only,macOS_only. add_test() { eval "test_${test_count}_args=\${1?}" eval "test_${test_count}_opts=\${2-}" @@ -86,6 +92,12 @@ while [ $i -lt $test_count ]; do tool=reflector exec=$run_reflector fi + # skip one-platform only tests if we are not the target + if expr -- "$opts" : '.*_only' >/dev/null; then + if ! expr -- "$opts" : ".*$RUNNER_OS" >/dev/null; then + continue + fi + fi timeout=5 timeout $timeout $exec $args diff --git a/.github/scripts/run_scheduled_tests_data.sh b/.github/scripts/run_scheduled_tests_data.sh index 0defd0342..da63c26a3 100644 --- a/.github/scripts/run_scheduled_tests_data.sh +++ b/.github/scripts/run_scheduled_tests_data.sh @@ -8,6 +8,7 @@ add_test -v # basic sanity test add_test --nonexistent-param should_fail add_test "-d sdl" should_timeout add_test "-t testcard -c lavc:e=libx265 -f rs -d dummy" should_timeout +add_test "-t spout:check_lib" Windows_only # reflector add_test -v run_reflector # basic sanity test diff --git a/src/video_capture/spout.cpp b/src/video_capture/spout.cpp index f973cdf0e..178a5f838 100644 --- a/src/video_capture/spout.cpp +++ b/src/video_capture/spout.cpp @@ -82,6 +82,11 @@ struct state_vidcap_spout { int frames; }; +/** + * @param probe do not abort if unable to create Spout instance + * @returns shared_ptr with valid Spout instance, unless probe=true + * in which case empty shared_ptr may be returned if error + */ static shared_ptr get_spout(bool probe) { @@ -126,6 +131,23 @@ static void usage() } } +static void +check_lib() +{ + static shared_ptr spout = get_spout(false); + constexpr char name[] = "test_sender"; + spout->SetSenderName(name); + if (strcmp(spout->GetSenderName(), name) != 0) { + // in case of the GH-487 problem, it actually doesn't reach + // here but segfaults on the returned name from the library + // because (const char *) 0x1 is returned + fprintf(stderr, "Unexpected sender name: %s (exp: %s)\n", + spout->GetSenderName(), name); + abort(); + } + printf("SpoutLibrary vtable doesn't seem to be corrupted.\n"); +} + static int vidcap_spout_init(struct vidcap_params *params, void **state) { if ((vidcap_params_get_flags(params) & VIDCAP_FLAG_AUDIO_ANY) != 0U) { @@ -147,6 +169,10 @@ static int vidcap_spout_init(struct vidcap_params *params, void **state) usage(); ret = VIDCAP_INIT_NOERR; break; + } else if (strcmp(item, "check_lib") == 0) { + check_lib(); + ret = VIDCAP_INIT_NOERR; + break; } else if (strstr(item, "name=") == item) { char *name = item + strlen("name="); if (strstr(name, "urlencoded=") == name) {