Provide ability to force a capture method via configuration. (#1063)

Co-authored-by: KuleRucket <luke.d.tucker@gmail.com>
This commit is contained in:
KuleRucket 2023-03-26 03:26:28 +02:00 committed by GitHub
parent 455155a1c9
commit c6548f4271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 21 deletions

View File

@ -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 <https://github.com/keylase/nvidia-patch/>`_
or `nvlax <https://github.com/keylase/nvidia-patch/>`_.
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 <about/usage: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
^^^^^^^

View File

@ -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<std::string, std::string> &&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);

View File

@ -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;

View File

@ -1,4 +1,14 @@
/**
* @file misc.cpp
*/
// standard includes
#include <fstream>
// lib includes
#include <arpa/inet.h>
#include <boost/asio/ip/address.hpp>
#include <boost/process.hpp>
#include <dlfcn.h>
#include <fcntl.h>
#include <ifaddrs.h>
@ -6,17 +16,13 @@
#include <pwd.h>
#include <unistd.h>
#include <fstream>
// 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 <boost/asio/ip/address.hpp>
#include <boost/process.hpp>
#include "vaapi.h"
#ifdef __GNUC__
#define SUNSHINE_GNUC_EXTENSION __extension__
@ -518,34 +524,44 @@ std::unique_ptr<deinit_t> 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<deinit_t> init() {
return std::make_unique<deinit_t>();
}
} // namespace platf
} // namespace platf

View File

@ -591,11 +591,25 @@
HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software encoding.
</div>
</div>
<!--Encoder -->
<!--Capture-->
<div class="mb-3" v-if="platform === 'linux'">
<label for="capture" class="form-label">Force a Specific Capture Method</label>
<select id="capture" class="form-select" v-model="config.capture">
<option value="">Autodetect</option>
<option value="nvfbc">NvFBC</option>
<option value="wlr">wlroots</option>
<option value="kms">KMS</option>
<option value="x11">X11</option>
</select>
<div class="form-text">
Force a specific capture method, otherwise Sunshine will use the first one that works. NvFBC requires patched nvidia drivers.
</div>
</div>
<!--Encoder-->
<div class="mb-3">
<label for="encoder" class="form-label">Force a Specific Encoder</label>
<select id="encoder" class="form-select" v-model="config.encoder">
<option value>Autodetect</option>
<option value="">Autodetect</option>
<option value="nvenc" v-if="platform === 'windows' || platform === 'linux'">NVIDIA NVENC</option>
<option value="quicksync" v-if="platform === 'windows'">Intel QuickSync</option>
<option value="amdvce" v-if="platform === 'windows'">AMD AMF/VCE</option>
@ -911,6 +925,7 @@
"amd_rc": "vbr_latency",
"amd_usage": "ultralowlatency",
"amd_vbaq": "enabled",
"capture": "",
"controller": "enabled",
"dwmflush": "enabled",
"encoder": "",