Skip to content

Resolve default video degradation preference by track source, including the backup codec - #1083

Merged
xianshijing-lk merged 1 commit into
mainfrom
sxian/default-degradation-preference-by-source
Aug 10, 2026
Merged

Resolve default video degradation preference by track source, including the backup codec#1083
xianshijing-lk merged 1 commit into
mainfrom
sxian/default-degradation-preference-by-source

Conversation

@xianshijing-lk

@xianshijing-lk xianshijing-lk commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Aligns Swift with the behavior landed in client-sdk-android (livekit/client-sdk-android#991). Two related changes.

Source-based defaults

VideoPublishOptions.degradationPreference already defaults to .auto, documented as "The SDK will decide which preference is suitable" — but .auto collapsed to .maintainResolution for every video track:

let degradationPreference = publishOptions.degradationPreference.toRTCType() ?? .maintainResolution

.auto now resolves from the track source: camera → .maintainFramerate (smoother video for real-time communication), screen share → .maintainResolution (clarity matters for text/UI), other → .balanced. balanced is the preference the WebRTC spec mandates as the default and is the honest choice when the application declined to declare a motion-vs-detail intent.

No API change — .auto already existed with exactly these semantics. An explicitly set preference still wins; the source default only applies to .auto.

Backup codec sender

Degradation preference is a property of the sender, not of the track — a top-level field on RtpParameters, not per-encoding. publish(additionalVideoCodec:for:) adds a second transceiver and therefore a second sender, which was never configured, so the backup encoder resolved a preference implicitly from the native source and could adapt along a different axis than the primary.

Both senders sink from the same video source, so a diverging backup does not just degrade itself — its restriction is merged onto the shared source and affects the primary too.

Both publish paths now resolve the preference the same way and share LKRTCRtpSender.set(degradationPreference:), extracted from the existing inline parameter write (the "changing params directly doesn't work" dance is preserved).

Note simulcast is unaffected — all simulcast encodings live under one sender and already share its preference. Only the backup codec is a separate sender.

Tests

Tests/LiveKitCoreTests/DegradationPreferenceTests.swift covers the three source mappings for .auto, explicit preferences winning over the source default, and the .auto default on VideoPublishOptions.

swift build clean, the 4 new tests pass, and the LiveKitCoreTests failure count is unchanged from main (132 issues on both, all from integration tests that need a local LiveKit server). swiftformat --lint clean on all touched files.

Cross-SDK

client-sdk-js gets the backup-sender half in livekit/client-sdk-js#2040 (its source-based defaults already matched); client-sdk-flutter gets both in livekit/client-sdk-flutter#1155. The Rust SDK already resolves the same defaults and has no backup-codec publish path.

🤖 Generated with Claude Code

`.auto` resolved to `.maintainResolution` for every video track. It now
resolves from the track source: camera maintains framerate, screen share
maintains resolution, other sources fall back to balanced.

Degradation preference is a sender-level property, and a backup codec
publishes over its own sender, so it needs the preference applied
separately. `publish(additionalVideoCodec:for:)` never set it, leaving the
backup encoder to resolve one implicitly and potentially adapt along a
different axis than the primary. Apply the resolved preference there too.

Extract the sender parameter write into `LKRTCRtpSender.set(degradationPreference:)`
so both publish paths share it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@devin-ai-integration devin-ai-integration Bot left a comment

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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

@xianshijing-lk
xianshijing-lk merged commit 6ebad83 into main Aug 10, 2026
30 checks passed
@xianshijing-lk
xianshijing-lk deleted the sxian/default-degradation-preference-by-source branch August 10, 2026 14:58
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