Skip to content

Commit

Permalink
Allow VAAPI encoding GPU to be manually specified when using VRAM cap…
Browse files Browse the repository at this point in the history
…ture
  • Loading branch information
cgutman committed Jan 21, 2024
1 parent 6e64398 commit b6b2a29
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
2 changes: 2 additions & 0 deletions docs/source/about/advanced_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ keybindings
**Linux + VA-API**
Unlike with `amdvce` and `nvenc`, it doesn't matter if video encoding is done on a different GPU.

.. note:: This MUST be a render node (renderD*) not a primary node (card*).

.. code-block:: bash
ls /dev/dri/renderD* # to find all devices capable of VAAPI
Expand Down
26 changes: 20 additions & 6 deletions src/platform/linux/kmsgrab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <filesystem>

#include "src/config.h"
#include "src/main.h"
#include "src/platform/common.h"
#include "src/round_robin.h"
Expand Down Expand Up @@ -292,17 +293,30 @@ namespace platf {
return -1;
}

// Open the render node for this card to share with libva.
// If it fails, we'll just share the primary node instead.
char *rendernode_path = drmGetRenderDeviceNameFromFd(fd.el);
if (rendernode_path) {
// The render node will be used for color conversion and encoding operations
std::string rendernode_path = config::video.adapter_name;
if (rendernode_path.empty()) {
char *rendernode_cstr = drmGetRenderDeviceNameFromFd(fd.el);
if (rendernode_cstr) {
rendernode_path.assign(rendernode_cstr);
free(rendernode_cstr);

BOOST_LOG(info) << "Using capture adapter for encoding: "sv << path << " -> "sv << rendernode_path;
}
else {
BOOST_LOG(info) << "Capture adapter has no render node: "sv << path;
}
}
else {
BOOST_LOG(info) << "Using manually selected adapter for encoding: "sv << path << " -> "sv << rendernode_path;
}
if (!rendernode_path.empty()) {
BOOST_LOG(debug) << "Opening render node: "sv << rendernode_path;
render_fd.el = open(rendernode_path, O_RDWR);
render_fd.el = open(rendernode_path.c_str(), O_RDWR);
if (render_fd.el < 0) {
BOOST_LOG(warning) << "Couldn't open render node: "sv << rendernode_path << ": "sv << strerror(errno);
render_fd.el = dup(fd.el);
}
free(rendernode_path);
}

if (drmSetClientCap(fd.el, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) {
Expand Down
2 changes: 1 addition & 1 deletion src_assets/common/assets/web/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ <h2 class="accordion-header">
<label for="adapter_name" class="form-label">Adapter Name</label>
<input class="form-control" id="adapter_name" placeholder="/dev/dri/renderD128" v-model="config.adapter_name" />
<div class="form-text">
Manually specify a GPU to use for capture.<br>
Manually specify a GPU to use for encoding. This MUST be a render node (renderD*) not a primary node (card*).<br>
<pre>ls /dev/dri/renderD* # to find all devices capable of VAAPI</pre>
<pre>
vainfo --display drm --device /dev/dri/renderD129 | \
Expand Down

0 comments on commit b6b2a29

Please sign in to comment.