From d8fbe2d7099e3d2705b21dde6394cb7872ef48d4 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Wed, 30 Oct 2024 10:06:06 -0400 Subject: [PATCH 01/26] build(deps): update dependency and paths for build-deps submodule (#3341) --- cmake/dependencies/common.cmake | 2 +- docs/Doxyfile | 2 +- src/cbs.cpp | 6 +++--- third-party/build-deps | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/dependencies/common.cmake b/cmake/dependencies/common.cmake index 5a98a5fd..810f8a87 100644 --- a/cmake/dependencies/common.cmake +++ b/cmake/dependencies/common.cmake @@ -30,7 +30,7 @@ if(NOT DEFINED FFMPEG_PREPARED_BINARIES) set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11) endif() set(FFMPEG_PREPARED_BINARIES - "${CMAKE_SOURCE_DIR}/third-party/build-deps/ffmpeg/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") + "${CMAKE_SOURCE_DIR}/third-party/build-deps/dist/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}") # check if the directory exists if(NOT EXISTS "${FFMPEG_PREPARED_BINARIES}") diff --git a/docs/Doxyfile b/docs/Doxyfile index 6526b8bf..b667429d 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -32,7 +32,7 @@ PROJECT_NAME = Sunshine # project specific settings DOT_GRAPH_MAX_NODES = 60 IMAGE_PATH = ../docs/images -INCLUDE_PATH = ../third-party/build-deps/ffmpeg/Linux-x86_64/include/ +INCLUDE_PATH = ../third-party/build-deps/dist/Linux-x86_64/include/ PREDEFINED += SUNSHINE_BUILD_WAYLAND PREDEFINED += SUNSHINE_TRAY=1 diff --git a/src/cbs.cpp b/src/cbs.cpp index 211541d0..0b795a55 100644 --- a/src/cbs.cpp +++ b/src/cbs.cpp @@ -3,10 +3,10 @@ * @brief Definitions for FFmpeg Coded Bitstream API. */ extern "C" { -#include -#include -#include #include +#include +#include +#include #include } diff --git a/third-party/build-deps b/third-party/build-deps index f8a2a112..ccac3685 160000 --- a/third-party/build-deps +++ b/third-party/build-deps @@ -1 +1 @@ -Subproject commit f8a2a1128eeeae2ca2ed64fd64604a529e24a682 +Subproject commit ccac36854da7697ee3beae0c1d46bb1137403b2e From ec0cdcf0fa711df47bda9e54a4177b7b1199e45d Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:34:18 -0400 Subject: [PATCH 02/26] docs(api): improve api documentation (#3343) --- docs/Doxyfile | 1 + docs/api.md | 64 ++++++++++++ docs/performance_tuning.md | 6 +- docs/troubleshooting.md | 6 +- src/confighttp.cpp | 138 +++++++++++++++++++++++++ src_assets/common/assets/web/apps.html | 8 +- 6 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 docs/api.md diff --git a/docs/Doxyfile b/docs/Doxyfile index b667429d..5695a2d6 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -52,6 +52,7 @@ INPUT = ../README.md \ app_examples.md \ guides.md \ performance_tuning.md \ + api.md \ troubleshooting.md \ building.md \ contributing.md \ diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 00000000..2c6e6409 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,64 @@ +# API + +Sunshine has a RESTful API which can be used to interact with the service. + +Unless otherwise specified, authentication is required for all API calls. You can authenticate using +basic authentication with the admin username and password. + +## GET /api/apps +@copydoc confighttp::getApps() + +## GET /api/logs +@copydoc confighttp::getLogs() + +## POST /api/apps +@copydoc confighttp::saveApp() + +## DELETE /api/apps{index} +@copydoc confighttp::deleteApp() + +## POST /api/covers/upload +@copydoc confighttp::uploadCover() + +## GET /api/config +@copydoc confighttp::getConfig() + +## GET /api/configLocale +@copydoc confighttp::getLocale() + +## POST /api/config +@copydoc confighttp::saveConfig() + +## POST /api/restart +@copydoc confighttp::restart() + +## POST /api/password +@copydoc confighttp::savePassword() + +## POST /api/pin +@copydoc confighttp::savePin() + +## POST /api/clients/unpair-all +@copydoc confighttp::unpairAll() + +## POST /api/clients/unpair +@copydoc confighttp::unpair() + +## GET /api/clients/list +@copydoc confighttp::listClients() + +## GET /api/apps/close +@copydoc confighttp::closeApp() + +
+ +| Previous | Next | +|:--------------------------------------------|--------------------------------------:| +| [Performance Tuning](performance_tuning.md) | [Troubleshooting](troubleshooting.md) | + +
+ +
+ + [TOC] +
diff --git a/docs/performance_tuning.md b/docs/performance_tuning.md index 79612142..b4418f6d 100644 --- a/docs/performance_tuning.md +++ b/docs/performance_tuning.md @@ -13,9 +13,9 @@ Enabling *Fast Sync* in Nvidia settings may help reduce latency.
-| Previous | Next | -|:--------------------|--------------------------------------:| -| [Guides](guides.md) | [Troubleshooting](troubleshooting.md) | +| Previous | Next | +|:--------------------|--------------:| +| [Guides](guides.md) | [API](api.md) |
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 133a063b..c5fcf13b 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -200,9 +200,9 @@ permissions on the disk.
-| Previous | Next | -|:--------------------------------------------|------------------------:| -| [Performance Tuning](performance_tuning.md) | [Building](building.md) | +| Previous | Next | +|:--------------|------------------------:| +| [API](api.md) | [Building](building.md) |
diff --git a/src/confighttp.cpp b/src/confighttp.cpp index 886008dd..756a4688 100644 --- a/src/confighttp.cpp +++ b/src/confighttp.cpp @@ -324,6 +324,11 @@ namespace confighttp { } } + /** + * @brief Get the list of available applications. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void getApps(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -336,6 +341,11 @@ namespace confighttp { response->write(content, headers); } + /** + * @brief Get the logs from the log file. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void getLogs(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -348,6 +358,36 @@ namespace confighttp { response->write(SimpleWeb::StatusCode::success_ok, content, headers); } + /** + * @brief Save an application. If the application already exists, it will be updated, otherwise it will be added. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "name": "Application Name", + * "output": "Log Output Path", + * "cmd": "Command to run the application", + * "index": -1, + * "exclude-global-prep-cmd": false, + * "elevated": false, + * "auto-detach": true, + * "wait-all": true, + * "exit-timeout": 5, + * "prep-cmd": [ + * { + * "do": "Command to prepare", + * "undo": "Command to undo preparation", + * "elevated": false + * } + * ], + * "detached": [ + * "Detached command" + * ], + * "image-path": "Full path to the application image. Must be a png file.", + * } + * @endcode + */ void saveApp(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -436,6 +476,11 @@ namespace confighttp { proc::refresh(config::stream.file_apps); } + /** + * @brief Delete an application. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void deleteApp(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -485,6 +530,18 @@ namespace confighttp { proc::refresh(config::stream.file_apps); } + /** + * @brief Upload a cover image. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "key": "igdb_", + * "url": "https://images.igdb.com/igdb/image/upload/t_cover_big_2x/.png", + * } + * @endcode + */ void uploadCover(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -545,6 +602,11 @@ namespace confighttp { outputTree.put("path", path); } + /** + * @brief Get the configuration settings. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void getConfig(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -570,6 +632,11 @@ namespace confighttp { } } + /** + * @brief Get the locale setting. This endpoint does not require authentication. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void getLocale(resp_https_t response, req_https_t request) { // we need to return the locale whether authenticated or not @@ -588,6 +655,19 @@ namespace confighttp { outputTree.put("locale", config::sunshine.locale); } + /** + * @brief Save the configuration settings. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "key": "value" + * } + * @endcode + * + * @attention{It is recommended to ONLY save the config settings that differ from the default behavior.} + */ void saveConfig(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -624,6 +704,11 @@ namespace confighttp { } } + /** + * @brief Restart Sunshine. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void restart(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -634,6 +719,21 @@ namespace confighttp { platf::restart(); } + /** + * @brief Update existing credentials. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "currentUsername": "Current Username", + * "currentPassword": "Current Password", + * "newUsername": "New Username", + * "newPassword": "New Password", + * "confirmNewPassword": "Confirm New Password" + * } + * @endcode + */ void savePassword(resp_https_t response, req_https_t request) { if (!config::sunshine.username.empty() && !authenticate(response, request)) return; @@ -692,6 +792,18 @@ namespace confighttp { } } + /** + * @brief Send a pin code to the host. The pin is generated from the Moonlight client during the pairing process. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "pin": "", + * "name": "Friendly Client Name" + * } + * @endcode + */ void savePin(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -724,6 +836,11 @@ namespace confighttp { } } + /** + * @brief Unpair all clients. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void unpairAll(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -742,6 +859,17 @@ namespace confighttp { outputTree.put("status", true); } + /** + * @brief Unpair a client. + * @param response The HTTP response object. + * @param request The HTTP request object. + * The body for the post request should be JSON serialized in the following format: + * @code{.json} + * { + * "uuid": "" + * } + * @endcode + */ void unpair(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -773,6 +901,11 @@ namespace confighttp { } } + /** + * @brief Get the list of paired clients. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void listClients(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; @@ -795,6 +928,11 @@ namespace confighttp { outputTree.put("status", true); } + /** + * @brief Close the currently running application. + * @param response The HTTP response object. + * @param request The HTTP request object. + */ void closeApp(resp_https_t response, req_https_t request) { if (!authenticate(response, request)) return; diff --git a/src_assets/common/assets/web/apps.html b/src_assets/common/assets/web/apps.html index f9191eae..e10ce026 100644 --- a/src_assets/common/assets/web/apps.html +++ b/src_assets/common/assets/web/apps.html @@ -506,12 +506,12 @@ if (dotIndex < 0 || slashIndex < 0) { return null; } - const hash = thumb.substring(slashIndex + 1, dotIndex); + const slug = thumb.substring(slashIndex + 1, dotIndex); return { name: game.name, - key: "igdb_" + game.id, - url: "https://images.igdb.com/igdb/image/upload/t_cover_big/" + hash + ".jpg", - saveUrl: "https://images.igdb.com/igdb/image/upload/t_cover_big_2x/" + hash + ".png", + key: `igdb_${game.id}`, + url: `https://images.igdb.com/igdb/image/upload/t_cover_big/${slug}.jpg`, + saveUrl: `https://images.igdb.com/igdb/image/upload/t_cover_big_2x/${slug}.png`, } }).filter(item => item)); } From f418566b3123eca4a426e5c57bf8bf7d9293a3db Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Thu, 31 Oct 2024 19:52:35 -0400 Subject: [PATCH 03/26] chore: remove mee6 (#3350) --- gh-pages-template/index.html | 9 --------- src/system_tray.cpp | 6 ------ src/system_tray.h | 7 ------- 3 files changed, 22 deletions(-) diff --git a/gh-pages-template/index.html b/gh-pages-template/index.html index 440e7f3d..ad8cbbc0 100644 --- a/gh-pages-template/index.html +++ b/gh-pages-template/index.html @@ -686,15 +686,6 @@ src="https://img.shields.io/github/sponsors/lizardbyte?label=Github%20Sponsors&style=for-the-badge&color=green&logo=githubsponsors" > - - MEE6 - Date: Fri, 1 Nov 2024 15:41:59 +0100 Subject: [PATCH 04/26] fix(homebrew): codesign binary only on Intel macOS (#3348) --- packaging/sunshine.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packaging/sunshine.rb b/packaging/sunshine.rb index 1b603fc1..72d0e985 100644 --- a/packaging/sunshine.rb +++ b/packaging/sunshine.rb @@ -115,6 +115,9 @@ class @PROJECT_NAME@ < Formula bin.install "tests/test_sunshine" end + # codesign the binary on intel macs + system "codesign", "-s", "-", "--force", "--deep", bin/"sunshine" if OS.mac? && Hardware::CPU.intel? + bin.install "src_assets/linux/misc/postinst" if OS.linux? end From 9e52ac426df1ed9078677d6b234d5549e1bd5790 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 1 Nov 2024 12:36:25 -0500 Subject: [PATCH 05/26] feat(vaapi): add option to enable strict enforcement of frame size (#3332) * feat(vaapi): add option to enable strict enforcement of frame size * Eliminate the QP fallback code that was only required for VAAPI --- docs/configuration.md | 27 +++ src/config.cpp | 6 + src/config.h | 4 + src/platform/common.h | 2 +- src/platform/linux/vaapi.cpp | 169 +++++++++++++++++- src/video.cpp | 143 ++++----------- src/video.h | 7 - src_assets/common/assets/web/config.html | 11 +- .../web/configs/tabs/ContainerEncoders.vue | 8 + .../configs/tabs/encoders/VAAPIEncoder.vue | 28 +++ .../assets/web/public/assets/locale/en.json | 2 + 11 files changed, 288 insertions(+), 119 deletions(-) create mode 100644 src_assets/common/assets/web/configs/tabs/encoders/VAAPIEncoder.vue diff --git a/docs/configuration.md b/docs/configuration.md index 2b282d1c..d4e33540 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2303,6 +2303,33 @@ editing the `conf` file in a text editor. Use the examples as reference. +## VA-API Encoder + +### vaapi_strict_rc_buffer + + + + + + + + + + + + + + +
Description + Enabling this option can avoid dropped frames over the network during scene changes, but video quality may + be reduced during motion. + @note{This option only applies for H.264 and HEVC when using VA-API [encoder](#encoder) on AMD GPUs.} +
Default@code{} + disabled + @endcode
Example@code{} + vaapi_strict_rc_buffer = enabled + @endcode
+ ## Software Encoder ### sw_preset diff --git a/src/config.cpp b/src/config.cpp index 8475a5e3..a61b69b9 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -377,6 +377,10 @@ namespace config { -1, }, // vt + { + false, // strict_rc_buffer + }, // vaapi + {}, // capture {}, // encoder {}, // adapter_name @@ -1014,6 +1018,8 @@ namespace config { int_f(vars, "vt_software", video.vt.vt_require_sw, vt::force_software_from_view); int_f(vars, "vt_realtime", video.vt.vt_realtime, vt::rt_from_view); + bool_f(vars, "vaapi_strict_rc_buffer", video.vaapi.strict_rc_buffer); + string_f(vars, "capture", video.capture); string_f(vars, "encoder", video.encoder); string_f(vars, "adapter_name", video.adapter_name); diff --git a/src/config.h b/src/config.h index e599afae..891a4079 100644 --- a/src/config.h +++ b/src/config.h @@ -71,6 +71,10 @@ namespace config { int vt_coder; } vt; + struct { + bool strict_rc_buffer; + } vaapi; + std::string capture; std::string encoder; std::string adapter_name; diff --git a/src/platform/common.h b/src/platform/common.h index 368bc733..ee48ed39 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -418,7 +418,7 @@ namespace platf { * @note Implementations may set or modify codec options prior to codec initialization. */ virtual void - init_codec_options(AVCodecContext *ctx, AVDictionary *options) {}; + init_codec_options(AVCodecContext *ctx, AVDictionary **options) {}; /** * @brief Prepare to derive a context. diff --git a/src/platform/linux/vaapi.cpp b/src/platform/linux/vaapi.cpp index ada63700..909ade10 100644 --- a/src/platform/linux/vaapi.cpp +++ b/src/platform/linux/vaapi.cpp @@ -9,6 +9,7 @@ extern "C" { #include +#include #include #include #if !VA_CHECK_VERSION(1, 9, 0) @@ -129,13 +130,173 @@ namespace va { return 0; } + /** + * @brief Finds a supported VA entrypoint for the given VA profile. + * @param profile The profile to match. + * @return A valid encoding entrypoint or 0 on failure. + */ + VAEntrypoint + select_va_entrypoint(VAProfile profile) { + std::vector entrypoints(vaMaxNumEntrypoints(va_display)); + int num_eps; + auto status = vaQueryConfigEntrypoints(va_display, profile, entrypoints.data(), &num_eps); + if (status != VA_STATUS_SUCCESS) { + BOOST_LOG(error) << "Failed to query VA entrypoints: "sv << vaErrorStr(status); + return (VAEntrypoint) 0; + } + entrypoints.resize(num_eps); + + // Sorted in order of descending preference + VAEntrypoint ep_preferences[] = { + VAEntrypointEncSliceLP, + VAEntrypointEncSlice, + VAEntrypointEncPicture + }; + for (auto ep_pref : ep_preferences) { + if (std::find(entrypoints.begin(), entrypoints.end(), ep_pref) != entrypoints.end()) { + return ep_pref; + } + } + + return (VAEntrypoint) 0; + } + + /** + * @brief Determines if a given VA profile is supported. + * @param profile The profile to match. + * @return Boolean value indicating if the profile is supported. + */ + bool + is_va_profile_supported(VAProfile profile) { + std::vector profiles(vaMaxNumProfiles(va_display)); + int num_profs; + auto status = vaQueryConfigProfiles(va_display, profiles.data(), &num_profs); + if (status != VA_STATUS_SUCCESS) { + BOOST_LOG(error) << "Failed to query VA profiles: "sv << vaErrorStr(status); + return false; + } + profiles.resize(num_profs); + + return std::find(profiles.begin(), profiles.end(), profile) != profiles.end(); + } + + /** + * @brief Determines the matching VA profile for the codec configuration. + * @param ctx The FFmpeg codec context. + * @return The matching VA profile or `VAProfileNone` on failure. + */ + VAProfile + get_va_profile(AVCodecContext *ctx) { + if (ctx->codec_id == AV_CODEC_ID_H264) { + // There's no VAAPI profile for H.264 4:4:4 + return VAProfileH264High; + } + else if (ctx->codec_id == AV_CODEC_ID_HEVC) { + switch (ctx->profile) { + case FF_PROFILE_HEVC_REXT: + switch (av_pix_fmt_desc_get(ctx->sw_pix_fmt)->comp[0].depth) { + case 10: + return VAProfileHEVCMain444_10; + case 8: + return VAProfileHEVCMain444; + } + break; + case FF_PROFILE_HEVC_MAIN_10: + return VAProfileHEVCMain10; + case FF_PROFILE_HEVC_MAIN: + return VAProfileHEVCMain; + } + } + else if (ctx->codec_id == AV_CODEC_ID_AV1) { + switch (ctx->profile) { + case FF_PROFILE_AV1_HIGH: + return VAProfileAV1Profile1; + case FF_PROFILE_AV1_MAIN: + return VAProfileAV1Profile0; + } + } + + BOOST_LOG(error) << "Unknown encoder profile: "sv << ctx->profile; + return VAProfileNone; + } + void - init_codec_options(AVCodecContext *ctx, AVDictionary *options) override { - // Don't set the RC buffer size when using H.264 on Intel GPUs. It causes - // major encoding quality degradation. + init_codec_options(AVCodecContext *ctx, AVDictionary **options) override { + auto va_profile = get_va_profile(ctx); + if (va_profile == VAProfileNone || !is_va_profile_supported(va_profile)) { + // Don't bother doing anything if the profile isn't supported + return; + } + + auto va_entrypoint = select_va_entrypoint(va_profile); + if (va_entrypoint == 0) { + // It's possible that only decoding is supported for this profile + return; + } + auto vendor = vaQueryVendorString(va_display); - if (ctx->codec_id != AV_CODEC_ID_H264 || (vendor && !strstr(vendor, "Intel"))) { + + if (va_entrypoint == VAEntrypointEncSliceLP) { + BOOST_LOG(info) << "Using LP encoding mode"sv; + av_dict_set_int(options, "low_power", 1, 0); + } + else { + BOOST_LOG(info) << "Using normal encoding mode"sv; + } + + VAConfigAttrib rc_attr = { VAConfigAttribRateControl }; + auto status = vaGetConfigAttributes(va_display, va_profile, va_entrypoint, &rc_attr, 1); + if (status != VA_STATUS_SUCCESS) { + // Stick to the default rate control (CQP) + rc_attr.value = 0; + } + + VAConfigAttrib slice_attr = { VAConfigAttribEncMaxSlices }; + status = vaGetConfigAttributes(va_display, va_profile, va_entrypoint, &slice_attr, 1); + if (status != VA_STATUS_SUCCESS) { + // Assume only a single slice is supported + slice_attr.value = 1; + } + if (ctx->slices > slice_attr.value) { + BOOST_LOG(info) << "Limiting slice count to encoder maximum: "sv << slice_attr.value; + ctx->slices = slice_attr.value; + } + + // Use VBR with a single frame VBV when the user forces it and for known good cases: + // - Intel GPUs + // - AV1 + // + // VBR ensures the bitstream isn't full of filler data for bitrate undershoots and + // single frame VBV ensures that we don't have large bitrate overshoots (at least + // as much as they can be avoided without pre-analysis). + // + // When we have to resort to the default 1 second VBV for encoding quality reasons, + // we stick to CBR in order to avoid encoding huge frames after bitrate undershoots + // leave headroom available in the RC window. + if (config::video.vaapi.strict_rc_buffer || + (vendor && strstr(vendor, "Intel")) || + ctx->codec_id == AV_CODEC_ID_AV1) { ctx->rc_buffer_size = ctx->bit_rate * ctx->framerate.den / ctx->framerate.num; + + if (rc_attr.value & VA_RC_VBR) { + BOOST_LOG(info) << "Using VBR with single frame VBV size"sv; + av_dict_set(options, "rc_mode", "VBR", 0); + } + else if (rc_attr.value & VA_RC_CBR) { + BOOST_LOG(info) << "Using CBR with single frame VBV size"sv; + av_dict_set(options, "rc_mode", "CBR", 0); + } + else { + BOOST_LOG(warning) << "Using CQP with single frame VBV size"sv; + av_dict_set_int(options, "qp", config::video.qp, 0); + } + } + else if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) { + BOOST_LOG(warning) << "Using CQP rate control"sv; + av_dict_set_int(options, "qp", config::video.qp, 0); + } + else { + BOOST_LOG(info) << "Using default rate control"sv; } } diff --git a/src/video.cpp b/src/video.cpp index ecd92e25..20d22385 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -462,7 +462,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "av1_nvenc"s, }, { @@ -472,7 +471,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "hevc_nvenc"s, }, { @@ -482,7 +480,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "h264_nvenc"s, }, PARALLEL_ENCODING | REF_FRAMES_INVALIDATION | YUV444_SUPPORT // flags @@ -525,7 +522,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "av1_nvenc"s, }, { @@ -552,7 +548,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "hevc_nvenc"s, }, { @@ -576,7 +571,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "h264_nvenc"s, }, PARALLEL_ENCODING @@ -618,7 +612,6 @@ namespace video { { "profile"s, (int) qsv::profile_av1_e::high }, }, {}, // Fallback options - std::nullopt, // QP rate control fallback "av1_qsv"s, }, { @@ -652,7 +645,6 @@ namespace video { // Fallback options { "low_power"s, []() { return config::video.qsv.qsv_slow_hevc ? 0 : 1; } }, }, - std::nullopt, // QP rate control fallback "hevc_qsv"s, }, { @@ -683,7 +675,6 @@ namespace video { // Fallback options { "low_power"s, 0 }, // Some old/low-end Intel GPUs don't support low power encoding }, - std::nullopt, // QP rate control fallback "h264_qsv"s, }, PARALLEL_ENCODING | CBR_WITH_VBR | RELAXED_COMPLIANCE | NO_RC_BUF_LIMIT | YUV444_SUPPORT @@ -716,7 +707,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "av1_amf"s, }, { @@ -741,7 +731,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "hevc_amf"s, }, { @@ -767,7 +756,6 @@ namespace video { // Fallback options { "usage"s, 2 /* AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY */ }, // Workaround for https://github.com/GPUOpen-LibrariesAndSDKs/AMF/issues/410 }, - std::nullopt, // QP rate control fallback "h264_amf"s, }, PARALLEL_ENCODING @@ -797,13 +785,10 @@ namespace video { {}, // YUV444 HDR-specific options {}, // Fallback options - // QP rate control fallback - std::nullopt, - #ifdef ENABLE_BROKEN_AV1_ENCODER - // Due to bugs preventing on-demand IDR frames from working and very poor - // real-time encoding performance, we do not enable libsvtav1 by default. - // It is only suitable for testing AV1 until the IDR frame issue is fixed. + // Due to bugs preventing on-demand IDR frames from working and very poor + // real-time encoding performance, we do not enable libsvtav1 by default. + // It is only suitable for testing AV1 until the IDR frame issue is fixed. "libsvtav1"s, #else {}, @@ -825,7 +810,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "libx265"s, }, { @@ -839,7 +823,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, // QP rate control fallback "libx264"s, }, H264_ONLY | PARALLEL_ENCODING | ALWAYS_REPROBE | YUV444_SUPPORT @@ -857,7 +840,6 @@ namespace video { { // Common options { - { "low_power"s, 1 }, { "async_depth"s, 1 }, { "idr_interval"s, std::numeric_limits::max() }, }, @@ -865,17 +847,12 @@ namespace video { {}, // HDR-specific options {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options - { - // Fallback options - { "low_power"s, 0 }, // Not all VAAPI drivers expose LP entrypoints - }, - std::make_optional("qp"s, &config::video.qp), + {}, // Fallback options "av1_vaapi"s, }, { // Common options { - { "low_power"s, 1 }, { "async_depth"s, 1 }, { "sei"s, 0 }, { "idr_interval"s, std::numeric_limits::max() }, @@ -884,17 +861,12 @@ namespace video { {}, // HDR-specific options {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options - { - // Fallback options - { "low_power"s, 0 }, // Not all VAAPI drivers expose LP entrypoints - }, - std::make_optional("qp"s, &config::video.qp), + {}, // Fallback options "hevc_vaapi"s, }, { // Common options { - { "low_power"s, 1 }, { "async_depth"s, 1 }, { "sei"s, 0 }, { "idr_interval"s, std::numeric_limits::max() }, @@ -903,15 +875,11 @@ namespace video { {}, // HDR-specific options {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options - { - // Fallback options - { "low_power"s, 0 }, // Not all VAAPI drivers expose LP entrypoints - }, - std::make_optional("qp"s, &config::video.qp), + {}, // Fallback options "h264_vaapi"s, }, // RC buffer size will be set in platform code if supported - LIMITED_GOP_SIZE | PARALLEL_ENCODING | SINGLE_SLICE_ONLY | NO_RC_BUF_LIMIT + LIMITED_GOP_SIZE | PARALLEL_ENCODING | NO_RC_BUF_LIMIT }; #endif @@ -938,7 +906,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, "av1_videotoolbox"s, }, { @@ -955,7 +922,6 @@ namespace video { {}, // YUV444 SDR-specific options {}, // YUV444 HDR-specific options {}, // Fallback options - std::nullopt, "hevc_videotoolbox"s, }, { @@ -975,7 +941,6 @@ namespace video { // Fallback options { "flags"s, "-low_delay" }, }, - std::nullopt, "h264_videotoolbox"s, }, DEFAULT @@ -1651,52 +1616,43 @@ namespace video { } } - if (video_format[encoder_t::CBR]) { - auto bitrate = config.bitrate * 1000; - ctx->rc_max_rate = bitrate; - ctx->bit_rate = bitrate; + auto bitrate = config.bitrate * 1000; + ctx->rc_max_rate = bitrate; + ctx->bit_rate = bitrate; - if (encoder.flags & CBR_WITH_VBR) { - // Ensure rc_max_bitrate != bit_rate to force VBR mode - ctx->bit_rate--; - } - else { - ctx->rc_min_rate = bitrate; - } - - if (encoder.flags & RELAXED_COMPLIANCE) { - ctx->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL; - } - - if (!(encoder.flags & NO_RC_BUF_LIMIT)) { - if (!hardware && (ctx->slices > 1 || config.videoFormat == 1)) { - // Use a larger rc_buffer_size for software encoding when slices are enabled, - // because libx264 can severely degrade quality if the buffer is too small. - // libx265 encounters this issue more frequently, so always scale the - // buffer by 1.5x for software HEVC encoding. - ctx->rc_buffer_size = bitrate / ((config.framerate * 10) / 15); - } - else { - ctx->rc_buffer_size = bitrate / config.framerate; - -#ifndef __APPLE__ - if (encoder.name == "nvenc" && config::video.nv_legacy.vbv_percentage_increase > 0) { - ctx->rc_buffer_size += ctx->rc_buffer_size * config::video.nv_legacy.vbv_percentage_increase / 100; - } -#endif - } - } - } - else if (video_format.qp) { - handle_option(*video_format.qp); + if (encoder.flags & CBR_WITH_VBR) { + // Ensure rc_max_bitrate != bit_rate to force VBR mode + ctx->bit_rate--; } else { - BOOST_LOG(error) << "Couldn't set video quality: encoder "sv << encoder.name << " doesn't support qp"sv; - return nullptr; + ctx->rc_min_rate = bitrate; + } + + if (encoder.flags & RELAXED_COMPLIANCE) { + ctx->strict_std_compliance = FF_COMPLIANCE_UNOFFICIAL; + } + + if (!(encoder.flags & NO_RC_BUF_LIMIT)) { + if (!hardware && (ctx->slices > 1 || config.videoFormat == 1)) { + // Use a larger rc_buffer_size for software encoding when slices are enabled, + // because libx264 can severely degrade quality if the buffer is too small. + // libx265 encounters this issue more frequently, so always scale the + // buffer by 1.5x for software HEVC encoding. + ctx->rc_buffer_size = bitrate / ((config.framerate * 10) / 15); + } + else { + ctx->rc_buffer_size = bitrate / config.framerate; + +#ifndef __APPLE__ + if (encoder.name == "nvenc" && config::video.nv_legacy.vbv_percentage_increase > 0) { + ctx->rc_buffer_size += ctx->rc_buffer_size * config::video.nv_legacy.vbv_percentage_increase / 100; + } +#endif + } } // Allow the encoding device a final opportunity to set/unset or override any options - encode_device->init_codec_options(ctx.get(), options); + encode_device->init_codec_options(ctx.get(), &options); if (auto status = avcodec_open2(ctx.get(), codec, &options)) { char err_str[AV_ERROR_MAX_STRING_SIZE] { 0 }; @@ -2419,18 +2375,11 @@ namespace video { return false; } - retry: // If we're expecting failure, use the autoselect ref config first since that will always succeed // if the encoder is available. auto max_ref_frames_h264 = expect_failure ? -1 : validate_config(disp, encoder, config_max_ref_frames); auto autoselect_h264 = max_ref_frames_h264 >= 0 ? max_ref_frames_h264 : validate_config(disp, encoder, config_autoselect); if (autoselect_h264 < 0) { - if (encoder.h264.qp && encoder.h264[encoder_t::CBR]) { - // It's possible the encoder isn't accepting Constant Bit Rate. Turn off CBR and make another attempt - encoder.h264.capabilities.set(); - encoder.h264[encoder_t::CBR] = false; - goto retry; - } return false; } else if (expect_failure) { @@ -2454,7 +2403,6 @@ namespace video { config_autoselect.videoFormat = 1; if (disp->is_codec_supported(encoder.hevc.name, config_autoselect)) { - retry_hevc: auto max_ref_frames_hevc = validate_config(disp, encoder, config_max_ref_frames); // If H.264 succeeded with max ref frames specified, assume that we can count on @@ -2463,13 +2411,6 @@ namespace video { max_ref_frames_hevc : validate_config(disp, encoder, config_autoselect); - if (autoselect_hevc < 0 && encoder.hevc.qp && encoder.hevc[encoder_t::CBR]) { - // It's possible the encoder isn't accepting Constant Bit Rate. Turn off CBR and make another attempt - encoder.hevc.capabilities.set(); - encoder.hevc[encoder_t::CBR] = false; - goto retry_hevc; - } - for (auto [validate_flag, encoder_flag] : packet_deficiencies) { encoder.hevc[encoder_flag] = (max_ref_frames_hevc & validate_flag && autoselect_hevc & validate_flag); } @@ -2492,7 +2433,6 @@ namespace video { config_autoselect.videoFormat = 2; if (disp->is_codec_supported(encoder.av1.name, config_autoselect)) { - retry_av1: auto max_ref_frames_av1 = validate_config(disp, encoder, config_max_ref_frames); // If H.264 succeeded with max ref frames specified, assume that we can count on @@ -2501,13 +2441,6 @@ namespace video { max_ref_frames_av1 : validate_config(disp, encoder, config_autoselect); - if (autoselect_av1 < 0 && encoder.av1.qp && encoder.av1[encoder_t::CBR]) { - // It's possible the encoder isn't accepting Constant Bit Rate. Turn off CBR and make another attempt - encoder.av1.capabilities.set(); - encoder.av1[encoder_t::CBR] = false; - goto retry_av1; - } - for (auto [validate_flag, encoder_flag] : packet_deficiencies) { encoder.av1[encoder_flag] = (max_ref_frames_av1 & validate_flag && autoselect_av1 & validate_flag); } diff --git a/src/video.h b/src/video.h index 6a50b2e3..1f397648 100644 --- a/src/video.h +++ b/src/video.h @@ -120,7 +120,6 @@ namespace video { enum flag_e { PASSED, ///< Indicates the encoder is supported. REF_FRAMES_RESTRICT, ///< Set maximum reference frames. - CBR, ///< Some encoders don't support CBR, if not supported attempt constant quantization parameter instead. DYNAMIC_RANGE, ///< HDR support. YUV444, ///< YUV 4:4:4 support. VUI_PARAMETERS, ///< AMD encoder with VAAPI doesn't add VUI parameters to SPS. @@ -135,7 +134,6 @@ namespace video { switch (flag) { _CONVERT(PASSED); _CONVERT(REF_FRAMES_RESTRICT); - _CONVERT(CBR); _CONVERT(DYNAMIC_RANGE); _CONVERT(YUV444); _CONVERT(VUI_PARAMETERS); @@ -167,11 +165,6 @@ namespace video { std::vector hdr444_options; std::vector fallback_options; - // QP option to set in the case that CBR/VBR is not supported - // by the encoder. If CBR/VBR is guaranteed to be supported, - // don't specify this option to avoid wasteful encoder probing. - std::optional qp; - std::string name; std::bitset capabilities; diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index c9c0a6dd..a7681fdd 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -257,6 +257,13 @@ "vt_realtime": "enabled", }, }, + { + id: "vaapi", + name: "VA-API Encoder", + options: { + "vaapi_strict_rc_buffer": "disabled", + }, + }, { id: "sw", name: "Software Encoder", @@ -283,7 +290,7 @@ var app = document.getElementById("app"); if (this.platform === "windows") { this.tabs = this.tabs.filter((el) => { - return el.id !== "vt"; + return el.id !== "vt" && el.id !== "vaapi"; }); } if (this.platform === "linux") { @@ -293,7 +300,7 @@ } if (this.platform === "macos") { this.tabs = this.tabs.filter((el) => { - return el.id !== "amd" && el.id !== "nv" && el.id !== "qsv"; + return el.id !== "amd" && el.id !== "nv" && el.id !== "qsv" && el.id !== "vaapi"; }); } diff --git a/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue b/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue index 084c3001..1dce1403 100644 --- a/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue +++ b/src_assets/common/assets/web/configs/tabs/ContainerEncoders.vue @@ -5,6 +5,7 @@ import IntelQuickSyncEncoder from './encoders/IntelQuickSyncEncoder.vue' import AmdAmfEncoder from './encoders/AmdAmfEncoder.vue' import VideotoolboxEncoder from './encoders/VideotoolboxEncoder.vue' import SoftwareEncoder from './encoders/SoftwareEncoder.vue' +import VAAPIEncoder from './encoders/VAAPIEncoder.vue' const props = defineProps([ 'platform', @@ -45,6 +46,13 @@ const config = ref(props.config) :config="config" /> + + + +import { ref } from 'vue' + +const props = defineProps([ + 'platform', + 'config', +]) + +const config = ref(props.config) + + + + + diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index 12844fcf..a41617fe 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "If disabled, touchpad presence will not be taken into account during gamepad type selection.", "upnp": "UPnP", "upnp_desc": "Automatically configure port forwarding for streaming over the Internet", + "vaapi_strict_rc_buffer": "Strictly enforce frame bitrate limits for H.264/HEVC on AMD GPUs", + "vaapi_strict_rc_buffer_desc": "Enabling this option can avoid dropped frames over the network during scene changes, but video quality may be reduced during motion.", "virtual_sink": "Virtual Sink", "virtual_sink_desc": "Manually specify a virtual audio device to use. If unset, the device is chosen automatically. We strongly recommend leaving this field blank to use automatic device selection!", "virtual_sink_placeholder": "Steam Streaming Speakers", From 03253fc114bf9b1f1375cee9e2dab7c5c7b8c917 Mon Sep 17 00:00:00 2001 From: Davide Marcoli <69892203+davidemarcoli@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:42:49 +0100 Subject: [PATCH 06/26] docs: fix typo in docker url (#3356) --- docs/getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index 4b0533ee..85ac749f 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -20,7 +20,7 @@ No support will be provided for third party packages!} ### Docker @warning{The Docker images are not recommended for most users.} -Docker images are available on [Dockerhub.io](https://hub.docker.com/repository/docker/lizardbyte/sunshin) +Docker images are available on [Dockerhub.io](https://hub.docker.com/repository/docker/lizardbyte/sunshine) and [ghcr.io](https://github.com/orgs/LizardByte/packages?repo_name=sunshine). See [Docker](../DOCKER_README.md) for more information. From c54664bbe0d1f06b12b64e13c5ec61601f30597c Mon Sep 17 00:00:00 2001 From: "Cathy J. Fitzpatrick" Date: Sat, 2 Nov 2024 09:03:11 -0700 Subject: [PATCH 07/26] build(vite): fix assets directories with symlinks present (#3359) --- vite.config.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/vite.config.js b/vite.config.js index 4bfd66d2..36397f4f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -20,13 +20,22 @@ if (process.env.SUNSHINE_BUILD_HOMEBREW) { console.log("Building for homebrew, using default paths") } else { + // If the paths supplied in the environment variables contain any symbolic links + // at any point in the series of directories, the entire build will fail with + // a cryptic error message like this: + // RollupError: The "fileName" or "name" properties of emitted chunks and assets + // must be strings that are neither absolute nor relative paths. + // To avoid this, we resolve the potential symlinks using `fs.realpathSync` before + // doing anything else with the paths. if (process.env.SUNSHINE_SOURCE_ASSETS_DIR) { - console.log("Using srcdir from Cmake: " + resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web")); - assetsSrcPath = resolve(process.env.SUNSHINE_SOURCE_ASSETS_DIR,"common/assets/web") + let path = resolve(fs.realpathSync(process.env.SUNSHINE_SOURCE_ASSETS_DIR), "common/assets/web"); + console.log("Using srcdir from Cmake: " + path); + assetsSrcPath = path; } if (process.env.SUNSHINE_ASSETS_DIR) { - console.log("Using destdir from Cmake: " + resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web")); - assetsDstPath = resolve(process.env.SUNSHINE_ASSETS_DIR,"assets/web") + let path = resolve(fs.realpathSync(process.env.SUNSHINE_ASSETS_DIR), "assets/web"); + console.log("Using destdir from Cmake: " + path); + assetsDstPath = path; } } From a06d4aefa6e359cacea2d6be1150f9d07b7d7c77 Mon Sep 17 00:00:00 2001 From: "Cathy J. Fitzpatrick" Date: Sat, 2 Nov 2024 10:05:56 -0700 Subject: [PATCH 08/26] fix(macos): prevent indefinite hanging if screen capture is not granted (#3360) --- src/platform/macos/display.mm | 8 ++++++++ src/platform/macos/misc.h | 5 +++++ src/platform/macos/misc.mm | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/platform/macos/display.mm b/src/platform/macos/display.mm index 093e8c17..5220c68d 100644 --- a/src/platform/macos/display.mm +++ b/src/platform/macos/display.mm @@ -5,6 +5,7 @@ #include "src/platform/common.h" #include "src/platform/macos/av_img_t.h" #include "src/platform/macos/av_video.h" +#include "src/platform/macos/misc.h" #include "src/platform/macos/nv12_zero_device.h" #include "src/config.h" @@ -100,6 +101,13 @@ namespace platf { int dummy_img(img_t *img) override { + if (!platf::is_screen_capture_allowed()) { + // If we don't have the screen capture permission, this function will hang + // indefinitely without doing anything useful. Exit instead to avoid this. + // A non-zero return value indicates failure to the calling function. + return 1; + } + auto signal = [av_capture capture:^(CMSampleBufferRef sampleBuffer) { auto new_sample_buffer = std::make_shared(sampleBuffer); auto new_pixel_buffer = std::make_shared(new_sample_buffer->buf); diff --git a/src/platform/macos/misc.h b/src/platform/macos/misc.h index ba0c9507..47d22ed4 100644 --- a/src/platform/macos/misc.h +++ b/src/platform/macos/misc.h @@ -8,6 +8,11 @@ #include +namespace platf { + bool + is_screen_capture_allowed(); +} + namespace dyn { typedef void (*apiproc)(); diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index 5366fdb2..cee850dc 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -42,6 +42,16 @@ namespace platf { CGRequestScreenCaptureAccess(void) __attribute__((weak_import)); #endif + namespace { + auto screen_capture_allowed = std::atomic { false }; + } // namespace + + // Return whether screen capture is allowed for this process. + bool + is_screen_capture_allowed() { + return screen_capture_allowed; + } + std::unique_ptr init() { // This will generate a warning about CGPreflightScreenCaptureAccess and @@ -68,6 +78,8 @@ namespace platf { return nullptr; } #pragma clang diagnostic pop + // Record that we determined that we have the screen capture permission. + screen_capture_allowed = true; return std::make_unique(); } From 39bab450dee8e034544714b98bb8c1751130f06a Mon Sep 17 00:00:00 2001 From: "Cathy J. Fitzpatrick" Date: Sat, 2 Nov 2024 12:00:04 -0700 Subject: [PATCH 09/26] build(docs): parallelize generation of dot graphs (#3361) --- docs/Doxyfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Doxyfile b/docs/Doxyfile index 5695a2d6..b6978d11 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -30,6 +30,7 @@ PROJECT_LOGO = ../sunshine.png PROJECT_NAME = Sunshine # project specific settings +DOT_NUM_THREADS = 0 DOT_GRAPH_MAX_NODES = 60 IMAGE_PATH = ../docs/images INCLUDE_PATH = ../third-party/build-deps/dist/Linux-x86_64/include/ From 2ab73869f6e094bc16cb86bd947043d7d6ed4c2b Mon Sep 17 00:00:00 2001 From: Kelvie Wong Date: Sun, 3 Nov 2024 06:08:07 -0800 Subject: [PATCH 10/26] docs(troubleshooting): Remove workaround for "blur" plugin in KDE (#3363) --- docs/troubleshooting.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index c5fcf13b..7260ec6c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -165,14 +165,6 @@ high as long as the encoder is used. ### Gamescope compatibility Some users have reported stuttering issues when streaming games running within Gamescope. -### Occasional flickering in KDE - -The `blur` plugin causes flickering during streaming for some people. Disable it from the -KDE System Settings or from the commandline: -```bash -qdbus org.kde.KWin /Effects unloadEffect blur -``` - ## macOS ### Dynamic session lookup failed From dbf4fa218a97bbca3047a20e55e99753c54b9faa Mon Sep 17 00:00:00 2001 From: LizardByte-bot <108553330+LizardByte-bot@users.noreply.github.com> Date: Sun, 3 Nov 2024 10:08:58 -0500 Subject: [PATCH 11/26] chore: update global workflows (#3362) --- .github/dependabot.yml | 7 +++++++ .github/workflows/common-lint.yml | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 75b9d1db..a275ce96 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,13 @@ version: 2 updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "daily" + time: "07:30" + open-pull-requests-limit: 10 + - package-ecosystem: "docker" directory: "/" schedule: diff --git a/.github/workflows/common-lint.yml b/.github/workflows/common-lint.yml index 4a62b245..10692ad9 100644 --- a/.github/workflows/common-lint.yml +++ b/.github/workflows/common-lint.yml @@ -193,6 +193,28 @@ jobs: exit 1 fi + - name: Rust - find Cargo.toml + id: run_cargo + if: always() + run: | + # check if Cargo.toml exists + if [ -f "Cargo.toml" ]; then + echo "found_cargo=true" >> $GITHUB_OUTPUT + else + echo "found_cargo=false" >> $GITHUB_OUTPUT + fi + + - name: Rust - setup toolchain + if: always() && steps.run_cargo.outputs.found_cargo == 'true' + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + + - name: Rust - cargo fmt + if: always() && steps.run_cargo.outputs.found_cargo == 'true' + run: | + cargo fmt -- --check + - name: YAML - find files id: yaml_files if: always() From fc5314b1b65f424865d3378a5ebdc0c25ccb2c49 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 3 Nov 2024 14:22:06 -0500 Subject: [PATCH 12/26] build(docs): revert parallelize generation of dot graphs (#3367) Revert "build(docs): parallelize generation of dot graphs (#3361)" This reverts commit 39bab450dee8e034544714b98bb8c1751130f06a. --- docs/Doxyfile | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index b6978d11..5695a2d6 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -30,7 +30,6 @@ PROJECT_LOGO = ../sunshine.png PROJECT_NAME = Sunshine # project specific settings -DOT_NUM_THREADS = 0 DOT_GRAPH_MAX_NODES = 60 IMAGE_PATH = ../docs/images INCLUDE_PATH = ../third-party/build-deps/dist/Linux-x86_64/include/ From 49734489883b39fa7bb04f9df9356825f6770d69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 08:29:57 -0500 Subject: [PATCH 13/26] build(deps): bump third-party/doxyconfig from `4c05198` to `0278e84` (#3370) Bumps [third-party/doxyconfig](https://github.com/LizardByte/doxyconfig) from `4c05198` to `0278e84`. - [Commits](https://github.com/LizardByte/doxyconfig/compare/4c051982c1523f88fbbdb69d44af2ea384dc7052...0278e846779760114394471a0bffc2d53a43e837) --- updated-dependencies: - dependency-name: third-party/doxyconfig dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- third-party/doxyconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/doxyconfig b/third-party/doxyconfig index 4c051982..0278e846 160000 --- a/third-party/doxyconfig +++ b/third-party/doxyconfig @@ -1 +1 @@ -Subproject commit 4c051982c1523f88fbbdb69d44af2ea384dc7052 +Subproject commit 0278e846779760114394471a0bffc2d53a43e837 From 740bbb66096698cb9d695d25ba31a4f500fddc12 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 5 Nov 2024 22:05:22 +0800 Subject: [PATCH 14/26] docs(readme): use official winget badge (#3374) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 61461576..be73eb71 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![Flathub installs](https://img.shields.io/flathub/downloads/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) [![Flathub Version](https://img.shields.io/flathub/v/dev.lizardbyte.app.Sunshine?style=for-the-badge&logo=flathub)](https://flathub.org/apps/dev.lizardbyte.app.Sunshine) [![GHCR](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fipitio.github.io%2Fbackage%2FLizardByte%2FSunshine%2Fsunshine.json&query=%24.downloads&label=ghcr%20pulls&style=for-the-badge&logo=github)](https://github.com/LizardByte/Sunshine/pkgs/container/sunshine) -[![Winget Version](https://img.shields.io/badge/dynamic/json.svg?color=orange&label=Winget&style=for-the-badge&prefix=v&query=$[-1:].name&url=https%3A%2F%2Fapi.github.com%2Frepos%2Fmicrosoft%2Fwinget-pkgs%2Fcontents%2Fmanifests%2Fl%2FLizardByte%2FSunshine&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHuSURBVFhH7ZfNTtRQGIYZiMDwN/IrCAqIhMSNKxcmymVwG+5dcDVsWHgDrtxwCYQVl+BChzDEwSnPY+eQ0sxoOz1mQuBNnpyvTdvz9jun5/SrjfxnJUkyQbMEz2ELduF1l0YUA3QyTrMAa2AnPtyOXsELeAYNyKtV2EC3k3lYgTOwg09ghy/BTp7CKBRV844BOpmmMV2+ySb4BmInG7AKY7AHH+EYqqhZo9PPBG/BVDlOizAD/XQFmnoPXzxRQX8M/CCYS48L6RIc4ygGHK9WGg9HZSZMUNRPVwNJGg5Hg2Qgqh4N3FsDsb6EmgYm07iwwvUxstdxJTwgmILf4CfZ6bb5OHANX8GN5x20IVxnG8ge94pt2xpwU3GnCwayF4Q2G2vgFLzHndFzQdk4q77nNfCdwL28qNyMtmEf3A1/QV5FjDiPWo5jrwf8TWZChTlgJvL4F9QL50/A43qVidTvLcuoM2wDQ1+IkgefgUpLcYwMVBqCKNJA2b0gKNocOIITOIef8C/F/CdMbh/GklynsSawKLHS8d9/B1x2LUqsfFyy3TMsWj5A1cLkotDbYO4JjWWZlZEGv8EbOIR1CAVN2eG8W5oNKgxaeC6DmTJjZs7ixUxpznLPLT+v4sXpoMLcLI3mzFSonDXIEI/M3QCIO4YuimBJ/gAAAABJRU5ErkJggg==)](https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine) +[![Winget Version](https://img.shields.io/winget/v/LizardByte.Sunshine?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHuSURBVFhH7ZfNTtRQGIYZiMDwN/IrCAqIhMSNKxcmymVwG+5dcDVsWHgDrtxwCYQVl+BChzDEwSnPY+eQ0sxoOz1mQuBNnpyvTdvz9jun5/SrjfxnJUkyQbMEz2ELduF1l0YUA3QyTrMAa2AnPtyOXsELeAYNyKtV2EC3k3lYgTOwg09ghy/BTp7CKBRV844BOpmmMV2+ySb4BmInG7AKY7AHH+EYqqhZo9PPBG/BVDlOizAD/XQFmnoPXzxRQX8M/CCYS48L6RIc4ygGHK9WGg9HZSZMUNRPVwNJGg5Hg2Qgqh4N3FsDsb6EmgYm07iwwvUxstdxJTwgmILf4CfZ6bb5OHANX8GN5x20IVxnG8ge94pt2xpwU3GnCwayF4Q2G2vgFLzHndFzQdk4q77nNfCdwL28qNyMtmEf3A1/QV5FjDiPWo5jrwf8TWZChTlgJvL4F9QL50/A43qVidTvLcuoM2wDQ1+IkgefgUpLcYwMVBqCKNJA2b0gKNocOIITOIef8C/F/CdMbh/GklynsSawKLHS8d9/B1x2LUqsfFyy3TMsWj5A1cLkotDbYO4JjWWZlZEGv8EbOIR1CAVN2eG8W5oNKgxaeC6DmTJjZs7ixUxpznLPLT+v4sXpoMLcLI3mzFSonDXIEI/M3QCIO4YuimBJ/gAAAABJRU5ErkJggg==)](https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LizardByte/Sunshine) + [![GitHub Workflow Status (CI)](https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/CI.yml.svg?branch=master&label=CI%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster) [![GitHub Workflow Status (localize)](https://img.shields.io/github/actions/workflow/status/lizardbyte/sunshine/localize.yml.svg?branch=master&label=localize%20build&logo=github&style=for-the-badge)](https://github.com/LizardByte/Sunshine/actions/workflows/localize.yml?query=branch%3Amaster) [![Read the Docs](https://img.shields.io/readthedocs/sunshinestream.svg?label=Docs&style=for-the-badge&logo=readthedocs)](http://sunshinestream.readthedocs.io) From 410f8c2e7013579cc1d4179370f8e7121d4cff92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 08:46:34 -0500 Subject: [PATCH 15/26] build(deps): bump LizardByte/homebrew-release-action from 2024.919.145818 to 2024.1105.185654 in the lizardbyte-actions group (#3375) build(deps): bump LizardByte/homebrew-release-action Bumps the lizardbyte-actions group with 1 update: [LizardByte/homebrew-release-action](https://github.com/lizardbyte/homebrew-release-action). Updates `LizardByte/homebrew-release-action` from 2024.919.145818 to 2024.1105.185654 - [Release notes](https://github.com/lizardbyte/homebrew-release-action/releases) - [Commits](https://github.com/lizardbyte/homebrew-release-action/compare/v2024.919.145818...v2024.1105.185654) --- updated-dependencies: - dependency-name: LizardByte/homebrew-release-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: lizardbyte-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/CI.yml | 4 ++-- .github/workflows/update-homebrew-release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f183243f..541fb57a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -643,7 +643,7 @@ jobs: - name: Validate Homebrew Formula if: | matrix.release != true - uses: LizardByte/homebrew-release-action@v2024.919.145818 + uses: LizardByte/homebrew-release-action@v2024.1105.185654 with: formula_file: ${{ github.workspace }}/homebrew/sunshine.rb git_email: ${{ secrets.GH_BOT_EMAIL }} @@ -692,7 +692,7 @@ jobs: github.repository_owner == 'LizardByte' && matrix.release && needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/homebrew-release-action@v2024.919.145818 + uses: LizardByte/homebrew-release-action@v2024.1105.185654 with: formula_file: ${{ github.workspace }}/homebrew/sunshine-beta.rb git_email: ${{ secrets.GH_BOT_EMAIL }} diff --git a/.github/workflows/update-homebrew-release.yml b/.github/workflows/update-homebrew-release.yml index 16796cb8..60cca023 100644 --- a/.github/workflows/update-homebrew-release.yml +++ b/.github/workflows/update-homebrew-release.yml @@ -60,7 +60,7 @@ jobs: if: >- steps.check-label.outputs.hasTopic == 'true' && fromJson(steps.download.outputs.downloaded_files)[0] - uses: LizardByte/homebrew-release-action@v2024.919.145818 + uses: LizardByte/homebrew-release-action@v2024.1105.185654 with: formula_file: ${{ fromJson(steps.download.outputs.downloaded_files)[0] }} git_email: ${{ secrets.GH_BOT_EMAIL }} From 738a079eb649f9c7d41f5a8d68acea0bfa936929 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Nov 2024 00:57:38 +0000 Subject: [PATCH 16/26] build(deps): bump third-party/doxyconfig from `0278e84` to `4c94524` (#3373) Bumps [third-party/doxyconfig](https://github.com/LizardByte/doxyconfig) from `0278e84` to `4c94524`. - [Commits](https://github.com/LizardByte/doxyconfig/compare/0278e846779760114394471a0bffc2d53a43e837...4c9452482bd01cb36764dc914d4537b278ad4218) --- updated-dependencies: - dependency-name: third-party/doxyconfig dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- third-party/doxyconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/doxyconfig b/third-party/doxyconfig index 0278e846..4c945248 160000 --- a/third-party/doxyconfig +++ b/third-party/doxyconfig @@ -1 +1 @@ -Subproject commit 0278e846779760114394471a0bffc2d53a43e837 +Subproject commit 4c9452482bd01cb36764dc914d4537b278ad4218 From 54ddf375842d28157927d7c0dab352964071d5e4 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 6 Nov 2024 22:57:27 -0600 Subject: [PATCH 17/26] fix(rtsp): fix RTSP timeout after quitting an app (#3376) * fix(rtsp): fix RTSP timeout after quitting an app * fix(process): ignore failures when terminating the process group --- src/process.cpp | 3 ++- src/rtsp.cpp | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/process.cpp b/src/process.cpp index c6cf48b2..26e2c0a3 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -87,7 +87,8 @@ namespace proc { // We always call terminate() even if we waited successfully for all processes above. // This ensures the process group state is consistent with the OS in boost. - group.terminate(); + std::error_code ec; + group.terminate(ec); group.detach(); } diff --git a/src/rtsp.cpp b/src/rtsp.cpp index a6abd9c1..be739313 100644 --- a/src/rtsp.cpp +++ b/src/rtsp.cpp @@ -588,10 +588,6 @@ namespace rtsp_stream { i++; } } - - if (all && !ios.stopped()) { - ios.stop(); - } } /** From 1cab1a5a1e1e3ace8829bc7babf11c6749eaaf28 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 7 Nov 2024 22:15:33 -0600 Subject: [PATCH 18/26] fix(process): avoid leaking zombies and fds in detached processes (#3379) --- src/platform/linux/misc.cpp | 10 ++++++---- src/platform/macos/misc.mm | 10 ++++++---- src/process.cpp | 10 ++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index b7a57c33..89262619 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -241,22 +241,24 @@ namespace platf { bp::child run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { + // clang-format off if (!group) { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec); } } else { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec, *group); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec, *group); } } + // clang-format on } /** diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index cee850dc..30b8dacd 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -182,22 +182,24 @@ namespace platf { bp::child run_command(bool elevated, bool interactive, const std::string &cmd, boost::filesystem::path &working_dir, const bp::environment &env, FILE *file, std::error_code &ec, bp::group *group) { + // clang-format off if (!group) { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec); } } else { if (!file) { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > bp::null, bp::std_err > bp::null, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > bp::null, bp::std_err > bp::null, bp::limit_handles, ec, *group); } else { - return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_out > file, bp::std_err > file, ec, *group); + return bp::child(cmd, env, bp::start_dir(working_dir), bp::std_in < bp::null, bp::std_out > file, bp::std_err > file, bp::limit_handles, ec, *group); } } + // clang-format on } /** diff --git a/src/process.cpp b/src/process.cpp index 26e2c0a3..1c78ff4d 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -269,6 +269,16 @@ namespace proc { int proc_t::running() { +#ifndef _WIN32 + // On POSIX OSes, we must periodically wait for our children to avoid + // them becoming zombies. This must be synchronized carefully with + // calls to bp::wait() and platf::process_group_running() which both + // invoke waitpid() under the hood. + auto reaper = util::fail_guard([]() { + while (waitpid(-1, nullptr, WNOHANG) > 0); + }); +#endif + if (placebo) { return _app_id; } From c40ac8dce92a6c19fd9a8efcf6b4a9ee745f0889 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Fri, 8 Nov 2024 23:05:05 -0500 Subject: [PATCH 19/26] chore(l10n): update translations (#3355) --- src_assets/common/assets/web/public/assets/locale/de.json | 2 ++ .../common/assets/web/public/assets/locale/en_GB.json | 2 ++ .../common/assets/web/public/assets/locale/en_US.json | 2 ++ src_assets/common/assets/web/public/assets/locale/es.json | 2 ++ src_assets/common/assets/web/public/assets/locale/fr.json | 4 +++- src_assets/common/assets/web/public/assets/locale/it.json | 2 ++ src_assets/common/assets/web/public/assets/locale/ja.json | 2 ++ src_assets/common/assets/web/public/assets/locale/pt.json | 2 ++ src_assets/common/assets/web/public/assets/locale/ru.json | 2 ++ src_assets/common/assets/web/public/assets/locale/sv.json | 2 ++ src_assets/common/assets/web/public/assets/locale/tr.json | 2 ++ src_assets/common/assets/web/public/assets/locale/zh.json | 6 ++++-- 12 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src_assets/common/assets/web/public/assets/locale/de.json b/src_assets/common/assets/web/public/assets/locale/de.json index acbc9cfd..751c4df0 100644 --- a/src_assets/common/assets/web/public/assets/locale/de.json +++ b/src_assets/common/assets/web/public/assets/locale/de.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Wenn deaktiviert, wird das Touchpad-Vorhandensein bei der Auswahl des Gamepad-Typs nicht berücksichtigt.", "upnp": "UPnP", "upnp_desc": "Portweiterleitung für Streaming über das Internet automatisch konfigurieren", + "vaapi_strict_rc_buffer": "Bitratenlimit für H.264/HEVC auf AMD GPUs strikt durchsetzen", + "vaapi_strict_rc_buffer_desc": "Wenn Sie diese Option aktivieren, können während der Szenenänderung gelöschte Frames über das Netzwerk vermieden werden, aber die Videoqualität kann während der Bewegung reduziert werden.", "virtual_sink": "Virtueller Sink", "virtual_sink_desc": "Legen Sie ein virtuelles Audiogerät manuell fest. Wenn nicht gesetzt, wird das Gerät automatisch ausgewählt. Wir empfehlen dringend, dieses Feld leer zu lassen, um die automatische Geräteauswahl zu verwenden!", "virtual_sink_placeholder": "Steam Streaming Lautsprecher", diff --git a/src_assets/common/assets/web/public/assets/locale/en_GB.json b/src_assets/common/assets/web/public/assets/locale/en_GB.json index 007af972..ca455f3e 100644 --- a/src_assets/common/assets/web/public/assets/locale/en_GB.json +++ b/src_assets/common/assets/web/public/assets/locale/en_GB.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "If disabled, touchpad presence will not be taken into account during gamepad type selection.", "upnp": "UPnP", "upnp_desc": "Automatically configure port forwarding for streaming over the Internet", + "vaapi_strict_rc_buffer": "Strictly enforce frame bitrate limits for H.264/HEVC on AMD GPUs", + "vaapi_strict_rc_buffer_desc": "Enabling this option can avoid dropped frames over the network during scene changes, but video quality may be reduced during motion.", "virtual_sink": "Virtual Sink", "virtual_sink_desc": "Manually specify a virtual audio device to use. If unset, the device is chosen automatically. We strongly recommend leaving this field blank to use automatic device selection!", "virtual_sink_placeholder": "Steam Streaming Speakers", diff --git a/src_assets/common/assets/web/public/assets/locale/en_US.json b/src_assets/common/assets/web/public/assets/locale/en_US.json index 12844fcf..a41617fe 100644 --- a/src_assets/common/assets/web/public/assets/locale/en_US.json +++ b/src_assets/common/assets/web/public/assets/locale/en_US.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "If disabled, touchpad presence will not be taken into account during gamepad type selection.", "upnp": "UPnP", "upnp_desc": "Automatically configure port forwarding for streaming over the Internet", + "vaapi_strict_rc_buffer": "Strictly enforce frame bitrate limits for H.264/HEVC on AMD GPUs", + "vaapi_strict_rc_buffer_desc": "Enabling this option can avoid dropped frames over the network during scene changes, but video quality may be reduced during motion.", "virtual_sink": "Virtual Sink", "virtual_sink_desc": "Manually specify a virtual audio device to use. If unset, the device is chosen automatically. We strongly recommend leaving this field blank to use automatic device selection!", "virtual_sink_placeholder": "Steam Streaming Speakers", diff --git a/src_assets/common/assets/web/public/assets/locale/es.json b/src_assets/common/assets/web/public/assets/locale/es.json index 5cb2e10b..4de5fd4a 100644 --- a/src_assets/common/assets/web/public/assets/locale/es.json +++ b/src_assets/common/assets/web/public/assets/locale/es.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Si está desactivado, la presencia del touchpad no se tendrá en cuenta durante la selección del tipo gamepad.", "upnp": "UPnP", "upnp_desc": "Configurar automáticamente el reenvío de puertos para transmitir a través de Internet", + "vaapi_strict_rc_buffer": "Aplicar estrictamente límites de bitrate de fotogramas para H.264/HEVC en AMD GPUs", + "vaapi_strict_rc_buffer_desc": "Activar esta opción puede evitar fotogramas soltados en la red durante los cambios de escena, pero la calidad del vídeo puede reducirse durante el movimiento.", "virtual_sink": "Enlace virtual", "virtual_sink_desc": "Especifique manualmente un dispositivo de audio virtual a utilizar. Si no está activado, el dispositivo se elige automáticamente. ¡Recomendamos encarecidamente dejar este campo en blanco para usar la selección automática de dispositivos!", "virtual_sink_placeholder": "Altavoces de Steam Streaming", diff --git a/src_assets/common/assets/web/public/assets/locale/fr.json b/src_assets/common/assets/web/public/assets/locale/fr.json index 00d657f8..a05cdfb7 100644 --- a/src_assets/common/assets/web/public/assets/locale/fr.json +++ b/src_assets/common/assets/web/public/assets/locale/fr.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Si désactivé, la présence du pavé tactile ne sera pas prise en compte lors de la sélection du type du pavé tactile.", "upnp": "UPnP", "upnp_desc": "Configurer automatiquement la redirection de port pour le streaming sur Internet", + "vaapi_strict_rc_buffer": "Appliquer strictement les limites de débit d'images pour H.264/HEVC sur les GPU AMD", + "vaapi_strict_rc_buffer_desc": "L'activation de cette option peut éviter de laisser tomber des images sur le réseau pendant les changements de scène, mais la qualité de la vidéo peut être réduite pendant le mouvement.", "virtual_sink": "Évier virtuel", "virtual_sink_desc": "Spécifiez manuellement un périphérique audio virtuel à utiliser. Si non défini, le périphérique est choisi automatiquement. Nous vous recommandons fortement de laisser ce champ vide pour utiliser la sélection automatique de l'appareil !", "virtual_sink_placeholder": "Steam Streaming Speakers", @@ -387,7 +389,7 @@ "troubleshooting": "Dépannage", "unpair_all": "Dissocier tous les appareils", "unpair_all_error": "Erreur lors de la dissociation", - "unpair_all_success": "Désappairage réussi !", + "unpair_all_success": "Désappairage réussi.", "unpair_desc": "Retirer vos appareils appariés. Les appareils individuellement non appariés avec une session active resteront connectés, mais ne peuvent pas démarrer ou reprendre une session.", "unpair_single_no_devices": "Il n'y a aucun appareil associé.", "unpair_single_success": "Cependant, le(s) appareil(s) peuvent toujours être dans une session active. Utilisez le bouton 'Forcer la fermeture' ci-dessus pour mettre fin à toute session ouverte.", diff --git a/src_assets/common/assets/web/public/assets/locale/it.json b/src_assets/common/assets/web/public/assets/locale/it.json index a0abff4f..07004cb7 100644 --- a/src_assets/common/assets/web/public/assets/locale/it.json +++ b/src_assets/common/assets/web/public/assets/locale/it.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Se disabilitata, la presenza del touchpad non sarà presa in considerazione durante la selezione del tipo del gamepad.", "upnp": "UPnP", "upnp_desc": "Configura automaticamente l'inoltro delle porte per lo streaming su Internet", + "vaapi_strict_rc_buffer": "Applicare rigorosamente i limiti di bitrate frame per H.264/HEVC su GPU AMD", + "vaapi_strict_rc_buffer_desc": "Abilitare questa opzione può evitare di cadere quadri sulla rete durante i cambiamenti di scena, ma la qualità video può essere ridotta durante il movimento.", "virtual_sink": "Uscita Audio Virtuale", "virtual_sink_desc": "Specifica manualmente un dispositivo audio virtuale da usare. Se disattivato, il dispositivo viene scelto automaticamente. Si consiglia vivamente di lasciare vuoto questo campo per utilizzare la selezione automatica del dispositivo!", "virtual_sink_placeholder": "Altoparlanti Streaming Di Steam", diff --git a/src_assets/common/assets/web/public/assets/locale/ja.json b/src_assets/common/assets/web/public/assets/locale/ja.json index 79e8bffc..e7211d6c 100644 --- a/src_assets/common/assets/web/public/assets/locale/ja.json +++ b/src_assets/common/assets/web/public/assets/locale/ja.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "無効にすると、ゲームパッドの種類選択中にタッチパッドの存在が考慮されません。", "upnp": "UPnP", "upnp_desc": "インターネット経由でストリーミングするポート転送を自動的に設定します", + "vaapi_strict_rc_buffer": "AMD GPUでH.264/HEVCのフレームビットレート制限を厳密に強制する", + "vaapi_strict_rc_buffer_desc": "このオプションを有効にすると、シーンの変更中にネットワーク上でフレームがドロップされるのを避けることができますが、移動中にビデオの品質が低下する可能性があります。", "virtual_sink": "Virtual Sink", "virtual_sink_desc": "使用する仮想オーディオデバイスを手動で指定します。未設定の場合は、デバイスが自動的に選択されます。 自動デバイス選択を使用するには、このフィールドを空白のままにすることを強くお勧めします!", "virtual_sink_placeholder": "Steamストリーミングスピーカー", diff --git a/src_assets/common/assets/web/public/assets/locale/pt.json b/src_assets/common/assets/web/public/assets/locale/pt.json index 4aaa6bbe..cbfa4a9f 100644 --- a/src_assets/common/assets/web/public/assets/locale/pt.json +++ b/src_assets/common/assets/web/public/assets/locale/pt.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Se desativada, a presença de touchpad não será tida em conta durante a seleção de tipos de controle.", "upnp": "UPNP", "upnp_desc": "Configurar automaticamente o encaminhamento de portas para transmissão na Internet", + "vaapi_strict_rc_buffer": "Impedir com rigor limites de taxa de bits para H.264/HEVC nas GPUs AMD", + "vaapi_strict_rc_buffer_desc": "Habilitar esta opção pode evitar frames lançados pela rede durante as mudanças de cena, mas a qualidade de vídeo pode ser reduzida durante o movimento.", "virtual_sink": "Pia Virtual", "virtual_sink_desc": "Especifique manualmente um dispositivo de áudio virtual para usar. Se não for definido, o dispositivo é escolhido automaticamente. Recomendamos fortemente deixar este campo em branco para usar a seleção automática de dispositivo!", "virtual_sink_placeholder": "Alto-falantes de streaming Steam", diff --git a/src_assets/common/assets/web/public/assets/locale/ru.json b/src_assets/common/assets/web/public/assets/locale/ru.json index 42307e7c..c0347702 100644 --- a/src_assets/common/assets/web/public/assets/locale/ru.json +++ b/src_assets/common/assets/web/public/assets/locale/ru.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Если отключено, присутствие сенсорной панели не будет учитываться при выборе типа геймпада.", "upnp": "UPnP", "upnp_desc": "Автоматически настраивать переадресацию портов для вещания через Интернет", + "vaapi_strict_rc_buffer": "Строго применять ограничения скорости битрейта для H.264/HEVC на AMD GPU", + "vaapi_strict_rc_buffer_desc": "Включение этой опции позволит избежать сброса кадров по сети во время изменения сцен, но во время движения качество видео может быть снижено.", "virtual_sink": "Виртуальный приёмник", "virtual_sink_desc": "Вручную укажите виртуальное аудио устройство. Если не указано, устройство будет выбрано автоматически. Рекомендуем оставить это поле пустым, для автоматического выбора устройств!", "virtual_sink_placeholder": "Динамики Steam", diff --git a/src_assets/common/assets/web/public/assets/locale/sv.json b/src_assets/common/assets/web/public/assets/locale/sv.json index d25039f3..109b86c8 100644 --- a/src_assets/common/assets/web/public/assets/locale/sv.json +++ b/src_assets/common/assets/web/public/assets/locale/sv.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Om inaktiverad, kommer närvaro av pekplatta inte att beaktas under val av speltyp.", "upnp": "UPPNP", "upnp_desc": "Konfigurera portvidarebefordran automatiskt för streaming över Internet", + "vaapi_strict_rc_buffer": "Strikt genomdriva rambitrate gränser för H.264/HEVC på AMD GPU", + "vaapi_strict_rc_buffer_desc": "Om du aktiverar det här alternativet kan du undvika tappade ramar över nätverket under scenändringar, men videokvaliteten kan minskas under rörelse.", "virtual_sink": "Virtuell sink", "virtual_sink_desc": "Ange manuellt en virtuell ljudenhet som ska användas. Om enheten inte är inställd väljs enheten automatiskt. Vi rekommenderar starkt att lämna detta fält tomt för att använda automatiskt val av enhet!", "virtual_sink_placeholder": "Steam-strömmande högtalare", diff --git a/src_assets/common/assets/web/public/assets/locale/tr.json b/src_assets/common/assets/web/public/assets/locale/tr.json index e17fc9b8..7621d9e9 100644 --- a/src_assets/common/assets/web/public/assets/locale/tr.json +++ b/src_assets/common/assets/web/public/assets/locale/tr.json @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "Devre dışı bırakılırsa, oyun kumandası türü seçimi sırasında dokunmatik yüzey varlığı dikkate alınmaz.", "upnp": "UPnP", "upnp_desc": "İnternet üzerinden akış için port yönlendirmeyi otomatik olarak yapılandırın", + "vaapi_strict_rc_buffer": "AMD GPU'larda H.264/HEVC için kare bit hızı sınırlarını kesin olarak uygulayın", + "vaapi_strict_rc_buffer_desc": "Bu seçeneğin etkinleştirilmesi, sahne değişiklikleri sırasında ağ üzerinden karelerin düşmesini önleyebilir, ancak hareket sırasında video kalitesi düşebilir.", "virtual_sink": "Sanal Lavabo", "virtual_sink_desc": "Kullanılacak sanal ses cihazını manuel olarak belirleyin. Ayarlanmamışsa, cihaz otomatik olarak seçilir. Otomatik cihaz seçimini kullanmak için bu alanı boş bırakmanızı şiddetle tavsiye ederiz!", "virtual_sink_placeholder": "Steam Akış Hoparlörleri", diff --git a/src_assets/common/assets/web/public/assets/locale/zh.json b/src_assets/common/assets/web/public/assets/locale/zh.json index 9fa7ad59..2b586460 100644 --- a/src_assets/common/assets/web/public/assets/locale/zh.json +++ b/src_assets/common/assets/web/public/assets/locale/zh.json @@ -213,7 +213,7 @@ "min_fps_factor": "最小帧率系数", "min_fps_factor_desc": "Sunshine 将使用此系数来计算帧之间的最小时间。当串流的内容主要为静态内容时,稍微增加此值可能会有帮助。更大的值将会使用更大的带宽。", "min_threads": "最低 CPU 线程数", - "min_threads_desc": "提高该值会略微降低编码效率,但为了获得更多的 CPU 内核用于编码,通常是值得的。理想值是在您的硬件配置上以所需的串流设置进行可靠编码的最低值。", + "min_threads_desc": "增加值稍微降低编码效率,但是交易通常值得使用更多的 CPU 核心进行编码。 理想值是可以在您的硬件上的流媒体设置中可靠编码的最低值。", "misc": "杂项选项", "motion_as_ds4": "如果客户端报告游戏手柄存在陀螺仪,则模拟一个 DS4 游戏手柄", "motion_as_ds4_desc": "如果禁用,则在选择游戏手柄类型时不会考虑陀螺仪的存在。", @@ -237,7 +237,7 @@ "nvenc_realtime_hags_desc": "目前,当启用 HAGS、使用实时优先级且 VRAM 利用率接近最大值时,NVIDIA 驱动程序可能会冻结编码器。禁用该选项可将优先级降至高,从而避免冻结,但代价是在 GPU 负载较高时捕捉性能会降低。", "nvenc_spatial_aq": "Spatial AQ", "nvenc_spatial_aq_desc": "将较高的 QP 值分配给视频的平场区域。建议在以较低的比特率进行串流时启用。", - "nvenc_spatial_aq_disabled": "禁用(更快,默认)", + "nvenc_spatial_aq_disabled": "已禁用 (aster, 默认)", "nvenc_spatial_aq_enabled": "启用(较慢)", "nvenc_twopass": "二次编码模式", "nvenc_twopass_desc": "添加二次编码。这样可以检测到更多的运动矢量,更好地分配整个帧的比特率,并更能防止比特率超过限制。不建议禁用它,因为这会导致偶尔的比特率超限和随后的丢包。", @@ -310,6 +310,8 @@ "touchpad_as_ds4_desc": "如果禁用,则在选择游戏手柄类型时不会考虑触摸板的存在。", "upnp": "UPnP", "upnp_desc": "为公网串流自动配置端口转发", + "vaapi_strict_rc_buffer": "在AMD GPU上严格强制执行H.264/HEVC帧比特率限制", + "vaapi_strict_rc_buffer_desc": "启用此选项可以在场景更改时避免在网络上放置帧,但在移动时可能会降低视频质量。", "virtual_sink": "虚拟音频输出设备", "virtual_sink_desc": "手动指定要使用的虚拟音频设备。如果未设置,则会自动选择设备。我们强烈建议将此字段留空,以便使用自动设备选择!", "virtual_sink_placeholder": "Steam Streaming Speakers", From d552073eaf4c05ce102733b08cb9d1619f224405 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 05:00:46 +0000 Subject: [PATCH 20/26] build(deps): bump packaging/linux/flatpak/deps/shared-modules from `4bfaef5` to `0529b12` (#3352) build(deps): bump packaging/linux/flatpak/deps/shared-modules Bumps [packaging/linux/flatpak/deps/shared-modules](https://github.com/flathub/shared-modules) from `4bfaef5` to `0529b12`. - [Commits](https://github.com/flathub/shared-modules/compare/4bfaef549f8b20accacb498fec5da7ad7f6af50f...0529b121864669aa14fac1c67b5684a4bc6542b8) --- updated-dependencies: - dependency-name: packaging/linux/flatpak/deps/shared-modules dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packaging/linux/flatpak/deps/shared-modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/linux/flatpak/deps/shared-modules b/packaging/linux/flatpak/deps/shared-modules index 4bfaef54..0529b121 160000 --- a/packaging/linux/flatpak/deps/shared-modules +++ b/packaging/linux/flatpak/deps/shared-modules @@ -1 +1 @@ -Subproject commit 4bfaef549f8b20accacb498fec5da7ad7f6af50f +Subproject commit 0529b121864669aa14fac1c67b5684a4bc6542b8 From fb1f5b5a894be14a28bb0778b936d596cac45e0b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 9 Nov 2024 14:05:46 -0600 Subject: [PATCH 21/26] fix(hostname): fix handling of non-ASCII hostnames on Windows (#3382) --- src/config.cpp | 2 +- src/platform/common.h | 7 +++++++ src/platform/linux/misc.cpp | 12 ++++++++++++ src/platform/linux/publish.cpp | 2 +- src/platform/macos/misc.mm | 12 ++++++++++++ src/platform/windows/misc.cpp | 10 ++++++++++ src/platform/windows/publish.cpp | 4 +--- tests/unit/platform/test_common.cpp | 7 +++++++ 8 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index a61b69b9..77531cc0 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -410,7 +410,7 @@ namespace config { PRIVATE_KEY_FILE, CERTIFICATE_FILE, - boost::asio::ip::host_name(), // sunshine_name, + platf::get_host_name(), // sunshine_name, "sunshine_state.json"s, // file_state {}, // external_ip }; diff --git a/src/platform/common.h b/src/platform/common.h index ee48ed39..4b2ca66a 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -858,6 +858,13 @@ namespace platf { [[nodiscard]] std::unique_ptr init(); + /** + * @brief Returns the current computer name in UTF-8. + * @return Computer name or a placeholder upon failure. + */ + std::string + get_host_name(); + /** * @brief Gets the supported gamepads for this platform backend. * @details This may be called prior to `platf::input()`! diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 89262619..05c5a264 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -15,6 +15,7 @@ // lib includes #include #include +#include #include #include #include @@ -797,6 +798,17 @@ namespace platf { return std::make_unique(sockfd, reset_options); } + std::string + get_host_name() { + try { + return boost::asio::ip::host_name(); + } + catch (boost::system::system_error &err) { + BOOST_LOG(error) << "Failed to get hostname: "sv << err.what(); + return "Sunshine"s; + } + } + namespace source { enum source_e : std::size_t { #ifdef SUNSHINE_BUILD_CUDA diff --git a/src/platform/linux/publish.cpp b/src/platform/linux/publish.cpp index 91d49248..9b7dbbc5 100644 --- a/src/platform/linux/publish.cpp +++ b/src/platform/linux/publish.cpp @@ -426,7 +426,7 @@ namespace platf::publish { return nullptr; } - auto instance_name = net::mdns_instance_name(boost::asio::ip::host_name()); + auto instance_name = net::mdns_instance_name(platf::get_host_name()); name.reset(avahi::strdup(instance_name.c_str())); client.reset( diff --git a/src/platform/macos/misc.mm b/src/platform/macos/misc.mm index 30b8dacd..9f11669f 100644 --- a/src/platform/macos/misc.mm +++ b/src/platform/macos/misc.mm @@ -23,6 +23,7 @@ #include "src/platform/common.h" #include +#include #include using namespace std::literals; @@ -538,6 +539,17 @@ namespace platf { return std::make_unique(sockfd, reset_options); } + std::string + get_host_name() { + try { + return boost::asio::ip::host_name(); + } + catch (boost::system::system_error &err) { + BOOST_LOG(error) << "Failed to get hostname: "sv << err.what(); + return "Sunshine"s; + } + } + class macos_high_precision_timer: public high_precision_timer { public: void diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index 21fe8b90..419ae749 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -1846,6 +1846,16 @@ namespace platf { return output; } + std::string + get_host_name() { + WCHAR hostname[256]; + if (GetHostNameW(hostname, ARRAYSIZE(hostname)) == SOCKET_ERROR) { + BOOST_LOG(error) << "GetHostNameW() failed: "sv << WSAGetLastError(); + return "Sunshine"s; + } + return to_utf8(hostname); + } + class win32_high_precision_timer: public high_precision_timer { public: win32_high_precision_timer() { diff --git a/src/platform/windows/publish.cpp b/src/platform/windows/publish.cpp index 05208a9c..780d31eb 100644 --- a/src/platform/windows/publish.cpp +++ b/src/platform/windows/publish.cpp @@ -9,8 +9,6 @@ #include #include -#include - #include "misc.h" #include "src/config.h" #include "src/logging.h" @@ -108,7 +106,7 @@ namespace platf::publish { std::wstring domain { SERVICE_TYPE_DOMAIN.data(), SERVICE_TYPE_DOMAIN.size() }; - auto hostname = boost::asio::ip::host_name(); + auto hostname = platf::get_host_name(); auto name = from_utf8(net::mdns_instance_name(hostname) + '.') + domain; auto host = from_utf8(hostname + ".local"); diff --git a/tests/unit/platform/test_common.cpp b/tests/unit/platform/test_common.cpp index 6f1c9bec..8424b4ba 100644 --- a/tests/unit/platform/test_common.cpp +++ b/tests/unit/platform/test_common.cpp @@ -4,6 +4,8 @@ */ #include +#include + #include "../../tests_common.h" struct SetEnvTest: ::testing::TestWithParam> { @@ -47,3 +49,8 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple("SUNSHINE_UNIT_TEST_ENV_VAR", "test_value_0", 0), std::make_tuple("SUNSHINE_UNIT_TEST_ENV_VAR", "test_value_1", 0), std::make_tuple("", "test_value", -1))); + +TEST(HostnameTests, TestAsioEquality) { + // These should be equivalent on all platforms for ASCII hostnames + ASSERT_EQ(platf::get_host_name(), boost::asio::ip::host_name()); +} From d1e7865f31f46b9466626b7c0536275af1d8c0a6 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sat, 9 Nov 2024 16:02:03 -0500 Subject: [PATCH 22/26] build(macos): fix libcurl linking (#3383) --- packaging/sunshine.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packaging/sunshine.rb b/packaging/sunshine.rb index 72d0e985..1c013187 100644 --- a/packaging/sunshine.rb +++ b/packaging/sunshine.rb @@ -38,6 +38,10 @@ class @PROJECT_NAME@ < Formula depends_on "boost" => :recommended depends_on "icu4c" => :recommended + on_macos do + depends_on "openldap" # curl requires this + end + on_linux do depends_on "avahi" depends_on "libcap" From 9abba8048a271963e2512d5c37d25213e0ace3f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 02:52:30 +0000 Subject: [PATCH 23/26] build(deps): bump LizardByte/homebrew-release-action from 2024.1105.185654 to 2024.1115.14934 in the lizardbyte-actions group (#3400) * build(deps): bump LizardByte/homebrew-release-action Bumps the lizardbyte-actions group with 1 update: [LizardByte/homebrew-release-action](https://github.com/lizardbyte/homebrew-release-action). Updates `LizardByte/homebrew-release-action` from 2024.1105.185654 to 2024.1115.14934 - [Release notes](https://github.com/lizardbyte/homebrew-release-action/releases) - [Commits](https://github.com/lizardbyte/homebrew-release-action/compare/v2024.1105.185654...v2024.1115.14934) --- updated-dependencies: - dependency-name: LizardByte/homebrew-release-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: lizardbyte-actions ... Signed-off-by: dependabot[bot] * docs(homebrew): update brew installation steps --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> --- .github/workflows/CI.yml | 4 ++-- .github/workflows/update-homebrew-release.yml | 2 +- docs/getting_started.md | 2 ++ packaging/sunshine.rb | 4 ---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 541fb57a..b82ad7be 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -643,7 +643,7 @@ jobs: - name: Validate Homebrew Formula if: | matrix.release != true - uses: LizardByte/homebrew-release-action@v2024.1105.185654 + uses: LizardByte/homebrew-release-action@v2024.1115.14934 with: formula_file: ${{ github.workspace }}/homebrew/sunshine.rb git_email: ${{ secrets.GH_BOT_EMAIL }} @@ -692,7 +692,7 @@ jobs: github.repository_owner == 'LizardByte' && matrix.release && needs.setup_release.outputs.publish_release == 'true' - uses: LizardByte/homebrew-release-action@v2024.1105.185654 + uses: LizardByte/homebrew-release-action@v2024.1115.14934 with: formula_file: ${{ github.workspace }}/homebrew/sunshine-beta.rb git_email: ${{ secrets.GH_BOT_EMAIL }} diff --git a/.github/workflows/update-homebrew-release.yml b/.github/workflows/update-homebrew-release.yml index 60cca023..65c9698e 100644 --- a/.github/workflows/update-homebrew-release.yml +++ b/.github/workflows/update-homebrew-release.yml @@ -60,7 +60,7 @@ jobs: if: >- steps.check-label.outputs.hasTopic == 'true' && fromJson(steps.download.outputs.downloaded_files)[0] - uses: LizardByte/homebrew-release-action@v2024.1105.185654 + uses: LizardByte/homebrew-release-action@v2024.1115.14934 with: formula_file: ${{ fromJson(steps.download.outputs.downloaded_files)[0] }} git_email: ${{ secrets.GH_BOT_EMAIL }} diff --git a/docs/getting_started.md b/docs/getting_started.md index 85ac749f..e100d5cc 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -240,6 +240,8 @@ This package requires that you have [Homebrew](https://docs.brew.sh/Installation ##### Install ```bash +brew update +brew upgrade brew tap LizardByte/homebrew brew install sunshine ``` diff --git a/packaging/sunshine.rb b/packaging/sunshine.rb index 1c013187..72d0e985 100644 --- a/packaging/sunshine.rb +++ b/packaging/sunshine.rb @@ -38,10 +38,6 @@ class @PROJECT_NAME@ < Formula depends_on "boost" => :recommended depends_on "icu4c" => :recommended - on_macos do - depends_on "openldap" # curl requires this - end - on_linux do depends_on "avahi" depends_on "libcap" From ad7f356aa1d28562ba42520d314d6349f39ac839 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 04:08:18 +0000 Subject: [PATCH 24/26] build(deps): bump packaging/linux/flatpak/deps/flatpak-builder-tools from `9a48b5e` to `6f611f1` (#3390) build(deps): bump packaging/linux/flatpak/deps/flatpak-builder-tools Bumps [packaging/linux/flatpak/deps/flatpak-builder-tools](https://github.com/flatpak/flatpak-builder-tools) from `9a48b5e` to `6f611f1`. - [Commits](https://github.com/flatpak/flatpak-builder-tools/compare/9a48b5e30a53715f1e71a5b804ff99fa46c430a3...6f611f108b1bfeff57dbeb93d34254cd541aeeb7) --- updated-dependencies: - dependency-name: packaging/linux/flatpak/deps/flatpak-builder-tools dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packaging/linux/flatpak/deps/flatpak-builder-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/linux/flatpak/deps/flatpak-builder-tools b/packaging/linux/flatpak/deps/flatpak-builder-tools index 9a48b5e3..6f611f10 160000 --- a/packaging/linux/flatpak/deps/flatpak-builder-tools +++ b/packaging/linux/flatpak/deps/flatpak-builder-tools @@ -1 +1 @@ -Subproject commit 9a48b5e30a53715f1e71a5b804ff99fa46c430a3 +Subproject commit 6f611f108b1bfeff57dbeb93d34254cd541aeeb7 From d5854ae2243da519879260e616744ee78d71aff5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:35:56 -0500 Subject: [PATCH 25/26] build(deps): bump third-party/inputtino from `5d4b8b2` to `8065aeb` (#3401) Bumps [third-party/inputtino](https://github.com/games-on-whales/inputtino) from `5d4b8b2` to `8065aeb`. - [Commits](https://github.com/games-on-whales/inputtino/compare/5d4b8b23f036eee7b36854523f8b41af6b33667e...8065aeb46e5e5980e700d9c1f1be3c4f7ec29630) --- updated-dependencies: - dependency-name: third-party/inputtino dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- third-party/inputtino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third-party/inputtino b/third-party/inputtino index 5d4b8b23..8065aeb4 160000 --- a/third-party/inputtino +++ b/third-party/inputtino @@ -1 +1 @@ -Subproject commit 5d4b8b23f036eee7b36854523f8b41af6b33667e +Subproject commit 8065aeb46e5e5980e700d9c1f1be3c4f7ec29630 From 8d2e322e1ac46345b5fbd443796134a0717c79a2 Mon Sep 17 00:00:00 2001 From: MeeSong <50670906+MiroKaku@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:05:51 +0800 Subject: [PATCH 26/26] fix(cmake): configuration generation fails when BUILD_TESTS is OFF (#3416) --- cmake/targets/common.cmake | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cmake/targets/common.cmake b/cmake/targets/common.cmake index e928b2c5..4cff2ce6 100644 --- a/cmake/targets/common.cmake +++ b/cmake/targets/common.cmake @@ -113,9 +113,15 @@ set_source_files_properties("${CMAKE_SOURCE_DIR}/third-party/ViGEmClient/src/ViG string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) if("${BUILD_TYPE}" STREQUAL "XDEBUG") if(WIN32) - set_source_files_properties("${CMAKE_SOURCE_DIR}/src/nvhttp.cpp" - DIRECTORY "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/tests" - PROPERTIES COMPILE_FLAGS -O2) + if (NOT BUILD_TESTS) + set_source_files_properties("${CMAKE_SOURCE_DIR}/src/nvhttp.cpp" + DIRECTORY "${CMAKE_SOURCE_DIR}" + PROPERTIES COMPILE_FLAGS -O2) + else() + set_source_files_properties("${CMAKE_SOURCE_DIR}/src/nvhttp.cpp" + DIRECTORY "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/tests" + PROPERTIES COMPILE_FLAGS -O2) + endif() endif() else() add_definitions(-DNDEBUG)