Hardware Acceleration

MediaX supports hardware-accelerated video encoding and decoding on a variety of platforms and GPU hardware.

Supported Platforms

Platform Architecture Status
Ubuntu 24.04 amd64 ✅ Supported
Ubuntu 26.04 amd64 ✅ Supported
AlmaLinux 9 amd64 ✅ Supported
AlmaLinux 10 amd64 ✅ Supported
Ubuntu 24.04 arm64 ✅ Supported
NVIDIA Jetson arm64 ✅ Supported
Android arm64, arm ✅ Supported

CI builds run on Ubuntu 24.04/26.04 (amd64), Ubuntu 24.04 (arm64, on an NVIDIA Jetson) and AlmaLinux 9/10. Windows is not a supported platform (the RTSP client is not available there).

Supported Codecs

Codec Standard Backend Encode (TX) Decode (RX)
Uncompressed (RGB24, YUV 4:2:2, Mono8, Mono16) RFC 4421 CPU (AVX2 / CUDA colourspace) ✅ ✅
H.264 RFC 3984 / RFC 6184 VAAPI ✅ ✅
H.264 RFC 3984 / RFC 6184 NVIDIA NVENC / NVDEC ✅ ✅
H.264 RFC 3984 / RFC 6184 Jetson Multimedia API ✅ ✅
H.264 RFC 3984 / RFC 6184 V4L2 M2M ✅ ✅
H.264 RFC 3984 / RFC 6184 Android AMediaCodec ✅ ✅
H.264 RFC 3984 / RFC 6184 OpenH264 (software) ✅ ✅
H.265 (HEVC) RFC 7798 VAAPI ✅ ✅
AV1 AV1 RTP payload format VAAPI ✅ ✅
AV1 AV1 RTP payload format Jetson Multimedia API — ✅
JPEG RFC 2435 VAAPI ✅ ✅
JPEG RFC 2435 libjpeg (software) ✅ ✅
GigE Vision (RGB8, Mono8/16, Bayer, YCbCr422) AIA GigE Vision 2.x CPU ✅ ✅

The codec is selected by the payloader / depayloader class (or ColourspaceType) and announced through SAP/SDP using the dynamic payload types 96 (uncompressed), 98 (AV1), 103 (H.264) and 104 (H.265). JPEG uses the static payload type 26.

Acceleration Backends

MediaX uses native backends to access hardware encoders and decoders. The following backends are available depending on your hardware:

Backend API Hardware Codecs CMake
VAAPI libva direct Intel (6th gen+), AMD (GCN 3+); AV1: Intel 12th gen+ / AMD RDNA2+ H.264, H.265, AV1, JPEG VAAPI_SUPPORTED=ON (libva detected)
NVENC / NVDEC NVIDIA Video Codec SDK NVIDIA GPUs (Kepler+) H.264 NVENC_SUPPORTED=ON
Jetson Multimedia API NvVideoEncoder / NvVideoDecoder NVIDIA Jetson (Orin etc.) H.264, AV1 (decode) Auto-detected (/usr/src/jetson_multimedia_api)
V4L2 M2M Linux V4L2 stateful codecs Raspberry Pi (bcm2835-codec), Jetson (tegra-venc) H.264 Always built on Linux
AMediaCodec Android NDK Android hardware codecs H.264 Automatic with the NDK toolchain
OpenH264 Cisco OpenH264 Any CPU (software) H.264 BUILD_OPENH264=ON
libjpeg libjpeg / libjpeg-turbo Any CPU (software) JPEG BUILD_JPEG=ON (default, needs libjpeg-dev)
AVX2 Intel SIMD Intel/AMD x86_64 CPUs (Haswell+) Colourspace Auto-detected at runtime
CUDA NVIDIA GPU NVIDIA GPUs Colourspace BUILD_CUDA=ON

Platform / Backend Matrix

