Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
564ef20
feat: add NVENC encoding support via VA-API (VAEntrypointEncSlice)
efortin Apr 2, 2026
ba535af
fix: harden NVENC encode path for reliability
efortin Apr 2, 2026
6b17691
chore: remove stray file accidentally committed
efortin Apr 2, 2026
ca90f7b
build: add i386 cross-compilation support for 32-bit Steam
efortin Apr 2, 2026
6ff9b61
feat: add 64-bit IPC encode helper for 32-bit Steam Remote Play
efortin Apr 2, 2026
65e59b4
fix: make nvenc-helper persistent daemon, improve helper discovery
efortin Apr 2, 2026
a1a0311
fix: allow surface creation without CUDA for IPC encode-only mode
efortin Apr 2, 2026
325bfb5
fix: force IDR keyframe on first encode frame
efortin Apr 2, 2026
0f2b00d
fix: add recv timeout to IPC helper to detect dead clients
efortin Apr 2, 2026
b713aad
feat: DMA-BUF zero-copy encode path for Steam Remote Play
efortin Apr 2, 2026
b7c3562
feat: DRM-backed GPU surfaces for IPC encode-only mode
efortin Apr 2, 2026
f817f88
fix: per-plane DMA-BUF import with CUarray→linear copy in helper
efortin Apr 2, 2026
d556b91
fix: send NVIDIA opaque fds (not DMA-BUF fds) to IPC helper
efortin Apr 2, 2026
e9c606d
fix: eagerly allocate GPU backing for surfaces in IPC encode mode
efortin Apr 2, 2026
e067609
feat: implement vaDeriveImage for IPC encode-only mode
efortin Apr 2, 2026
425474b
fix: prefer host pixel data over DMA-BUF for IPC encode
efortin Apr 2, 2026
aa6b1a6
fix: forward IDR keyframe requests from VA-API to NVENC
efortin Apr 2, 2026
3a08964
fix: snapshot frame buffer before IPC send to prevent tearing
efortin Apr 2, 2026
bac32a2
fix: use surface dimensions for NV12 copy, not encoder dimensions
efortin Apr 2, 2026
295c82e
feat: add install.sh and systemd user service
efortin Apr 2, 2026
37e7d29
fix: periodic IDR keyframes every 60 frames for streaming recovery
efortin Apr 2, 2026
9d140c5
feat: shared memory for zero-copy IPC frame transfer
efortin Apr 3, 2026
34ee99e
docs: add encoding test suite and document B-frame limitation
efortin Apr 3, 2026
5cdcd49
fix: IPC bridge is CUDA-fallback, not architecture-specific
efortin Apr 3, 2026
6d7ec1c
docs: comprehensive NVENC encoding architecture documentation
efortin Apr 3, 2026
e17df5e
docs: add PR summary with vibe coded disclaimer
efortin Apr 3, 2026
0f39226
docs: add PR summary with vibe coded disclaimer
efortin Apr 3, 2026
c7b2f9b
hardening: fix all issues from C expert code review
efortin Apr 3, 2026
0664fdf
perf: eliminate redundant memory operations in encode hot path
efortin Apr 3, 2026
03263cd
feat: add slice type parsing for future B-frame support
efortin Apr 3, 2026
16db47a
test: add C integration test suite for encode path
efortin Apr 3, 2026
65e1ad4
perf: persistent CUDA buffer + cuMemcpy2D for GPU-side encode
efortin Apr 3, 2026
31396d8
test: add Intel-style config/capability test suite with meson integra…
efortin Apr 3, 2026
6cc717d
docs: update PR summary with test suite, performance, and hardening s…
efortin Apr 3, 2026
8cfe09d
refactor: clean up code style to match project conventions
efortin Apr 3, 2026
7670bb1
refactor: restore type safety and inline field comments in nvenc.h
efortin Apr 3, 2026
fe42f0d
quality: fix all cppcheck and -Dwarning_level=3 issues
efortin Apr 3, 2026
72c7f7e
feat: complete VA-API encode attribute coverage
efortin Apr 3, 2026
137b9e8
docs: add Steam feature usage table to PR summary
efortin Apr 3, 2026
6a479e3
fix: advertise all packed header types to silence Steam warning
efortin Apr 3, 2026
6e11b5c
docs: update packed header status in PR summary
efortin Apr 3, 2026
be37d42
perf: harden nvenc-helper daemon for production
efortin Apr 3, 2026
ea6c024
feat: install.sh auto-detects NVIDIA driver version and installs all …
efortin Apr 3, 2026
7e329bc
docs: fix inconsistencies in PR summary
efortin Apr 4, 2026
2d00dff
chore: remove docs folder — documentation lives in PR description
efortin Apr 4, 2026
6bb9e83
chore: remove markdown from tests — only C test code
efortin Apr 4, 2026
29f508e
fix: return proper surface attributes for encode configs (GStreamer c…
efortin Apr 4, 2026
eaa29c8
docs: replace install.sh with per-distro install guides
efortin Apr 4, 2026
3a58095
test: add GStreamer VA-API encode integration tests
efortin Apr 4, 2026
0ee22e5
Set correct encoder options for 10 bit encoder, do not reset encoder …
mittorn Apr 25, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ va-api-nvidia.files
va-api-nvidia.includes
meson.build.user
.idea
pr_summary.md
22 changes: 22 additions & 0 deletions cross-i386.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[binaries]
c = 'gcc'
cpp = 'g++'
ar = 'ar'
strip = 'strip'
pkg-config = 'pkg-config'

[built-in options]
c_args = ['-m32']
c_link_args = ['-m32']
cpp_args = ['-m32']
cpp_link_args = ['-m32']

[properties]
pkg_config_libdir = ['/usr/lib/i386-linux-gnu/pkgconfig', '/usr/share/pkgconfig', '/usr/lib/pkgconfig']
sys_root = '/'

[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
141 changes: 141 additions & 0 deletions docs/install-fedora.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Installation on Fedora

Tested on Fedora 43 with NVIDIA driver 580.126.18 (RPM Fusion).

## Prerequisites

NVIDIA proprietary driver installed via RPM Fusion (`akmod-nvidia`).

Verify:
```bash
nvidia-smi --query-gpu=driver_version --format=csv,noheader
```

## Step 1 — Install build dependencies (64-bit)

```bash
sudo dnf install -y \
meson ninja-build gcc pkg-config \
libva-devel libdrm-devel mesa-libEGL-devel nv-codec-headers \
libva-utils
```

## Step 2 — Install build dependencies (32-bit, for Steam)

```bash
sudo dnf install -y \
glibc-devel.i686 \
libva-devel.i686 libdrm-devel.i686 mesa-libEGL-devel.i686
```

## Step 3 — Remove stock libva-nvidia-driver

If you have the Fedora-packaged version (v0.0.16, decode-only), remove it first:

```bash
sudo dnf remove -y libva-nvidia-driver
```

## Step 4 — Build 64-bit

```bash
meson setup build64 . --wipe --prefix=/usr
meson compile -C build64
```

## Step 5 — Build 32-bit (cross-compile)

Fedora uses `/usr/lib/pkgconfig` for 32-bit `.pc` files (not `/usr/lib/i386-linux-gnu/`).
Create a cross-file:

```bash
cat > cross-i386-fedora.txt << 'EOF'
[binaries]
c = 'gcc'
cpp = 'g++'
ar = 'ar'
strip = 'strip'
pkg-config = 'pkg-config'

[built-in options]
c_args = ['-m32']
c_link_args = ['-m32']
cpp_args = ['-m32']
cpp_link_args = ['-m32']

[properties]
pkg_config_libdir = ['/usr/lib/pkgconfig', '/usr/share/pkgconfig']
sys_root = '/'

[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'
EOF
```

Then build:

```bash
meson setup build32 . --wipe --cross-file cross-i386-fedora.txt
meson compile -C build32
```

## Step 6 — Install

```bash
sudo meson install -C build64
sudo mkdir -p /usr/lib/dri
sudo cp build32/nvidia_drv_video.so /usr/lib/dri/nvidia_drv_video.so
```

This installs:
- 64-bit driver → `/usr/lib64/dri/nvidia_drv_video.so`
- 32-bit driver → `/usr/lib/dri/nvidia_drv_video.so`
- nvenc-helper → `/usr/libexec/nvenc-helper`

## Step 7 — Systemd user service

```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/nvenc-helper.service << 'EOF'
[Unit]
Description=NVENC encode helper for nvidia-vaapi-driver
Documentation=https://github.com/efortin/nvidia-vaapi-driver
After=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/libexec/nvenc-helper
Restart=on-failure
RestartSec=2

[Install]
WantedBy=graphical-session.target
EOF

systemctl --user daemon-reload
systemctl --user enable nvenc-helper.service
systemctl --user restart nvenc-helper.service
```

## Step 8 — Verify

```bash
# Check helper is running
systemctl --user is-active nvenc-helper.service

# Check VA-API profiles (should show VAEntrypointEncSlice for encode)
vainfo --display drm --device /dev/dri/renderD128
```

Expected output includes both decode (VLD) and encode (EncSlice) entrypoints:
```
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
```

No environment variables needed. Just launch Steam.
114 changes: 114 additions & 0 deletions docs/install-ubuntu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Installation on Ubuntu

Tested on Ubuntu 22.04+ with NVIDIA proprietary driver.

## Prerequisites

NVIDIA proprietary driver installed.

Verify:
```bash
nvidia-smi --query-gpu=driver_version --format=csv,noheader
```

Detect the driver version (used for 32-bit packages):
```bash
NV_VER=$(dpkg -l | grep 'libnvidia-compute-.*amd64' | awk '{print $2}' | sed 's/libnvidia-compute-//' | sed 's/:amd64//' | head -1)
echo "NVIDIA driver: $NV_VER"
```

## Step 1 — Install build dependencies (64-bit)

```bash
sudo apt-get install -y --no-install-recommends \
meson ninja-build gcc pkg-config \
libva-dev libdrm-dev libegl-dev libffmpeg-nvenc-dev \
vainfo
```

## Step 2 — Install build dependencies (32-bit, for Steam)

```bash
sudo dpkg --add-architecture i386
sudo apt-get update

sudo apt-get install -y --no-install-recommends \
gcc-multilib \
libva-dev:i386 libdrm-dev:i386 libegl-dev:i386 \
libnvidia-compute-${NV_VER}:i386 \
libnvidia-encode-${NV_VER}:i386
```

## Step 3 — Build 64-bit

```bash
meson setup build64 . --wipe --prefix=/usr
meson compile -C build64
```

## Step 4 — Build 32-bit (cross-compile)

The repo includes `cross-i386.txt` configured for Ubuntu paths (`/usr/lib/i386-linux-gnu/`).

```bash
meson setup build32 . --wipe --cross-file cross-i386.txt
meson compile -C build32
```

## Step 5 — Install

```bash
sudo meson install -C build64
sudo mkdir -p /usr/lib/i386-linux-gnu/dri
sudo cp build32/nvidia_drv_video.so /usr/lib/i386-linux-gnu/dri/nvidia_drv_video.so
```

This installs:
- 64-bit driver → `/usr/lib/x86_64-linux-gnu/dri/nvidia_drv_video.so`
- 32-bit driver → `/usr/lib/i386-linux-gnu/dri/nvidia_drv_video.so`
- nvenc-helper → `/usr/libexec/nvenc-helper`

## Step 6 — Systemd user service

```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/nvenc-helper.service << 'EOF'
[Unit]
Description=NVENC encode helper for nvidia-vaapi-driver
Documentation=https://github.com/efortin/nvidia-vaapi-driver
After=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/libexec/nvenc-helper
Restart=on-failure
RestartSec=2

[Install]
WantedBy=graphical-session.target
EOF

systemctl --user daemon-reload
systemctl --user enable nvenc-helper.service
systemctl --user restart nvenc-helper.service
```

## Step 7 — Verify

```bash
# Check helper is running
systemctl --user is-active nvenc-helper.service

# Check VA-API profiles (should show VAEntrypointEncSlice for encode)
vainfo --display drm --device /dev/dri/renderD128
```

Expected output includes both decode (VLD) and encode (EncSlice) entrypoints:
```
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
```

No environment variables needed. Just launch Steam.
45 changes: 45 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,14 @@ sources = [
'src/direct/direct-export-buf.c',
'src/direct/nv-driver.c',
'src/h264.c',
'src/h264_encode.c',
'src/hevc.c',
'src/hevc_encode.c',
'src/jpeg.c',
'src/mpeg2.c',
'src/mpeg4.c',
'src/nvenc.c',
'src/nvenc-ipc-client.c',
'src/vabackend.c',
'src/vc1.c',
'src/vp8.c',
Expand All @@ -84,6 +88,47 @@ shared_library(
gnu_symbol_visibility: 'hidden',
)

# Build the 64-bit NVENC helper daemon (only for native builds, not cross-compiled i386)
if host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64'
helper_deps = [
cc.find_library('dl', required : false),
dependency('ffnvcodec', version: '>= 11.1.5.1'),
dependency('threads'),
]
executable(
'nvenc-helper',
'src/nvenc-helper.c',
'src/nvenc-ipc-client.c', # for nvenc_ipc_get_socket_path
dependencies: helper_deps,
install: true,
install_dir: get_option('libexecdir'),
)
endif

# Tests (native builds only, not cross-compiled)
if not meson.is_cross_build()
libva_test_deps = [
dependency('libva'),
dependency('libva-drm'),
cc.find_library('m', required : false),
]

test_encode = executable('test_encode', 'tests/test_encode.c',
dependencies : libva_test_deps, install : false)
test('encode', test_encode, timeout : 60)

test_encode_config = executable('test_encode_config', 'tests/test_encode_config.c',
dependencies : libva_test_deps, install : false)
test('encode_config', test_encode_config, timeout : 60)

gst_launch = find_program('gst-launch-1.0', required : false)
if gst_launch.found()
test('gstreamer', find_program('tests/test_gstreamer.sh'),
timeout : 120,
env : ['GST_VAAPI_ALL_DRIVERS=1', 'LIBVA_DRIVER_NAME=nvidia'])
endif
endif

meson.add_devenv(environment({
'NVD_LOG': '1',
'LIBVA_DRIVER_NAME': 'nvidia',
Expand Down
13 changes: 13 additions & 0 deletions nvenc-helper.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=NVENC encode helper for nvidia-vaapi-driver
Documentation=https://github.com/efortin/nvidia-vaapi-driver
After=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/libexec/nvenc-helper
Restart=on-failure
RestartSec=2

[Install]
WantedBy=graphical-session.target
Loading