October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Redmond desk7 min

How to use libvmaf_cuda on Windows: an easy-to-follow guide (WSL2 + Docker + NVIDIA)

Run VMAF scoring with FFmpeg's libvmaf_cuda filter on Windows through a Linux container, Docker Desktop's WSL 2 backend and NVIDIA GPU passthrough, with the checks that keep the scores valid.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

On Windows, the documented route to libvmaf_cuda runs FFmpeg inside a Linux container, using Docker Desktop’s WSL 2 backend and an NVIDIA GPU passed through with --gpus all. The filter only accepts CUDA frames, so both the reference and distorted videos have to reach the GPU as CUDA frames and stay there through the filter graph. This guide covers the setup, the filter command, and the points where VMAF results can go wrong.

What libvmaf_cuda needs in place

The CUDA variant of the libvmaf filter is a GPU-side scorer. FFmpeg’s filter documentation states that libvmaf_cuda “only accepts CUDA frames,” and it requires Netflix’s libvmaf library to be built into FFmpeg. Before you run anything, these pieces must all be present:

As an Amazon Associate I earn from qualifying purchases.

  • A supported NVIDIA GPU with a current Windows driver that includes WSL 2 GPU support.
  • WSL 2 with an up-to-date Linux kernel and a Linux distribution installed under it.
  • Docker Desktop with the WSL 2 backend enabled, so that --gpus passthrough to Linux containers works.
  • An FFmpeg build that includes both the VMAF library and the CUDA filter. NVIDIA states that VMAF-CUDA “must be built from the source” (NVIDIA technical blog, 2024).
  • Both input videos decoded or uploaded as CUDA frames, with matching dimensions, frame rate, and pixel format.

Version requirements change over time. Microsoft documents CUDA support for Windows 11 and for Windows 10 version 21H2, but exact minimum driver and WSL versions are maintained on live vendor pages. Check Docker’s GPU support page for Docker Desktop, NVIDIA’s WSL user guide, and Microsoft’s WSL documentation on the day you set up. A supported NVIDIA GPU is a hard prerequisite for this route; the steps do not depend on any particular card model.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step 1: Confirm the GPU is visible in WSL and in Docker

Debug the GPU path before you touch FFmpeg. Many failures that look like filter errors are really container or driver problems.

#1 Best Overall
Sale
ASUS Dual GeForce RTX 5060 Ti 16GB GDDR7 OC Edition Gaming Graphics Card | PCIe 5.0, HDMI 2.1b, DisplayPort 2.1b, 2.5-slot, Axial-tech Fans, 0dB Technology, Dual BIOS
  • AI Performance: 767 AI TOPS
  • OC mode: 2632 MHz (OC mode)/ 2602 MHz (Default mode)
  • Powered by the NVIDIA Blackwell architecture and DLSS 4
  • Axial-tech fan design features a smaller fan hub that facilitates longer blades and a barrier ring that increases downward air pressure
  • A 2.5-slot design maximizes compatibility and cooling efficiency for superior performance in small chassis
  1. In PowerShell, run wsl --update to bring the WSL 2 kernel up to date.
  2. Open your Linux distribution and run nvidia-smi. A table listing your GPU confirms the driver is reachable from WSL. NVIDIA’s WSL guide notes that nvidia-smi has a limited feature set under WSL 2, so some queries may report unsupported values even when CUDA works.
  3. Run a simple container with GPU access using docker run --rm --gpus all followed by a command that calls nvidia-smi. Use the test command from Docker’s GPU support page, because image names change. If the container cannot see the GPU, fix the Docker Desktop backend or the driver before going further.

Step 2: Build an FFmpeg image with libvmaf and CUDA

Netflix’s VMAF Docker guide describes an NVIDIA Container Toolkit setup and a separate Dockerfile.ffmpeg that builds FFmpeg with CUDA support and the VMAF filter. Start from that upstream Dockerfile rather than writing your own. FFmpeg’s filter documentation lists the configure flags --enable-nonfree --enable-ffnvcodec --enable-libvmaf, to be used after libvmaf is installed. Those flags are necessary but do not make a complete recipe: the CUDA and FFmpeg toolchain versions must match, and the upstream Dockerfile manages that.

