Commit 30a88de
Default video degradation preference by track source, including the backup codec (#1155)
Aligns Flutter with the behavior landed in client-sdk-android
(livekit/client-sdk-android#991). Two related changes.
## Source-based defaults
Previously every video track fell back to `maintainResolution`, and the
preference was only applied to camera and screen share tracks at all:
```dart
if ([TrackSource.camera, TrackSource.screenShareVideo].contains(track.source)) {
final degradationPreference = options.degradationPreference ?? DegradationPreference.maintainResolution;
await track.setDegradationPreference(degradationPreference);
}
```
Now `getDefaultDegradationPreference(source)` resolves camera →
`maintainFramerate` (smoother video for real-time communication), screen
share → `maintainResolution` (clarity matters for text/UI), other →
`balanced`, and it is applied to every video sender. Custom sources
previously got whatever WebRTC derived implicitly from the native
source; `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.
An explicitly set `degradationPreference` still wins in all cases — the
default only fills a null.
## Backup codec sender
Degradation preference is a property of the **sender**, not of the track
— a top-level field on `RtpParameters`, not per-encoding.
`publishAdditionalCodecForPublication` adds a second transceiver and
therefore a second sender, which was never configured, so the backup
encoder resolved a preference implicitly 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.
`setDegradationPreference` now stores the resolved preference and fans
out to every sender, and `publishAdditionalCodecForPublication` applies
it to the backup sender once created. Using the track's stored resolved
value means the two encoders cannot disagree.
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
`test/options/degradation_preference_test.dart` covers the three source
mappings. Full suite passes (379 tests), `flutter analyze lib/ test/`
clean, `dart format` clean at the repo's 120-column width.
## Cross-SDK
client-sdk-js gets the backup-sender half in livekit/client-sdk-js#2040
(its source-based defaults already matched). The Rust SDK already
resolves the same defaults and has no backup-codec publish path. Swift
follows separately.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com>1 parent 3f67c74 commit 30a88de
5 files changed
Lines changed: 110 additions & 11 deletions
File tree
- .changes
- lib/src
- participant
- track/local
- test/options
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
351 | 374 | | |
352 | 375 | | |
353 | 376 | | |
| |||
415 | 438 | | |
416 | 439 | | |
417 | 440 | | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
418 | 448 | | |
419 | 449 | | |
420 | 450 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
390 | 390 | | |
391 | 391 | | |
392 | 392 | | |
393 | | - | |
394 | | - | |
395 | | - | |
396 | | - | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
397 | 396 | | |
398 | 397 | | |
399 | 398 | | |
| |||
489 | 488 | | |
490 | 489 | | |
491 | 490 | | |
492 | | - | |
493 | | - | |
494 | | - | |
495 | | - | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
496 | 494 | | |
497 | 495 | | |
498 | 496 | | |
| |||
944 | 942 | | |
945 | 943 | | |
946 | 944 | | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
947 | 949 | | |
948 | 950 | | |
949 | 951 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| 71 | + | |
| 72 | + | |
71 | 73 | | |
72 | 74 | | |
73 | 75 | | |
| |||
503 | 505 | | |
504 | 506 | | |
505 | 507 | | |
506 | | - | |
507 | | - | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
508 | 525 | | |
509 | 526 | | |
| 527 | + | |
510 | 528 | | |
511 | | - | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
512 | 534 | | |
513 | 535 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
0 commit comments