wiki
Plex

Intel VAAPI hardware decoding in Plex Desktop (Flatpak)

Force Plex Desktop Flatpak to use Intel Quick Sync VAAPI decode on a hybrid Intel + NVIDIA laptop, including the render-node and EGL fixes.

Plex Desktop uses mpv for playback. On a hybrid-graphics laptop (Intel iGPU + NVIDIA dGPU) the Flatpak often silently falls back to software decoding even though host VAAPI works. Getting hardware decode requires fixing three separate things:

  1. Driver path — libva can't find the iHD driver inside the sandbox.
  2. Render node — mpv defaults to the NVIDIA node, where the Intel driver can't initialize.
  3. Render backend — zero-copy VAAPI needs an EGL OpenGL context; plain GLX is refused.

The result is either full software decoding, or (after fixing 1 + 2) hardware copy-back decoding, or (after all three) true zero-copy decoding.

Package: tv.plex.PlexDesktop Config dir: ~/.var/app/tv.plex.PlexDesktop/data/plex/ Applies to X11 sessions. Adjust the EGL step for Wayland (see notes).

1. Confirm host VAAPI works

vainfo

You want va_openDriver() returns 0 and a driver line like Intel iHD driver for Intel(R) Gen Graphics. If the host itself can't do VAAPI, fix that first — nothing below will help.

2. Identify the Intel render node

On hybrid systems the render-node numbering is not fixed — the NVIDIA GPU is often renderD128 and Intel renderD129, but verify:

ls -l /dev/dri/by-path/
pci-0000:00:02.0-render -> ../renderD129   # Intel iGPU  (bus 00:02.0)
pci-0000:01:00.0-render -> ../renderD128   # NVIDIA dGPU (bus 01:00.0)

The Intel iGPU is the one on PCI bus 00:02.0. Note its renderD* number — that's the node you'll pin mpv to below (renderD129 in this example).

Confirm the Intel driver only initializes on the Intel node (this is why the default fails):

# Intel node → succeeds
LIBVA_DRIVER_NAME=iHD vainfo --display drm --device /dev/dri/renderD129
# NVIDIA node → "unsupported drm device by media driver" / va_openDriver() returns 18
LIBVA_DRIVER_NAME=iHD vainfo --display drm --device /dev/dri/renderD128

3. Install the VAAPI runtime extension (matching the runtime version)

# find the runtime version, e.g. 23.08
flatpak info tv.plex.PlexDesktop | grep -i runtime

flatpak install flathub org.freedesktop.Platform.VAAPI.Intel//23.08

The extension mounts the driver into a subdirectory libva does not search by default:

flatpak run --command=sh tv.plex.PlexDesktop -c \
  'find /usr/lib -name "iHD_drv_video.so"'
# → /usr/lib/x86_64-linux-gnu/dri/intel-vaapi-driver/iHD_drv_video.so

4. Set the Flatpak environment overrides

flatpak override --user tv.plex.PlexDesktop \
  --device=dri \
  --env=LIBVA_DRIVER_NAME=iHD \
  --env=LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri/intel-vaapi-driver \
  --env=DRI_PRIME=0 \
  --env=QT_XCB_GL_INTEGRATION=xcb_egl
VariableWhy
LIBVA_DRIVER_NAME=iHDUse the modern Intel media driver (needed for recent Intel GPUs / AV1)
LIBVA_DRIVERS_PATH=…/intel-vaapi-driverPoint libva at the subdirectory where the extension puts the .so
DRI_PRIME=0Keep GL rendering on the Intel GPU
QT_XCB_GL_INTEGRATION=xcb_eglForce Qt's OpenGL onto EGL — required for zero-copy VAAPI interop (X11 defaults to GLX, which mpv refuses for VAAPI)

If you previously set QT_QUICK_BACKEND=opengl to fix white/corrupted posters, keep it — these overrides accumulate, they don't replace it.

Verify all of them reach the sandbox:

