Skip to content

Commit ae3755b

Browse files
committed
build(hwaccel): add libva 2.22.0 for VA-API backend
- Add libva library definition with libdrm dependency - Patch meson.build to build static library (upstream only supports shared) - Enable vaapi FFmpeg configure flag via FFmpegEnables - Disable X11/GLX/Wayland backends for minimal headless build - Link both libva and libva-drm static libraries Provides VA-API child device support required by QSV hwcontext on Linux.
1 parent b3cb224 commit ae3755b

4 files changed

Lines changed: 86 additions & 22 deletions

File tree

README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Build once, deploy anywhere. No hunting for system FFmpeg. No version mismatches
1515
- **FFmpeg 8.0.1** - Latest release with AV1, H.265, H.264, VP8/9
1616
- **Truly static** - Builds into your binary (just needs system `m` and `stdc++` libraries)
1717
- **Cross-platform** - Linux and macOS (arm64, amd64)
18-
- **Hardware acceleration** - NVENC/NVDEC, VideoToolbox, Vulkan and QuickSync support
18+
- **Hardware acceleration** - NVENC/NVDEC, QuickSync, VA-API, VideoToolbox, and Vulkan support
1919
- **GPL build** - x264, x265, and all the good codecs included
2020
- **Auto-generated** - Thin, predictable bindings directly from FFmpeg headers
2121
- **Preserved documentation** - Original FFmpeg comments in your IDE
@@ -50,7 +50,7 @@ ffmpeg-statigo provides a **curated FFmpeg static library** focused on the core
5050

5151
- **Decoders**: All contemporary formats (H.264, H.265, AV1, VP8/9, Opus, AAC, MP3)
5252
- **Encoders**: Modern codecs for streaming and transcoding (x264, x265, dav1d, rav1e, vpx, lame, opus)
53-
- **Hardware acceleration**: NVENC, QuickSync, VideoToolbox, Vulkan Video
53+
- **Hardware acceleration**: NVENC, QuickSync, VA-API, VideoToolbox, Vulkan Video
5454
- **Containers**: MP4, MKV, WebM, DASH, HLS, and all major formats
5555
- **Filters**: Video scaling, colour conversion, audio resampling, and processing filters
5656
- **Streaming protocols**: RTMP, SRT, HLS, DASH
@@ -86,9 +86,10 @@ If you need complete FFmpeg with all filters, use the official FFmpeg distributi
8686
| FFmpeg | 8.0.1 | A complete, cross-platform solution to record, convert and stream audio and video |
8787
| dav1d | 1.5.2 | AV1 cross-platform decoder, open-source, and focused on speed, size and correctness|
8888
| glslang | 15.4.0 | Khronos-reference front end for GLSL/ESSL and a SPIR-V generator |
89-
| libdrm | 2.4.129 | Direct Rendering Manager library and headers |
89+
| libdrm | 2.4.129 | Direct Rendering Manager library and headers (*Linux only*) |
9090
| libiconv | 1.18 | A character set conversion library (*macOS only*) |
9191
| libsrt | 1.5.5-rc.0a | A transport protocol for ultra low latency live video and audio streaming |
92+
| libva | 2.22.0 | An implementation for VA-API (Video Acceleration API) (*Linux only*) |
9293
| libvpl | 2.15.0 | Intel Video Processing Library (Intel VPL) API (*Linux only*) |
9394
| libvpx | 1.15.2 | High-quality, open video format for the web that's freely available to everyone |
9495
| libwebp | 1.6.0 | A modern image format providing superior lossless and lossy compression |
@@ -112,16 +113,16 @@ Details of codecs, muxers and parsers available in enable in the static ffmpeg l
112113

113114
### Hardware Acceleration Support Matrix
114115

115-
| Codec | NVENC (Linux) | QuickSync (Linux) | VideoToolbox (macOS) | Vulkan Video (Cross-platform) |
116-
|----------------|------------------|-------------------|----------------------|-------------------------------|
117-
| **AV1** | ✅ Encode/Decode | ✅ Encode/Decode | ☑️ Decode | ✅ Encode/Decode |
118-
| **H.266/VVC** || ☑️ Decode || ☑️ Decode |
119-
| **H.265/HEVC** | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode |
120-
| **H.264/AVC** | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode |
121-
| **VP9** | ✅ Encode/Decode | ✅ Encode/Decode || ☑️ Decode |
122-
| **VP8** | ☑️ Dec️ode | ☑️ Decode |||
123-
| **MPEG-2** | ☑️ Decode | ✅ Encode/Decode |||
124-
| **JPEG/MJPEG** | ☑️ Decode | ✅ Encode/Decode |||
116+
| Codec | NVENC (Linux) | VA-API (Linux) | QuickSync (Linux) | VideoToolbox (macOS) | Vulkan Video (Cross-platform) |
117+
|----------------|------------------|-------------------|-------------------|----------------------|-------------------------------|
118+
| **AV1** | ✅ Encode/Decode | ☑️ Encode | ✅ Encode/Decode | ☑️ Decode | ✅ Encode/Decode |
119+
| **H.266/VVC** || | ☑️ Decode || ☑️ Decode |
120+
| **H.265/HEVC** | ✅ Encode/Decode | ☑️ Encode | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode |
121+
| **H.264/AVC** | ✅ Encode/Decode | ☑️ Encode | ✅ Encode/Decode | ✅ Encode/Decode | ✅ Encode/Decode |
122+
| **VP9** | ✅ Encode/Decode | ☑️ Encode | ✅ Encode/Decode || ☑️ Decode |
123+
| **VP8** | ☑️ Decode | ☑️ Encode | ☑️ Decode |||
124+
| **MPEG-2** | ☑️ Decode | ☑️ Encode | ✅ Encode/Decode |||
125+
| **MJPEG** | ☑️ Decode | ☑️ Encode | ✅ Encode/Decode |||
125126

