Repository navigation
video: encode the H.264 profile the viewer negotiated - #68
Merged
Merged
Conversation
The encoder always produced High profile, level 5.2, but a browser whose offer has no High entry (Chrome without a High-capable decoder, for one) negotiates Constrained Baseline and was sent High anyway. Lenient decoders cope; strict ones such as OpenH264 cannot decode CABAC. Read the negotiated codecs when a viewer connects, mirror the track's binding choice, and switch mpph264enc's profile at runtime before the viewer's keyframe is requested. The choice survives pipeline rebuilds. Log the SPS profile_idc whenever it changes so the switch is visible. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Requested by 4c
Summary
Before: the encoder always sent H.264 High profile, even when the browser negotiated Constrained Baseline. Linux Chrome offers no High entry, so its session negotiated
42e01fand then got a High 5.2 stream. Lenient decoders cope with that, but a strict decoder such as OpenH264 cannot decode CABAC and would show a black screen.After: the encoder sends the profile that was negotiated. Browsers that offer High (Chrome or Safari on macOS, for example) still get High; baseline-only browsers get Constrained Baseline (SPS
42 c0).How
When a viewer's ICE connects,
negotiated_h264_profilereads the sender's negotiated codecs and picks the same codec that webrtc-rs binds the track to (the first exact match for640034, otherwise the first H.264 codec).video::set_h264_profilethen switchesmpph264enc'sprofileproperty at runtime. The switch happens before the new viewer's keyframe is requested, so its first IDR already carries the new SPS. The choice is also applied on every pipeline rebuild, so supervisor restarts keep it. The encoder probe logs the SPSprofile_idcwhenever it changes, which makes the switch visible in the device log.The level is still 5.2 while browsers advertise level 3.1 (
1f). Every browser accepts that for 4K WebRTC, so this change leaves the level alone.Testing
cargo +nightly fmt --allcargo +nightly clippy -p rustkvm --release --all-targets -- -D warningscargo +nightly test --workspace: this host has no GStreamer, so I cross-built the newh264_profiletest and ran it on the device instead (6/6 passed). CI runs the full suite.H.264 encoder profile set to match the viewer, profile: "baseline", thenencoder SPS profile, profile_idc: 66, with the IDR delivered 26 ms after the request.devbuild. Both readings are 60 fps within sampling noise.mpph264enc profile=baseline|main|highproduces SPS bytes42 c0,4d 40and64 10on this device.Checklist
#[allow(...)]suppressions and no newunwrap()/expect()in production pathsMissedTickBehavior::Delayrkvm-protoapp/tests/rpc_methods.txtupdated (unchanged)AGENTS.mdupdated (unchanged)🤖 Generated with Claude Code