diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst index 59d24465..3f4cd2ee 100644 --- a/docs/source/about/advanced_usage.rst +++ b/docs/source/about/advanced_usage.rst @@ -752,6 +752,40 @@ hevc_mode hevc_mode = 2 +capture +^^^^^^^ + +**Description** + Force specific screen capture method. + + .. Caution:: Applies to Linux only. + +**Choices** + +.. table:: + :widths: auto + + ========= =========== + Value Description + ========= =========== + nvfbc Use NVIDIA Frame Buffer Capture to capture direct to GPU memory. This is usually the fastest method for + NVIDIA cards. For GeForce cards it will only work with drivers patched with + `nvidia-patch `_ + or `nvlax `_. + wlr Capture for wlroots based Wayland compositors via DMA-BUF. + kms DRM/KMS screen capture from the kernel. This requires that sunshine has cap_sys_admin capability. + See :ref:`Linux Setup `. + x11 Uses XCB. This is the slowest and most CPU intensive so should be avoided if possible. + ========= =========== + +**Default** + Automatic. Sunshine will use the first capture method available in the order of the table above. + +**Example** + .. code-block:: text + + capture = kms + encoder ^^^^^^^ diff --git a/src/config.cpp b/src/config.cpp index 71b90df8..89c7dba1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -351,6 +351,7 @@ video_t video { -1, }, // vt + {}, // capture {}, // encoder {}, // adapter_name {}, // output_name @@ -882,6 +883,7 @@ void apply_config(std::unordered_map &&vars) { 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); + string_f(vars, "capture", video.capture); string_f(vars, "encoder", video.encoder); string_f(vars, "adapter_name", video.adapter_name); string_f(vars, "output_name", video.output_name); diff --git a/src/config.h b/src/config.h index 2a4a638a..3a2ff822 100644 --- a/src/config.h +++ b/src/config.h @@ -52,6 +52,7 @@ struct video_t { int vt_coder; } vt; + std::string capture; std::string encoder; std::string adapter_name; std::string output_name; diff --git a/src/platform/linux/misc.cpp b/src/platform/linux/misc.cpp index 081fb534..01a7bf60 100644 --- a/src/platform/linux/misc.cpp +++ b/src/platform/linux/misc.cpp @@ -1,4 +1,14 @@ +/** + * @file misc.cpp + */ + +// standard includes +#include + +// lib includes #include +#include +#include #include #include #include @@ -6,17 +16,13 @@ #include #include -#include - +// local includes #include "graphics.h" #include "misc.h" -#include "vaapi.h" - +#include "src/config.h" #include "src/main.h" #include "src/platform/common.h" - -#include -#include +#include "vaapi.h" #ifdef __GNUC__ #define SUNSHINE_GNUC_EXTENSION __extension__ @@ -518,34 +524,44 @@ std::unique_ptr init() { window_system = window_system_e::X11; } #endif + #ifdef SUNSHINE_BUILD_CUDA - if(verify_nvfbc()) { - sources[source::NVFBC] = true; + if(config::video.capture.empty() || config::video.capture == "nvfbc") { + if(verify_nvfbc()) { + sources[source::NVFBC] = true; + } } #endif #ifdef SUNSHINE_BUILD_WAYLAND - if(verify_wl()) { - sources[source::WAYLAND] = true; + if(config::video.capture.empty() || config::video.capture == "wlr") { + if(verify_wl()) { + sources[source::WAYLAND] = true; + } } #endif #ifdef SUNSHINE_BUILD_DRM - if(verify_kms()) { - if(window_system == window_system_e::WAYLAND) { - // On Wayland, using KMS, the cursor is unreliable. - // Hide it by default - display_cursor = false; + if(config::video.capture.empty() || config::video.capture == "kms") { + if(verify_kms()) { + if(window_system == window_system_e::WAYLAND) { + // On Wayland, using KMS, the cursor is unreliable. + // Hide it by default + display_cursor = false; + } } sources[source::KMS] = true; } #endif #ifdef SUNSHINE_BUILD_X11 - if(verify_x11()) { - sources[source::X11] = true; + if(config::video.capture.empty() || config::video.capture == "x11") { + if(verify_x11()) { + sources[source::X11] = true; + } } #endif if(sources.none()) { + BOOST_LOG(error) << "Unable to initialize capture method"sv; return nullptr; } @@ -555,4 +571,4 @@ std::unique_ptr init() { return std::make_unique(); } -} // namespace platf \ No newline at end of file +} // namespace platf diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index a0b4f64f..f4ea4171 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -591,11 +591,25 @@ HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software encoding. - + +
+ + +
+ Force a specific capture method, otherwise Sunshine will use the first one that works. NvFBC requires patched nvidia drivers. +
+
+