126127
### Capabilities
127128

@@ -132,7 +133,12 @@ Details of codecs, muxers and parsers available in enable in the static ffmpeg l
132133
- Encoding HEVC 10-bit - Pascal and newer
133134
- Decoding AV1 8/10-bit - Ampere and newer
134135
- Encoding AV1 8/10-bit - Ada Lovelace and newer
135-
- **QuickSync (QSV)**: Requires Intel CPU (6th gen Skylake+) or Intel Arc GPU. Uses libvpl/oneVPL dispatcher.
136+
- **VA-API**: Video Acceleration API for Intel, AMD, and NVIDIA (via `nvidia-vaapi-driver`) GPUs on Linux. Provides hardware encoding; decoding uses FFmpeg's hwaccel framework.
137+
- Encoding H.264, HEVC, AV1, VP8, VP9, MPEG-2, MJPEG - Hardware dependent
138+
- Intel: Use `iHD` driver (intel-media-driver) for broadest codec support
139+
- AMD: Use `radeonsi` driver (Mesa) for RDNA/GCN GPUs
140+
- NVIDIA: Use `nvidia` driver (nvidia-vaapi-driver) which translates to NVENC
141+
- **QuickSync (QSV)**: Requires Intel CPU (11th gen Tiger Lake+) or Intel Arc GPU. Uses libvpl/oneVPL dispatcher. Older Intel CPUs (6th-10th gen) should use VA-API instead.
136142
- Decoding & Encoding H.264 8-bit - Any Intel GPU that supports Quick Sync Video
137143
- Decoding & Encoding HEVC 8-bit - Gen 9 Skylake (6th Gen Core) and newer
138144
- Decoding & Encoding HEVC 10-bit - Gen 9.5 Kaby Lake (7th Gen Core), Apollo Lake, Gemini Lake (Pentium and Celeron) and newer

flake.nix

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
# Hardware acceleration runtime (Linux only)
5858
vulkan-loader # Required for Vulkan accelerated encoders
5959
intel-media-driver # VA-API driver for Intel GPUs (iHD_drv_video.so)
60-
vpl-gpu-rt # oneVPL runtime for Intel GPUs (QSV backend)
60+
vpl-gpu-rt # oneVPL runtime for 11th gen+ Intel (Tiger Lake+) QSV
6161
];
6262

6363
# Environment for go-clang CGO compilation and hardware acceleration
@@ -82,7 +82,23 @@
8282
# Intel media driver and oneVPL runtime for QuickSync
8383
export LD_LIBRARY_PATH="${pkgs.intel-media-driver}/lib:$LD_LIBRARY_PATH"
8484
export LD_LIBRARY_PATH="${pkgs.vpl-gpu-rt}/lib:$LD_LIBRARY_PATH"
85+
# oneVPL search path for QSV (11th gen+ Intel only)
8586
export ONEVPL_SEARCH_PATH="${pkgs.vpl-gpu-rt}/lib"
87+
# VA-API driver discovery for libva
88+
# Use system drivers if available, fall back to nix package for Intel
89+
if [ -d "/run/opengl-driver/lib/dri" ]; then
90+
export LIBVA_DRIVERS_PATH="/run/opengl-driver/lib/dri"
91+
fi
92+
# Auto-detect VA-API driver based on GPU vendor (prefer Intel for VA-API)
93+
if lspci -d ::0300 2>/dev/null | grep -qi intel; then
94+
export LIBVA_DRIVER_NAME="iHD"
95+
# Ensure Intel driver path is set even without system drivers
96+
export LIBVA_DRIVERS_PATH="${pkgs.intel-media-driver}/lib/dri:''${LIBVA_DRIVERS_PATH:-}"
97+
elif lspci -d ::0300 2>/dev/null | grep -qi amd; then
98+
export LIBVA_DRIVER_NAME="radeonsi"
99+
elif lspci -d ::0300 2>/dev/null | grep -qi nvidia; then
100+
export LIBVA_DRIVER_NAME="nvidia"
101+
fi
86102
87103
# Vulkan ICD discovery: tell vulkan-loader where to find GPU drivers
88104
# NixOS installs ICDs under /run/opengl-driver/share/vulkan/icd.d/

internal/builder/ffmpeg_args.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -360,32 +360,33 @@ func FFmpegArgsCommon(os string) []string {
360360
"--disable-encoder=h263",
361361
}
362362

363-
// Linux-specific hardware acceleration (NVENC, CUVID, QuickSync)
363+
// Linux-specific hardware acceleration (NVENC, CUVID, QuickSync, VA-API)
364364
if os == "linux" {
365365
args = append(args,
366366
// AV1 hardware acceleration
367-
"--enable-encoder=av1_nvenc,av1_qsv",
367+
"--enable-encoder=av1_nvenc,av1_qsv,av1_vaapi",
368368
"--enable-decoder=av1_cuvid,av1_qsv",
369369
// H.264 hardware acceleration
370-
"--enable-encoder=h264_nvenc,h264_qsv",
370+
"--enable-encoder=h264_nvenc,h264_qsv,h264_vaapi",
371371
"--enable-decoder=h264_cuvid,h264_qsv",
372372
// H.265 hardware acceleration
373-
"--enable-encoder=hevc_nvenc,hevc_qsv",
373+
"--enable-encoder=hevc_nvenc,hevc_qsv,hevc_vaapi",
374374
"--enable-decoder=hevc_cuvid,hevc_qsv",
375375
// MJPEG hardware acceleration
376-
"--enable-encoder=mjpeg_qsv",
376+
"--enable-encoder=mjpeg_qsv,mjpeg_vaapi",
377377
"--enable-decoder=mjpeg_cuvid,mjpeg_qsv",
378378
// MPEG-2 hardware acceleration
379-
"--enable-encoder=mpeg2_qsv",
379+
"--enable-encoder=mpeg2_qsv,mpeg2_vaapi",
380380
"--enable-decoder=mpeg2_cuvid,mpeg2_qsv",
381381
// MPEG-4 Part 2 hardware acceleration
382382
"--enable-decoder=mpeg4_cuvid",
383383
// VC-1 hardware acceleration
384384
"--enable-decoder=vc1_cuvid,vc1_qsv",
385385
// VP8 hardware acceleration
386+
"--enable-encoder=vp8_vaapi",
386387
"--enable-decoder=vp8_cuvid,vp8_qsv",
387388
// VP9 hardware acceleration
388-
"--enable-encoder=vp9_qsv",
389+
"--enable-encoder=vp9_qsv,vp9_vaapi",
389390
"--enable-decoder=vp9_cuvid,vp9_qsv",
390391
// VVC hardware acceleration
391392
"--enable-decoder=vvc_qsv",

internal/builder/libraries.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var allLibraryDefinitions = []*Library{
2727

2828
// Hardware acceleration
2929
libdrm,
30+
libva,
3031
libvpl,
3132
nvcodecheaders,
3233
vulkanheaders,
@@ -320,6 +321,46 @@ var libdrm = &Library{
320321
LinkLibs: []string{"libdrm"},
321322
}
322323

324+
// libva - Video Acceleration API (Linux only, provides VA-API backend for QSV)
325+
var libva = &Library{
326+
Name: "libva",
327+
URL: "https://github.com/intel/libva/releases/download/2.22.0/libva-2.22.0.tar.bz2",
328+
Platform: []string{"linux"},
329+
Dependencies: []*Library{libdrm},
330+
FFmpegEnables: []string{"vaapi"},
331+
BuildSystem: &MesonBuild{},
332+
ConfigureArgs: func(os string) []string {
333+
return []string{
334+
// Note: -Ddefault_library=static is added automatically by MesonBuild
335+
"-Dwith_x11=no",
336+
"-Dwith_glx=no",
337+
"-Dwith_wayland=no",
338+
"-Dwith_win32=no",
339+
"-Dwith_legacy=",
340+
"-Denable_docs=false",
341+
}
342+
},
343+
PostExtract: func(srcPath string) error {
344+
// Patch va/meson.build to use library() instead of shared_library()
345+
// This allows respecting the default_library=static option
346+
mesonBuild := filepath.Join(srcPath, "va", "meson.build")
347+
content, err := os.ReadFile(mesonBuild)
348+
if err != nil {
349+
return fmt.Errorf("failed to read va/meson.build: %w", err)
350+
}
351+
352+
// Replace shared_library with library (respects default_library option)
353+
patched := strings.ReplaceAll(string(content), "shared_library(", "library(")
354+
355+
if err := os.WriteFile(mesonBuild, []byte(patched), 0644); err != nil {
356+
return fmt.Errorf("failed to write patched va/meson.build: %w", err)
357+
}
358+
359+
return nil
360+
},
361+
LinkLibs: []string{"libva", "libva-drm"},
362+
}
363+
323364
// libvpl - Intel VPL/oneVPL headers (Linux only, for QuickSync)
324365
var libvpl = &Library{
325366
Name: "libvpl",

0 commit comments

Comments
 (0)