feat: encode H.264 with NVENC on NVIDIA GPUs, on Windows and Linux - #312
Merged
Merged
Conversation
HardwareVideoEncoderFactory now uses NVENC where there is an NVIDIA GPU. NVENC and the CUDA driver are loaded at run time from the driver, so building needs only the NVENC header, vendored from FFmpeg's nv-codec-headers at API 12.0 (MIT, its license goes into the platform jar), and machines without an NVIDIA driver are unaffected. API 12.0 needs drivers 522 (Windows) or 520 (Linux) and newer; older drivers are detected and leave NVENC out. The encoder runs on the primary CUDA context of the first device and encodes synchronously: low-latency preset P4 with ultra-low-latency tuning, Baseline profile with CAVLC, CBR with a one-frame VBV buffer, no B-frames, an infinite GOP with IDR frames on request, SPS/PPS repeated with every IDR frame, and bitrate changes through reconfiguration. Frames are passed as NV12 into an input buffer NVENC allocates. The hardware factory now takes several hardware factories in order of preference and chains their encoders, so that each falls back to the next and finally to software. On Windows NVENC comes before Media Foundation; on Linux NVENC is the only one so far.
This was referenced Sep 30, 2026
devopvoid
added this pull request to stack #311
October 1, 2026 22:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #310 (which is stacked on #303): this PR targets its branch and should be merged after it.
Important
Not yet run on NVIDIA hardware. It was developed on a machine with an AMD GPU and no NVIDIA driver, so the NVENC path itself has only been built and syntax-checked. See Needs testing on NVIDIA below.
HardwareVideoEncoderFactorynow encodes H.264 with NVENC where there is an NVIDIA GPU, on Windows and Linux. The Java API is unchanged.HardwareVideoEncoderFactoryencodes H.264 withLoading
nvEncodeAPI64.dll/libnvidia-encode.so.1) and the CUDA driver (nvcuda.dll/libcuda.so.1) are loaded at run time. Nothing is linked, so machines without an NVIDIA driver are unaffected.nvEncodeAPI.h, vendored unchanged from FFmpeg'snv-codec-headersat tagn12.0.16.1(NVENC API 12.0, MIT license). The license is installed into the platform jar underMETA-INF/licenses/nvenc/.dependencies/nvenc/README.mdrecords the source and version.NvEncodeAPIGetMaxSupportedVersion, and NVENC is then left out.Encoder
NvencH264Encoderruns on the primary CUDA context of the first device and encodes synchronously on the encoder thread:repeatSPSPPS, so SPS/PPS come with every IDR frame.nvEncReconfigureEncoder, without a reset.nvEncCreateInputBuffer), the same approach FFmpeg uses for frames in system memory.Fallback chain
The native
HardwareVideoEncoderFactorynow takes several hardware factories in order of preference and chains their encoders withFallbackVideoEncoder. Each encoder falls back to the next one and finally to software, both when it fails to start and when it fails mid-stream (e.g. when the GPU runs out of encoder sessions, which consumer GPUs limit). On Windows the order is NVENC, then Media Foundation.Testing
MediaFoundation (AMDh264Encoder), checked with-Dwebrtc.test.hardwareEncoder=true.mvn -pl webrtc test: 197 tests pass.-Pjni-check: 197 tests pass, noFATAL ERROR in native method.g++ -std=c++20 -fsyntax-onlyagainst Linux headers in WSL. CI (clang) will be the first full Linux build.HardwareVideoEncoderIntegrationTestnow runs on Linux too, and acceptsNVENC (...)as well asMediaFoundation (...).Needs testing on NVIDIA
On Windows, and ideally on Linux:
This fails unless H.264 is actually encoded on the GPU. The
encoderImplementationstat of a call should readNVENC (<GPU name>). Also worth checking: