Skip to content

fix: improve initial video quality by setting x-google-start-bitrate for all video codecs#1050

Open
xianshijing-lk wants to merge 1 commit into
mainfrom
sxian/CLT-3068/fix-initial-video-quality-blurriness-by-setting-x-google-start-bitrate
Open

fix: improve initial video quality by setting x-google-start-bitrate for all video codecs#1050
xianshijing-lk wants to merge 1 commit into
mainfrom
sxian/CLT-3068/fix-initial-video-quality-blurriness-by-setting-x-google-start-bitrate

Conversation

@xianshijing-lk

Copy link
Copy Markdown
Contributor

Summary

  • Add x-google-start-bitrate SDP munging for all video codecs (VP8, VP9, AV1, H264, H265)
  • Use 90% of target bitrate as start bitrate to prevent initial blurriness
  • Default degradationPreference to .maintainResolution for video tracks

Problem

Video starts blurry for 5-15 seconds before improving. This is caused by WebRTC's bandwidth estimator starting at ~300kbps and slowly ramping up to the target bitrate.

Solution

  1. x-google-start-bitrate: Tell WebRTC to start at 90% of target bitrate instead of ramping up from ~300kbps. Applied consistently to all video codecs.
  2. MaintainResolution: When bandwidth is constrained, prefer dropping frames over reducing resolution. This maintains video clarity at the cost of smoothness.

Changes

  • Added TrackBitrateInfo struct and tracking in Transport
  • Added setTrackBitrateInfo() method to register bitrate info when publishing video tracks
  • Added mungeStartBitrate() SDP munging function
  • Updated negotiate sequence to apply start bitrate munging
  • Changed default degradationPreference from .auto to .maintainResolution

Test plan

  • Verify video quality is sharp from the start when publishing
  • Test with VP8, VP9, H264, AV1 codecs
  • Verify bandwidth estimator adapts properly if network can't handle the start bitrate

🤖 Generated with Claude Code

…for all video codecs

- Add x-google-start-bitrate SDP munging for all video codecs (VP8, VP9, AV1, H264, H265)
- Use 90% of target bitrate as start bitrate to prevent initial blurriness
- Default degradationPreference to .maintainResolution for video tracks

This addresses the issue where video starts blurry for several seconds before improving, by telling WebRTC's bandwidth estimator to start at a higher bitrate instead of ramping up from ~300kbps.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@xianshijing-lk xianshijing-lk force-pushed the sxian/CLT-3068/fix-initial-video-quality-blurriness-by-setting-x-google-start-bitrate branch from 9772bef to 00a2993 Compare June 29, 2026 10:08

/// Munge SDP to add x-google-start-bitrate for video codecs.
/// This helps prevent initial video blurriness by starting at a higher bitrate.
func mungeStartBitrate(_ sdp: String, trackBitrates: [String: TrackBitrateInfo]) -> String {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few suggestions:

  • Per-codec, not global max. We compute max(maxBitrateKbps) across all tracks and stamp that single value onto every video payload. The consensus in the thread was "0.9× of that codec's target." It happens to work because one codec is negotiated at a time, but it's not what it says on the tin.
  • H264 loses payloads. codecPayloads[codecName] = payload keeps only the last payload per codec name. H264 commonly advertises several profile payloads; only one gets the hint. (Low impact since H264 doesn't benefit anyway, but it shows the matching is loose.)
  • Can be static like mungeInactiveToRecvOnlyForMedia — it uses no instance state.
  • Needs a test. This is non-trivial string parsing (CRLF detection, fmtp insert-vs-append, payload matching) with no coverage. Please add a unit test that feeds a representative VP9/AV1 offer and asserts the resulting a=fmtp line.

@pblazej

pblazej commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Changing the degradationPreference default to .maintainResolution is the right call — it's the consensus from the investigation thread and the change that actually fixed the reported VP8 case (the x-google-start-bitrate munging is confirmed to be a no-op for VP8/H264 and only helps SVC codecs). Please add a changeset entry for it, since it's a public default-behavior change for camera publishing. Also needs a lint/format pass — CI is red.

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