Skip to content

Commit

Permalink
Provide ability to force a capture method via configuration. (#1063)
Browse files Browse the repository at this point in the history
Co-authored-by: KuleRucket <[email protected]>
  • Loading branch information
KuleRucket and KuleRucket authored Mar 26, 2023
1 parent 455155a commit c6548f4
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 21 deletions.
34 changes: 34 additions & 0 deletions docs/source/about/advanced_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^

Expand Down
2 changes: 2 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ video_t video {
-1,
}, // vt

{}, // capture
{}, // encoder
{}, // adapter_name
{}, // output_name
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
54 changes: 35 additions & 19 deletions src/platform/linux/misc.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
/**
* @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>
#include <netinet/udp.h>
#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__
Expand Down Expand Up @@ -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;
}

Expand All @@ -555,4 +571,4 @@ std::unique_ptr<deinit_t> init() {

return std::make_unique<deinit_t>();
}
} // namespace platf
} // namespace platf
19 changes: 17 additions & 2 deletions src_assets/common/assets/web/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,25 @@ <h1 class="my-4">Configuration</h1>
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>
Expand Down Expand Up @@ -911,6 +925,7 @@ <h1 class="my-4">Configuration</h1>
"amd_rc": "vbr_latency",
"amd_usage": "ultralowlatency",
"amd_vbaq": "enabled",
"capture": "",
"controller": "enabled",
"dwmflush": "enabled",
"encoder": "",
Expand Down

0 comments on commit c6548f4

Please sign in to comment.