After the build, confirm the filters exist inside the image:

Rank #2
GIGABYTE GeForce RTX 5070 Ti Gaming OC 16G Graphics Card, 16GB 256-bit GDDR7, PCIe 5.0, WINDFORCE Cooling System, GV-N507TGAMING OC-16GD Video Card
  • Powered by the NVIDIA Blackwell architecture and DLSS 4
  • Powered by GeForce RTX 5070 Ti
  • Integrated with 16GB GDDR7 256bit memory interface
  • PCIe 5.0
  • WINDFORCE cooling system
ffmpeg -hide_banner -filters | grep -E "libvmaf|scale_cuda"

You should see libvmaf_cuda and scale_cuda in the output. If libvmaf_cuda is missing, the image was built without the CUDA filter or without libvmaf, and the filter graph below will fail with a “filter not found” style error.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Step 3: Run the container with the GPU and your media mounted

Keep the videos in a Windows folder and mount that folder into the container. From an Ubuntu shell in WSL, Windows drives appear under /mnt/c. Netflix’s examples use --gpus all together with NVIDIA_DRIVER_CAPABILITIES=compute,video, which covers the compute and video decode features the pipeline uses. Replace your-ffmpeg-vmaf-image with the tag you built in Step 2.

Rank #3
ASUS TUF Gaming GeForce RTX™ 5080 16GB GDDR7 OC Edition Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.6-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
  • Powered by the NVIDIA Blackwell architecture and DLSS 4. System Requirements: Minimum 850W PSU with 16-pin 12V-2x6 (12VHPWR) connector required. Verify before purchasing.
  • Military-grade components deliver rock-solid power and longer lifespan for ultimate durability. Compatibility: 348mm (13.7") length, 3.6 slots, 4.3 lbs. Confirm case clearance and slot spacing. GPU bracket included.
  • Protective PCB coating helps protect against short circuits caused by moisture, dust, or debris
  • 3.6-slot design with massive fin array optimized for airflow from three Axial-tech fans
  • Phase-change GPU thermal pad helps ensure optimal thermal performance and longevity, outlasting traditional thermal paste for graphics cards under heavy loads
docker run --rm --gpus all 
  -e NVIDIA_DRIVER_CAPABILITIES=compute,video 
  -v /mnt/c/videos:/data -w /data 
  your-ffmpeg-vmaf-image 
  ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i distorted.mp4 
  -hwaccel cuda -hwaccel_output_format cuda -i reference.mp4 
  -filter_complex '[0:v]scale_cuda=format=yuv420p[dist];[1:v]scale_cuda=format=yuv420p[ref];[dist][ref]libvmaf_cuda=log_fmt=json:log_path=output.json' 
  -f null -

This command adapts FFmpeg’s documented CUDA example and Netflix’s Docker example. It has not been tested on a specific Windows, WSL, driver, or GPU combination, so treat it as a starting point and verify the output on your own machine. Input order matters: in FFmpeg’s libvmaf filters, the distorted video is the first input and the reference is the second.

Understanding the filter graph

Each part of the command has a specific job:

  • -hwaccel cuda -hwaccel_output_format cuda asks the decoder to output frames in CUDA memory rather than system memory. It must appear before each -i it applies to.
  • scale_cuda=format=yuv420p converts each stream to a common pixel format on the GPU. Whether it is needed depends on what the decoder produces, covered in the next section.
  • libvmaf_cuda=log_fmt=json:log_path=output.json runs the score and writes the results to a JSON file in the mounted folder.
  • -f null – discards the video output, because only the score log matters here.

Pixel format and input alignment

Netflix’s example says that 4:2:0 video decoded to NV12 needs a conversion to 4:2:0 with scale_cuda, while formats such as yuv444p or yuv422p may pass from the decoder without that conversion. Treat this as format-dependent guidance, not a universal rule. Before scoring a pair, check what each file actually contains:

Rank #4
GIGABYTE GeForce RTX 5060 WINDFORCE OC 8G Graphics Card, Cooling System, 8GB 128-bit GDDR7, PCIe 5.0, Manufactured by NVIDIA, DisplayPort & HDMI - Video Output Interface, GV-N5060WF2OC-8GD Video Card
  • Powered by the NVIDIA Blackwell architecture and DLSS 4
  • Powered by GeForce RTX 5060
  • Integrated with 8GB GDDR7 128bit memory interface
  • PCIe 5.0
  • WINDFORCE cooling system
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,pix_fmt,r_frame_rate -of csv=p=0 distorted.mp4
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,pix_fmt,r_frame_rate -of csv=p=0 reference.mp4

The two lines should match in width, height, and frame rate. If the pixel formats differ, or the reference and distorted clips have different lengths or frame timing, align them before scoring. The sources cited for this route show CUDA decoding and scaling, but they do not provide a preprocessing recipe for every media pair, so trimming, resizing, or frame-rate conversion decisions remain yours to make and document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reading the JSON log

The output.json file is written inside the mounted folder, so it appears on Windows as soon as the run finishes. Open it in any text editor. The pooled metrics section contains the aggregate VMAF score for the clip, and the per-frame section lets you find where quality dips. Keep the JSON with the command and the image tag you used; a score without its model, input format, and build details is hard to reproduce later.

Best Value
ASUS TUF Gaming GeForce RTX 5070 12GB GDDR7 OC EditionGaming Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.125-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
  • Powered by the NVIDIA Blackwell architecture and DLSS 4 OC mode: 2640MHz/Default mode: 2610MHz (Boost Clock)
  • Military-grade components deliver rock-solid power and longer lifespan for ultimate durability
  • Protective PCB coating helps protect against short circuits caused by moisture, dust, or debris
  • 3.125-slot design with massive fin array optimized for airflow from three Axial-tech fans
  • Phase-change GPU thermal pad helps ensure optimal thermal performance and longevity, outlasting traditional thermal paste for graphics cards under heavy loads
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Are CPU and CUDA VMAF scores the same?

This is not established by the sources behind this guide. A community discussion on Reddit asks exactly this question, but it is a reader question, not a verified answer. Do not assume that a CUDA score will match a CPU score for every version, model, pixel format, or input pair. If the number matters, run the CPU filter and the CUDA filter on the same two files with the same VMAF model, then compare the results yourself before you rely on the CUDA numbers in a report.

Performance: what NVIDIA reports

NVIDIA’s technical blog (2024) reports that VMAF-CUDA delivers “up to 37x lower per-frame latency at 4K” and “up to 4.4x higher throughput in FFmpeg,” compared with a dual Intel Xeon 8480 CPU system. These are vendor-reported benchmark results, not an independent replication. They describe one hardware comparison and one workload type. Your speed depends on the GPU, the resolution, the codec, the decoder path, and whether the files stay on the GPU; treat the figures as an upper bound on what the vendor measured, not a guarantee.

Decode paths compared

Path How frames reach the filter Evidence in the sources for this guide
GPU decode with CUDA output -hwaccel cuda -hwaccel_output_format cuda keeps frames on the GPU Shown in FFmpeg’s documented CUDA example and Netflix’s Docker example
CPU decode, then upload Frames decoded in system memory and moved to CUDA memory before scoring Not stated for this route in the cited sources
Decoder output used directly No scale_cuda step when the decoder format already matches the filter’s needs Netflix’s example for yuv444p and yuv422p; format-dependent
scale_cuda conversion Converts NV12 or other formats to a common format on the GPU Netflix’s example for 4:2:0 video decoded to NV12

The sources establish the GPU decode path and the scaling example. They do not establish that one route is always faster or easier for every user, so measure with your own files if speed is a deciding factor.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common problems and fixes

  • nvidia-smi fails inside WSL: Update the NVIDIA Windows driver with WSL support, run wsl --update, then restart WSL.
  • The container cannot see the GPU: Confirm Docker Desktop uses the WSL 2 backend and that the run command includes --gpus all.
  • The filter is not found: The image lacks the CUDA filter or libvmaf. Rebuild from the upstream Dockerfile and rerun the -filters check from Step 2.
  • Format or conversion errors: Add or adjust the scale_cuda=format= step after checking the pixel format with ffprobe.
  • Scores look wrong or the run ends early: Compare frame counts, dimensions, and frame rates of both inputs. A mismatch in timing or length means the pair is not aligned.

Keep each run’s command, image tag, and JSON log together so you can repeat the result or explain a difference later.

A supported NVIDIA GPU is required for this Docker Desktop GPU-passthrough route.

Quick Recap

SaleBestseller No. 1
ASUS Dual GeForce RTX 5060 Ti 16GB GDDR7 OC Edition Gaming Graphics Card | PCIe 5.0, HDMI 2.1b, DisplayPort 2.1b, 2.5-slot, Axial-tech Fans, 0dB Technology, Dual BIOS
ASUS Dual GeForce RTX 5060 Ti 16GB GDDR7 OC Edition Gaming Graphics Card | PCIe 5.0, HDMI 2.1b, DisplayPort 2.1b, 2.5-slot, Axial-tech Fans, 0dB Technology, Dual BIOS
AI Performance: 767 AI TOPS; OC mode: 2632 MHz (OC mode)/ 2602 MHz (Default mode); Powered by the NVIDIA Blackwell architecture and DLSS 4
$770.55
Bestseller No. 2
GIGABYTE GeForce RTX 5070 Ti Gaming OC 16G Graphics Card, 16GB 256-bit GDDR7, PCIe 5.0, WINDFORCE Cooling System, GV-N507TGAMING OC-16GD Video Card
GIGABYTE GeForce RTX 5070 Ti Gaming OC 16G Graphics Card, 16GB 256-bit GDDR7, PCIe 5.0, WINDFORCE Cooling System, GV-N507TGAMING OC-16GD Video Card
Powered by the NVIDIA Blackwell architecture and DLSS 4; Powered by GeForce RTX 5070 Ti; Integrated with 16GB GDDR7 256bit memory interface
$1,249.99
Bestseller No. 3
ASUS TUF Gaming GeForce RTX™ 5080 16GB GDDR7 OC Edition Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.6-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
ASUS TUF Gaming GeForce RTX™ 5080 16GB GDDR7 OC Edition Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.6-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
3.6-slot design with massive fin array optimized for airflow from three Axial-tech fans; Auto-Extreme precision automated manufacturing helps ensure higher reliability
$1,899.99
Bestseller No. 4
GIGABYTE GeForce RTX 5060 WINDFORCE OC 8G Graphics Card, Cooling System, 8GB 128-bit GDDR7, PCIe 5.0, Manufactured by NVIDIA, DisplayPort & HDMI - Video Output Interface, GV-N5060WF2OC-8GD Video Card
GIGABYTE GeForce RTX 5060 WINDFORCE OC 8G Graphics Card, Cooling System, 8GB 128-bit GDDR7, PCIe 5.0, Manufactured by NVIDIA, DisplayPort & HDMI - Video Output Interface, GV-N5060WF2OC-8GD Video Card
Powered by the NVIDIA Blackwell architecture and DLSS 4; Powered by GeForce RTX 5060; Integrated with 8GB GDDR7 128bit memory interface
$494.95
Bestseller No. 5
ASUS TUF Gaming GeForce RTX 5070 12GB GDDR7 OC EditionGaming Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.125-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
ASUS TUF Gaming GeForce RTX 5070 12GB GDDR7 OC EditionGaming Graphics Card | PCIe 5.0, HDMI/DP 2.1, 3.125-slot, Military-grade Components, Protective PCB Coating, Axial-tech Fans
3.125-slot design with massive fin array optimized for airflow from three Axial-tech fans; Auto-Extreme precision automated manufacturing helps ensure higher reliability
$937.39

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.