Skip to content

feat: encode VP9 in hardware on Windows, when turned on - #348

Merged
devopvoid merged 1 commit into
feat/windows-hevc-codecsfrom
feat/windows-vp9-encoder
Oct 11, 2026
Merged

devopvoid merged 1 commit into
feat/windows-hevc-codecsfrom
feat/windows-vp9-encoder

Conversation

@devopvoid

Copy link
Copy Markdown
Owner

Summary

Stacked on #347 (hardware H.265 on Windows), and based on its branch until that is merged.

Intel GPUs have a Media Foundation VP9 encoder. The hardware encoder factory now uses it for VP9 (profile 0), the way it uses the H.264, H.265 and AV1 encoders — but only when it is turned on:

System.setProperty("webrtc.hardware.vp9Encoder", "true"); // before the factory is created

It is off by default because it has not been tested on an Intel GPU, and once on it takes over VP9 from libvpx for every stream.

  • The property is read natively (HardwareCodecOptions, through Boolean.getBoolean) when the Windows hardware factories are made, so it reaches both the codec list and the encoders of a call, with no new API. The read is safe from any thread: its own local frame, nothing done while another exception is pending.
  • Without the property, or where there is no VP9 encoder, VP9 stays with libvpx. A hardware encoder that fails to start, or a stream that asks for SVC, falls back to libvpx too, through the existing fallback chain. VP9 is offered by the software encoders anyway, so turning it on changes nothing that is negotiated.
  • EncoderOutputProcessor passes VP9 frames on as they come, with the VP9 information of a single layer that the Java encoders get as well (the group of frames with every key frame), parses the QP and uses the VP9 quality scaling thresholds of the Java encoders.
  • The factory Javadoc and the codec guide describe the property.

Testing

On Windows x64 (AMD Radeon RX 9070 XT):

  • vp9HardwareEncodingIsOptIn: without the property, a VP9 call is encoded by libvpx. It runs on every Windows and Linux machine, CI included.
  • hardwareEncodesVp9WhenEnabled: with the property, a VP9 call is encoded in hardware where there is a VP9 encoder; webrtc.test.hardwareVp9Encoder makes it fail rather than skip without one. This machine has an Intel VP9 encoder registered but no Intel GPU: the factory found it, the encoder failed to start (E_FAIL) and libvpx took over, so the call went on and the test skipped.
  • The full webrtc test suite: 277 tests, no failures.

Not verified

VP9 encoding on an actual Intel GPU: neither this machine nor CI has one. That is why it is opt-in.

@devopvoid
devopvoid added this pull request to stack #349 October 11, 2026 13:02
Intel GPUs have a Media Foundation VP9 encoder. The hardware encoder
factory uses it for VP9 (profile 0), the way it uses the others, when the
system property webrtc.hardware.vp9Encoder is true as the factory is
created. It is off by default: the encoder has not been tested on an Intel
GPU, and once on, it would take over VP9 from libvpx. Without the property,
or where there is no VP9 encoder, VP9 is encoded with libvpx, and a
hardware encoder that fails to start, or a stream that asks for SVC, falls
back to libvpx as well. VP9 is offered by the software encoders anyway, so
turning it on changes nothing that is negotiated.

EncoderOutputProcessor passes VP9 frames on as they come, with the VP9
information of a single layer that the Java encoders get too (the group
of frames with every key frame), parses their QP, and uses the VP9 quality
scaling thresholds of the Java encoders.

On a machine with an Intel VP9 encoder registered but no Intel GPU, it
fails to start and libvpx takes over, which the test of the property saw.
@devopvoid
devopvoid force-pushed the feat/windows-vp9-encoder branch from 581ea61 to 74846be Compare October 11, 2026 17:37
@devopvoid
devopvoid merged commit 25df78d into main Oct 11, 2026
24 checks passed
@devopvoid
devopvoid deleted the feat/windows-vp9-encoder branch October 11, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant