Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/>`_.
Comment thread
ReenigneArcher marked this conversation as resolved.
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
Comment thread
ReenigneArcher marked this conversation as resolved.
#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;
}
Comment thread
KuleRucket marked this conversation as resolved.
}
#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