Skip to content

Add AV1 codec support for WebRTC - #2334

Open
duckysownyou wants to merge 1 commit into
AlexxIT:masterfrom
duckysownyou:av1-webrtc
Open

Add AV1 codec support for WebRTC#2334
duckysownyou wants to merge 1 commit into
AlexxIT:masterfrom
duckysownyou:av1-webrtc

Conversation

@duckysownyou

Copy link
Copy Markdown

What

Adds AV1 as a negotiable video codec for WebRTC consumers.

  • pkg/webrtc/api.go — register AV1 in the pion MediaEngine (PT 105, same
    RTCP feedback set as the other video codecs), and request larger socket
    buffers on the WebRTC UDP mux listeners (see below).
  • pkg/av1/rtp.go (new) — RTPDepay/RTPPay handlers mirroring the existing
    H264/H265 structure, built on pion/rtp's AV1Depacketizer/AV1Payloader:
    incoming AV1 RTP is reassembled into temporal units, then re-fragmented at
    MTU 1200 (RTSP sources are often TCP-interleaved and can carry RTP packets
    larger than the UDP/TURN-safe MTU).
  • pkg/webrtc/consumer.go — wire the AV1 case into AddTrack.

Why the pacing + socket buffers

A 4K AV1 keyframe temporal unit spans hundreds of RTP packets. Writing them
in one tight loop overflowed UDP socket buffers — ~50% packet loss measured on
a gigabit LAN with the kernel-default (~208KB) send buffer. Two mitigations:

  • light pacing in the AV1 payloader (2ms per 16 packets); each go2rtc sender
    runs on its own goroutine, so this never delays the producer or other
    consumers,
  • SetWriteBuffer(4MB) / SetReadBuffer(1MB) on the UDP mux listeners (this
    also benefits large H265 keyframes).

Tested

  • UniFi Protect G6 PTZ, 4K AV1 via rtspx:// → Chrome 148: AV1 negotiated
    first in the answer, 3840x2160 frames decoded, direct and through a coturn
    TURN relay.
  • H264/H265/audio paths untouched; regression-checked against an H265 camera
    (MSE + WebRTC negotiation unchanged).

Not included

MSE/fMP4 AV1 (av01 muxing) — separate concern, tracked in #2260. Browsers
that can't receive AV1 over WebRTC still get the "codecs not matched" error
as before.

Register AV1 in the pion MediaEngine and add RTP depacketize/repacketize
handlers (pkg/av1) built on pion/rtp's AV1Depacketizer/AV1Payloader,
mirroring the existing H264/H265 handler structure: AV1 RTP from RTSP
sources is reassembled into temporal units and re-fragmented at MTU 1200.

Two burst-loss fixes that large AV1 temporal units surface (a 4K keyframe
spans hundreds of RTP packets; blasting them in one loop overflowed UDP
socket buffers with ~50% observed loss on a gigabit LAN):
- pace AV1 sends lightly (2ms per 16 packets) inside the payload handler;
  each sender runs on its own goroutine so this never delays the producer
- request larger socket buffers on the WebRTC UDP mux listeners

Tested end-to-end with a UniFi Protect G6 PTZ (4K AV1 via rtspx) playing
in Chrome over WebRTC, direct and through a coturn TURN relay.
@skrashevich
skrashevich requested a review from AlexxIT July 5, 2026 21:52
@skrashevich

Copy link
Copy Markdown
Collaborator

@AlexxIT the magic of codecs is beyond my competence. I can add to dev for testing after your positive review

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.

2 participants