Skip to content

rtpav1: do not set Y/Z bits when no OBU bytes were written - #1153

Merged
aler9 merged 2 commits into
bluenviron:mainfrom
winklemad:fix/av1-zero-sized-fragment
Sep 5, 2026
Merged

aler9 merged 2 commits into
bluenviron:mainfrom
winklemad:fix/av1-zero-sized-fragment

Conversation

@winklemad

Copy link
Copy Markdown
Contributor

When the space left in a packet is too small to hold any byte of the next OBU, the encoder writes nothing into that packet but still marks it with Y=1 and marks the following packet with Z=1.

The AV1 RTP payload format (v1.0, section 4.4) says Y "MUST be set to 1 if the last OBU element is an OBU fragment that will continue in the next packet, and MUST be set to 0 otherwise", and Z the same for a continuation at the start of a packet. Nothing was fragmented here, so both must be 0.

Receivers that honor the bits join the two complete OBUs into a single one. I checked this against the decoder in this package, against pion/rtp, and the same handling is in ffmpeg's rtpdec_av1. There is no error anywhere, the OBU is just silently lost.

It is reachable whenever an earlier OBU leaves exactly 0 free bytes in the packet, or 0 to 2 bytes when the next OBU is size-prefixed. With the default payload size those first-OBU sizes are 1447 and 1445-1447. This affects streams that get repacketized rather than forwarded, for instance non-RTSP sources read over RTSP in mediamtx.

The fix only sets the two bits when bytes were actually written; when nothing fits, the OBU is retried in the fresh packet as before. Added encode/decode round-trip tests for both the omit-size and the size-prefixed path (they fail without the change).

When the remaining space in a packet is too small to hold any byte of the
next OBU, the encoder writes nothing but still marks the current packet
with Y=1 and the following one with Z=1. The AV1 RTP payload format (v1.0,
section 4.4) requires both bits to be 0 unless an OBU element is actually
fragmented across the two packets.

Receivers that honor the bits therefore join two complete OBUs into one:
this happens with the decoder in this package, with pion/rtp and with
ffmpeg. It is reachable whenever an earlier OBU leaves exactly 0 free
bytes (or 0-2 when the next OBU is size-prefixed), so it affects streams
that are repacketized, e.g. non-RTSP sources read over RTSP in mediamtx.
@codecov

codecov Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.17%. Comparing base (3e20947) to head (1eb4d37).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1153   +/-   ##
=======================================
  Coverage   87.17%   87.17%           
=======================================
  Files         133      133           
  Lines       10587    10623   +36     
=======================================
+ Hits         9229     9261   +32     
- Misses       1358     1362    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@aler9
aler9 merged commit 3eb05e4 into bluenviron:main Sep 5, 2026
9 checks passed
@aler9

aler9 commented Sep 5, 2026

Copy link
Copy Markdown
Member

i refactored tests and merged, thanks

@winklemad

Copy link
Copy Markdown
Contributor Author

Thanks @aler9!

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