flatpak run --command=sh tv.plex.PlexDesktop -c 'env | grep -iE "LIBVA|DRI_|QT_"'

5. Pin mpv to the Intel node and pick the decode mode

Plex reads ~/.var/app/tv.plex.PlexDesktop/data/plex/mpv.conf before every playback (see mpv.conf.md in the same dir). Set the render node to the Intel node you found in step 2:

# ~/.var/app/tv.plex.PlexDesktop/data/plex/mpv.conf
hwdec=vaapi
vaapi-device=/dev/dri/renderD129

Which hwdec value?

ValueDecodeFrame pathNeeds EGL backend?
vaapiIntel GPUzero-copy (stays in GPU)Yes
vaapi-copyIntel GPUcopied to RAM, then displayedNo
(software)CPU
  • Use vaapi (zero-copy) if step 4's EGL override works with your UI — lowest CPU, power, and memory bandwidth.
  • Fall back to vaapi-copy if EGL causes UI glitches or interop is refused. Still decodes on the Intel Video engine; only adds a cheap per-frame RAM copy. This is the robust, always-works option.
  • Do not use auto-copy on a hybrid system — it may select NVIDIA's cuda-copy (NVDEC) instead of Intel VAAPI.

6. Restart and verify

flatpak kill tv.plex.PlexDesktop

Reopen Plex, make sure Settings → Player → "Use hardware decoding" is on, and play an H.264/HEVC file.

Check the log~/.var/app/tv.plex.PlexDesktop/data/plex/Logs/Plex.log:

grep -iE 'vaapi|hwdec|Using (software|hardware)|only works with' \
  ~/.var/app/tv.plex.PlexDesktop/data/plex/Logs/Plex.log | tail

Success (zero-copy) looks like:

vd: Trying hardware decoding via hevc-vaapi.
vd: Using hardware decoding (vaapi).
vf: [out] 1920x1080 vaapi[p010] ...

Using hardware decoding (vaapi-copy) is the copy-mode success line. vd: Using software decoding. means it's still failing — check the failure reason on the lines just above.

Check the GPU — the Intel Video engine should be active during playback:

sudo intel_gpu_top   # watch the "Video" engine row

Troubleshooting

Log lineMeaningFix
iHD_drv_video.so init failed / va_openDriver() returns 18mpv opened the NVIDIA nodeSet vaapi-device to the Intel renderD* (step 5)
Trying to open .../dri/iHD_drv_video.so then softwareDriver not found — wrong pathSet LIBVA_DRIVERS_PATH to the intel-vaapi-driver subdir (step 4)
VAAPI hwdec only works with OpenGL or Vulkan backendsGL context is GLX, not EGLAdd QT_XCB_GL_INTEGRATION=xcb_egl, or use hwdec=vaapi-copy
White/corrupted posters after enabling EGLEGL broke Qt UI renderingRevert to hwdec=vaapi-copy and unset QT_XCB_GL_INTEGRATION

Revert to the safe copy-mode:

flatpak override --user --unset-env=QT_XCB_GL_INTEGRATION tv.plex.PlexDesktop
# and in mpv.conf: hwdec=vaapi  →  hwdec=vaapi-copy

Notes

  • The NVIDIA GPU provides no VAAPI (it uses NVDEC/VDPAU); VAAPI decode always belongs to the Intel iGPU here. DRI_PRIME is for GL render offload, not decode — it does not select the VAAPI device.
  • Plex Desktop uses mpv, not Chromium/Electron — Chromium VAAPI flags (--enable-features=VaapiVideoDecoder) do not apply.
  • Wayland: Qt already uses EGL, so QT_XCB_GL_INTEGRATION is unneeded; ensure the Flatpak has Wayland socket access and try hwdec=vaapi directly.
  • If a specific file shows green frames or wrong colors under zero-copy, that's a per-file interop quirk — switch that session to vaapi-copy.

References

On this page