# Hardware Transcoding (HW) not working with libva/VA-API using d3d12 driver (WSL2)

**URL:** <https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042>\
**Category:** Plex Media Server\
**Tags:** server-docker\
**Created:** [January 22, 2025, 1:32am UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042 "2025-01-22T01:32:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![victorsebrito](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/victorsebrito/32/330410_2.png) [@victorsebrito](https://forums.plex.tv/u/victorsebrito)\
**Post date:** [January 22, 2025, 1:32am UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/1 "2025-01-22T01:32:38Z")

</div>

Server Version#: 1.41.3.9314-a0bfb8370  
Player Version#: 4.141.0

Hey there!

I’m not sure this is supported, but I thought it should work since Plex does support VA-API. 😩

GPU acceleration in WSL has been around [for a while now](https://devblogs.microsoft.com/commandline/d3d12-gpu-video-acceleration-in-the-windows-subsystem-for-linux-now-available/) and using it in a Docker container is [fairly easy](https://github.com/microsoft/wslg/blob/main/samples/container/Containers.md#containerized-applications-access-to-vgpu-accelerated-video). Although I’ve managed to successfully perform HW transcoding using `ffmpeg`, Plex itself fails to load the drivers.

Here is the error output on Ubuntu 22.04:

```log
[Req#149/Transcode] Codecs: testing h264 (decoder) with hwdevice vaapi
[Req#149/Transcode] Codecs: hardware transcoding: testing API vaapi for device '' ()
[Req#149/Transcode] [FFMPEG] - libva: dlopen of /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so failed: Error relocating /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so: fcntl64: symbol not found
[Req#149/Transcode] [FFMPEG] - Failed to initialise VAAPI connection: -1 (unknown libva error).
[Req#149/Transcode] Codecs: hardware transcoding: opening hw device failed - probably not supported by this system, error: I/O error
[Req#149/Transcode] Could not create hardware context for h264

```

With Ubuntu 24.04 I get the same kind of error, but it’s a different symbol… probably because of the different libs versions:

```log
[FFMPEG] - libva: dlopen of /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so failed: Error relocating /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so: __isoc23_strtoul: symbol not found

```

This is the output for `vainfo --display drm` on Ubuntu 24.04:

```auto
libva info: VA-API version 1.20.0
libva info: User environment variable requested driver 'd3d12'
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/d3d12_drv_video.so
libva info: Found init function __vaDriverInit_1_20
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.20 (libva 2.12.0)
vainfo: Driver version: Mesa Gallium driver 24.0.9-0ubuntu0.3 for D3D12 (Intel(R) Iris(R) Xe Graphics)
vainfo: Supported profile and entrypoints
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264Main : VAEntrypointVLD
      VAProfileH264Main : VAEntrypointEncSlice
      VAProfileH264High : VAEntrypointVLD
      VAProfileH264High : VAEntrypointEncSlice
      VAProfileHEVCMain : VAEntrypointVLD
      VAProfileHEVCMain : VAEntrypointEncSlice
      VAProfileHEVCMain10 : VAEntrypointVLD
      VAProfileHEVCMain10 : VAEntrypointEncSlice
      VAProfileVP9Profile0 : VAEntrypointVLD
      VAProfileVP9Profile2 : VAEntrypointVLD
      VAProfileAV1Profile0 : VAEntrypointVLD
      VAProfileNone : VAEntrypointVideoProc

```

I did my homework and I’m guessing this happens because of [this change](https://forums.plex.tv/t/plex-media-server-forum-preview-faster-and-smaller-builds-with-new-toolchain/699575). And others have faced similar problems before… see [this reply](https://forums.plex.tv/t/got-hw-transcoding-to-work-with-libva-vaapi-on-ryzen-apu-ryzen-7-4700u/676546/46) and [this Dockerfile](https://github.com/skjnldsv/docker-plex/blob/1befd2c7fe571b4558fdc63498e4545b7f6844b8/Dockerfile), which downloads the drivers in Alpine to work around the issue.

This is what I’m going to try next, but I don’t think people should go through all this trouble to make it work. I don’t have much expertise with this kind of issue, but I was hoping it could be fixed in Plex.

Here’s a minimal Docker setup if you’d like to reproduce it:

- [wsl2-plex-hw-transcoding.zip](https://forums.plex.tv/uploads/short-url/2nVZ3aWGOyQtaROyczj0OvIIglt.zip) (1.2 KB)

Just add any video inside the `samples` folder and then include it in a library once Plex is running. I used [this video](https://github.com/chthomos/video-media-samples/raw/refs/heads/master/big-buck-bunny-1080p-30sec.mp4) and on the web player I set resolution to 480p to trigger transcoding.

Not sure it matters, but this is my `wsl --version` output:

```auto
WSL version: 2.3.26.0
Kernel version: 5.15.167.4-1
WSLg version: 1.0.65
MSRDC version: 1.2.5620
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.26100.2894

```

I’ve shared how I got here in [this repo](https://github.com/victorsebrito/hyperv-wsl2-gpu-experiments). While it primarily documents my personal home server setup, it includes valuable context that might help others troubleshooting similar issues.

---

<div class="post-metadata">

**Author:** ![victorsebrito](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/victorsebrito/32/330410_2.png) [@victorsebrito](https://forums.plex.tv/u/victorsebrito)\
**Post date:** [January 29, 2025, 6:47pm UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/2 "2025-01-29T18:47:12Z")

</div>

@ChuckPa any chance you could help me with this? 🥲

---

<div class="post-metadata">

**Author:** ![ChuckPa](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/chuckpa/32/79710_2.png) [@ChuckPa](https://forums.plex.tv/u/ChuckPa)\
**Post date:** [January 29, 2025, 7:52pm UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/3 "2025-01-29T19:52:38Z")

</div>

I’m curious as to why you’re trying to use WSL with all those additional translation layers instead of the native package.

Your logs are showing that MUSL doesn’t know where to look for the D3D support libraries it needs to back-link into the windows runtimes.

As for what’s happening with the unresolved symbols;

1. MUSL must be told where to look for runtime libraries (the toolchain)
2. To keep configuration sane, I write the MUSL config each time PMS is started but before PMS actually launches the binary

Here is the code which adds (or skips) the Nvidia GPU libraries for PMS to use on QNAP

```auto

      # Construct ld-musl-x86_64.path
      mkdir -p ${QPKG_DIR}/etc
      {
       echo /lib
       echo /usr/lib
       echo /usr/local/lib
       echo /usr/local/cuda/lib64
      } > ${QPKG_DIR}/etc/ld-musl-x86_64.path

      # If GPU is supported (Has Drivers & Is Available)
      if [$SupportedGPU -gt 0]; then

        # determine and write paths (QTS & QuTS)
        GPU_DRV_DIR="$(getcfg -f $Config NVIDIA_GPU_DRV Install_Path)"
        ["$GPU_DRV_DIR" != ""] && echo $GPU_DRV_DIR/usr/lib >> ${QPKG_DIR}/etc/ld-musl-x86_64.path

        # Older versions
        if [-d "/opt/NVIDIA_GPU_DRV"]; then
          {
            echo /opt/NVIDIA_GPU_DRV/usr/syslib
            echo /opt/NVIDIA_GPU_DRV/usr/lib
            echo /opt/NVIDIA_GPU_DRV/usr/applib
          } >> ${QPKG_DIR}/etc/ld-musl-x86_64.path
        fi
      fi
    fi # if x86_64

    # Make certain ${QPKG_DIR}/Library/tmp exists (those cases when the user is resetting but maintaining existing install on the side)
    if [! -d "${QPKG_DIR}/Library/tmp"]; then

      # Create and set permissions
      mkdir -p "${QPKG_DIR}/Library/tmp"
      chown -R 0:0 "${QPKG_DIR}/Library/tmp"
    fi

```

While you can make this change for yours, I don’t see what benefit, if any, there will be.

May I ask what your end goal is?

---

<div class="post-metadata">

**Author:** ![victorsebrito](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/victorsebrito/32/330410_2.png) [@victorsebrito](https://forums.plex.tv/u/victorsebrito)\
**Post date:** [January 30, 2025, 12:50pm UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/4 "2025-01-30T12:50:30Z")

</div>

In fact, I’m currently running Plex directly on Windows as a workaround, but I prefer to have all my services running in Docker containers. All the compose/Dockerfiles can be easily synced from/to Git and it makes it easier for me to manage versions and configs.

The base OS for my home server used to be Ubuntu and mapping `/dev/dri` was all that I needed, but now I’m trying to making the switch to Windows and have been struggling with this issue.

I thought support libraries were successfully found because first I had to set this in my environment to get `ffmpeg` to work:

```auto
LIBVA_DRIVER_NAME=d3d12
LD_LIBRARY_PATH=/usr/lib/wsl/lib

```

But that alone wasn’t enough for Plex:

```log
[Req#87/Transcode] Codecs: testing h264 (decoder) with hwdevice vaapi
[Req#87/Transcode] Codecs: hardware transcoding: testing API vaapi for device '' ()
[Req#87/Transcode] [FFMPEG] - Failed to initialise VAAPI connection: -1 (unknown libva error).
[Req#87/Transcode] Codecs: hardware transcoding: opening hw device failed - probably not supported by this system, error: I/O error
[Req#87/Transcode] Could not create hardware context for h264

```

For Plex to find the drivers I also had to set `LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri`. I discovered some of its child processes like `Plex Plug-in [com.plexapp.system]` had it set to `/config/Library/Application Support/Plex Media Server/Cache/va-dri-linux-x86_64`, which was just an empty folder.

So it doesn’t seem like an issue to find the support libraries but to actually load them? I truly appreciate the code you shared though! Will take a closer look soon and get back to you!

---

<div class="post-metadata">

**Author:** ![ChuckPa](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/chuckpa/32/79710_2.png) [@ChuckPa](https://forums.plex.tv/u/ChuckPa)\
**Post date:** [January 30, 2025, 5:20pm UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/5 "2025-01-30T17:20:18Z")

</div>

@victorsebrito

What you’re showing me is all based on using `glibc` which, in most cases, is the correct answer.

Plex doesn’t use `glibc`. It uses `MUSL` for multiple reasons:

1. Smaller binaries
2. Faster executables
3. Increased portability
4. Decreased dependency issues.
5. Improved and consistent baseline (NAS glibc implementations are bad)

You’ll find that there are times when a host OS-native app is required.

Think of the structure of:

Host OS → Linux VM → Linux Container → Docker container  
(There are different abstractions here. Look carefully)

Docker is on the bottom of the functionality list and least flexible.  
If you want to look at something more flexible, just as light, easier to use, that Plex does run in — Look at Linux Containers ( example: Incus or LXD )

FWIW: I don’t use VMs or Docker (hate them both). I use LXC because it’s still a container (like Docker) with a full OS capability in it (like a VM) but not only a few hundred MB for the entire OS (no bloat)

PMS runs in these Linux Containers without issue. It takes about 5 minutes to spin up a new container and have PMS running – with GPU 😉

---

<div class="post-metadata">

**Author:** ![victorsebrito](https://sea1.discourse-cdn.com/plex/user_avatar/forums.plex.tv/victorsebrito/32/330410_2.png) [@victorsebrito](https://forums.plex.tv/u/victorsebrito)\
**Post date:** [March 4, 2025, 12:52am UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/6 "2025-03-04T00:52:14Z")

</div>

I appreciate you taking your time to reply! It’s been a while, but I finally got some free time to work on this again.

I have this weird setup because I’m trying to share the GPU between the Windows host and the Docker containers inside WSL. 🥲

Anyways… I managed to build the drivers from source on Alpine and load them successfully into Plex, but stumbled upon what appears to be [an issue with WSL itself](https://github.com/microsoft/WSL/issues/12653). We’ll see how that goes.

I’m confident that Plex will work just fine once I get the drivers to work on Alpine.

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/plex/original/3X/2/a/2acb9765406f63293d357b4ec509ec39aa28f2ad.png) [@system](https://forums.plex.tv/u/system)\
**Post date:** [June 2, 2025, 12:52am UTC](https://forums.plex.tv/t/hardware-transcoding-hw-not-working-with-libva-va-api-using-d3d12-driver-wsl2/903042/7 "2025-06-02T00:52:46Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
