Repository navigation
feat: encode and decode H.265 in hardware on Windows - #347
Merged
Merged
Conversation
The hardware codec factories now use VideoToolbox for the codecs WebRTC's macOS factories lack, where the Mac has the hardware for them: - H.265 (Main profile), encoded and decoded on the media engine. The sessions are required to be hardware ones and checked to be, so H.265 is never encoded or decoded in software; a Mac without a hardware HEVC encoder or decoder does not offer it. The encoder works in real time, without frame reordering, with a key frame only on request, and takes CVPixelBuffers as they are and converts other frames to NV12. Its output goes through EncoderOutputProcessor, which puts the parameter sets in front of each key frame. The decoder makes its session from the VPS, SPS and PPS of key frames. - AV1 (profile 0, 8 bit), decoded on Macs with an AV1 decoder (Apple M3 and newer). The session is made from the sequence header, which is parsed for the AV1 configuration box; high bit depth, monochrome and spatial layers go to dav1d, as does a decoder that keeps failing. The VP9 decoder shares a new VTVideoDecoder base with them, which holds the session, the hardware check and the output. The session limit of the process applies only to codecs with a software decoder to go to. H.265 is offered after the default codecs, which keep their order, with the SDP format and the EncoderOutputProcessor support of #347, taken over as they are there. Tests that a call in H.265 is encoded and decoded in hardware run on macOS now, check that the call is still in H.265 rather than in a codec WebRTC switched to, and cover odd sizes, a resolution change, a bitrate cap and restarts; the software factories are checked to offer no H.265.
The hardware codec factories offer H.265 (Main profile) where the GPU has it: encoded with NVENC or the Media Foundation encoder of the GPU driver, decoded by the Media Foundation decoder of Windows on Direct3D 11, which needs the HEVC Video Extensions. There is no software H.265, so H.265 is offered after the codecs of the default factories, which keep their order, and only where the hardware has it; a call uses it only if it is preferred and the other end decodes it. When the hardware encoder cannot take a stream, WebRTC switches to the next negotiated codec. NVENC's H.265 is in the Linux build as well. The H.265 handling of EncoderOutputProcessor (parameter sets in front of key frames, IRAP pictures as key frames, the QP and the H.264 quality scaling thresholds, frame dependencies from the generic frame info), the SDP format and the H.265 call tests come with the macOS change this is stacked on, and serve these encoders and decoders as they are. AMD's Media Foundation H.265 encoder refuses widths up to 352, which is why the H.265 call tests send 640x360, and it leaves the last chroma row of a picture whose height is no multiple of 16 slightly off, which the padded frame test of H.265 leaves out of its check.
devopvoid
force-pushed
the
feat/windows-hevc-codecs
branch
from
October 11, 2026 13:59
ab23890 to
14a0dc4
Compare
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.
Summary
Stacked on #346 (H.265 in the WebRTC build), and based on its branch until that is merged.
The hardware codec factories now offer H.265 (Main profile) where the GPU has it:
MFVideoFormat_HEVCwitheAVEncH265VProfile_Main_420_8.D3D11_DECODER_PROFILE_HEVC_VLD_MAINand Windows has an HEVC decoder (the HEVC Video Extensions, or one of the GPU vendor).EncoderOutputProcessorhandles H.265 as it does H.264: it keeps the parameter sets and puts them back in front of key frames that lack them, treats IRAP pictures as key frames, parses the QP (with the H.264 quality scaling thresholds, as WebRTC does), and fills the frame dependencies from the generic frame info, as for AV1.H265Formatholds the one SDP format all of them offer: Main profile, main tier, level 3.1,tx-mode=SRST.Testing
On Windows x64 with an AMD Radeon RX 9070 XT (
AMDh265Encoder,HEVCVideoExtension), withwebrtc.test.hardwareH265Encoderandwebrtc.test.hardwareH265Decoderset so that the H.265 tests fail rather than skip:hardwareEncodesH265,hardwareDecodesH265andhardwareCropsPaddedH265(640x360, which HEVC decodes into a larger surface), plushardwareKeepsCodecsin both test classes, which now checks that the default codecs come first in their order and that hardware adds nothing but H.265.webrtctest suite: 275 tests, no failures (the two skipped are the macOS-only ones).hardwareCropsPaddedH265passed in five runs.Two things about AMD's H.265 encoder showed up and are handled in the tests rather than the code:
MF_E_INVALIDMEDIATYPE); widths of 480 and up work. WebRTC then switches to the next codec, so the H.265 call tests send 640x360 instead of 320x240.hardwareCropsPaddedH265leaves that row out; a crop at the wrong offset would show across the plane. The AMD H.264 encoder does not do this.Not verified
NVENC's H.265 has not run: there is no NVIDIA GPU here, and CI has no GPU, where the hardware tests skip. Nor has an Intel GPU. H.265 decoding on Linux (NVDEC, Vulkan/VA-API) and macOS comes in later changes, so a Linux NVENC H.265 stream needs a Windows receiver for now.