✅ supported and exercised in CI or the platform documentation · ⚙ supported when the dependency or device is present (not provisioned in CI) · — not applicable

Backend Ubuntu 24.04 Ubuntu 26.04 AlmaLinux 9 AlmaLinux 10 Ubuntu 24.04 arm64 Jetson Android
VAAPI (Intel) ✅ ✅ ⚙ ⚙ — — —
VAAPI (AMD) ✅ ✅ ⚙ ⚙ — — —
NVENC / NVDEC ⚙ ⚙ ⚙ ⚙ — — —
Jetson Multimedia API — — — — ⚙ ✅ —
V4L2 M2M ⚙ ⚙ ⚙ ⚙ ⚙ ✅ —
AMediaCodec — — — — — — ✅
OpenH264 (SW) ✅ ✅ ⚙ ⚙ ✅ ✅ —
AVX2 (colourspace) ✅ ✅ ✅ ✅ — — —
CUDA (colourspace) ✅ ✅ ⚙ ⚙ ✅ ✅ —

Codec / Backend Matrix

Codec VAAPI NVENC / NVDEC Jetson MMAPI V4L2 M2M AMediaCodec OpenH264 CPU only
Uncompressed — — — — — — ✅
H.264 ✅ ✅ ✅ ✅ ✅ ✅ —
H.265 ✅ — — — — — —
AV1 ✅ — ✅ (decode) — — — —
JPEG ✅ — — — — — ✅

CMake Build Options

Enable hardware acceleration at build time:

# Intel/AMD VAAPI
cmake -DVAAPI_SUPPORTED=ON ..

# CUDA colourspace acceleration
cmake -DBUILD_CUDA=ON ..

# NVIDIA NVENC/NVDEC H.264
cmake -DNVENC_SUPPORTED=ON ..

# OpenH264 software codec
cmake -DBUILD_OPENH264=ON ..

# All options combined
cmake -DVAAPI_SUPPORTED=ON -DBUILD_CUDA=ON ..

Intel VAAPI Setup

Install Drivers

# Ubuntu 24.04 / 26.04
sudo apt install -y \
    intel-media-va-driver \
    libva-dev

Verify Installation

# Check VA-API support
vainfo

Usage

#include "h264/vaapi/rtp_h264_vaapi_payloader.h"
#include "h265/vaapi/rtp_h265_vaapi_payloader.h"

// H.264 with VAAPI
mediax::rtp::h264::vaapi::RtpH264VaapiPayloader h264_payloader;

// H.265 with VAAPI
mediax::rtp::h265::vaapi::RtpH265VaapiPayloader h265_payloader;

Native VAAPI AV1

MediaX includes a native VAAPI AV1 backend that uses libva directly. This is automatically built when CMake detects libva (LIBVA_FOUND).

Requirements

  • Decode: Intel 11th gen+ or AMD RDNA2+
  • Encode: Intel 12th gen+ or AMD RDNA3+

Verify Support

# Check for AV1 profiles
vainfo 2>&1 | grep -i av1

# You should see entries like:
#   VAProfileAV1Profile0   : VAEntrypointVLD        (decode)
#   VAProfileAV1Profile0   : VAEntrypointEncSliceLP  (encode)

Usage

#include "av1/vaapi/rtp_av1_vaapi_payloader.h"
#include "av1/vaapi/rtp_av1_vaapi_depayloader.h"

// AV1 encode + transmit (native VAAPI)
mediax::rtp::av1::vaapi::RtpAv1VaapiPayloader av1_payloader;

// AV1 receive + decode (native VAAPI)
mediax::rtp::av1::vaapi::RtpAv1VaapiDepayloader av1_depayloader;

// Check availability at runtime
if (mediax::rtp::av1::vaapi::RtpAv1VaapiPayloader::IsVaapiAvailable()) {
  // Hardware AV1 encoding is available
}

Android AMediaCodec

MediaX includes a native H.264 backend for Android using the NDK's AMediaCodec API — see Android Support for build instructions, usage, and Qt6 integration (including the multicast lock required for reliable RTP/SAP reception on Android Wi-Fi).

Performance Comparison

Typical encoding performance for 1920×1080 @ 30fps:

Method CPU Usage Latency Notes
OpenH264 (software) ~60% ~30ms Any platform
VAAPI (Intel) ~5% ~10ms Requires Intel GPU

Note

Actual performance varies with resolution, framerate, bitrate, and hardware generation.

CUDA Colourspace Acceleration

MediaX can use CUDA for GPU-accelerated colourspace conversions (RGB ↔ YUV, scaling, etc.) independently of video codec acceleration:

cmake -DBUILD_CUDA=ON ..

The GPU architecture defaults to 75 (Turing), which also runs on newer GPUs through PTX. Choose the architecture of your GPU with -DCMAKE_CUDA_ARCHITECTURES, for example 87 for Jetson Orin, or native to build for the GPU in the build machine (CMake 3.24 or newer). On NVIDIA Jetson the CUDA toolkit is in /usr/local/cuda, add /usr/local/cuda/bin to PATH so CMake finds nvcc. The Ubuntu 24.04 arm64 CI build runs on a Jetson with -DBUILD_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=native.

Supported conversions include:

  • RGB24 ↔ YUV422
  • RGB24 ↔ Mono8/Mono16
  • NV12 → BGRA / RGB
  • YUV → ARGB
  • Bilinear scaling (BGRA)

CUDA acceleration requires an NVIDIA GPU and the CUDA toolkit.

AVX2 Colourspace Acceleration

On x86_64 platforms (Ubuntu 24.04/26.04, AlmaLinux 9/10), MediaX automatically detects AVX2 support at runtime and uses SIMD-accelerated colourspace conversions when available. No build flags are required — AVX2 is compiled as a separate object library with -mavx2 and dispatched via CPUID at startup.

AVX2-accelerated functions:

Function Description
YuvToRgb YUV 4:2:2 (UYVY) → RGB24
YuvToBgra YUV 4:2:2 (UYVY) → BGRA
RgbToYuv RGB24 → YUV 4:2:2 (UYVY)
RgbaToBgra RGBA → BGRA channel swap
RgbToBgra RGB24 → BGRA
Mono8ToBgra Greyscale 8-bit → BGRA

On CPUs without AVX2 (or on ARM platforms), these functions automatically fall back to the optimised scalar CPU implementation. No application code changes are needed.

Platform Availability

Platform AVX2 Status
Ubuntu 24.04 (amd64) ✅ Auto-detected
Ubuntu 26.04 (amd64) ✅ Auto-detected
AlmaLinux 9 / 10 (amd64) ✅ Auto-detected
Ubuntu 24.04 (arm64) — Not available
NVIDIA Jetson (arm64) — Not available

Troubleshooting

No Hardware Acceleration Detected

  1. Verify driver installation with vainfo
  2. Ensure the correct CMake option is enabled (-DVAAPI_SUPPORTED=ON)

Fallback to Software Encoding

If hardware encoding fails, MediaX falls back to OpenH264 software encoding. Check build output for warnings about missing hardware support.

VAAPI Permission Denied

# Add user to video and render groups
sudo usermod -aG video,render $USER
# Log out and back in

Diagnostic Output

The library is silent by default (errors and warnings still go to stderr). To see which codec, encoder and device were selected, set MEDIAX_LOG:

MEDIAX_LOG=info ./my_app    # codec/device initialisation and selected encoder
MEDIAX_LOG=debug ./my_app   # plus per-frame and bitstream diagnostics

Applications can also call mediax::SetLogLevel(mediax::LogLevel::kInfo) (see utils/log.h). The Qt6 session manager uses the Qt logging category mediax.sap.session: QT_LOGGING_RULES="mediax.sap.session.debug=true".

Support