feat: adaptive quality in desktop, relay quality directive, Oboe state polling

- Wire AdaptiveQualityController into desktop engine send/recv tasks
  (mirrors Android pattern: AtomicU8 pending_profile, auto-mode check)
- Wire same into Android engine send task (was only in recv before)
- QualityDirective SignalMessage variant for relay-initiated codec switch
- ParticipantQuality tracking in relay RoomManager (per-participant
  AdaptiveQualityController, weakest-link tier computation)
- Relay broadcasts QualityDirective to all participants when room-wide
  tier degrades (coordinated codec switching)
- Oboe stream state polling: poll getState() for up to 2s after
  requestStart() to ensure both streams reach Started before proceeding
  (fixes intermittent silent calls on cold start, Nothing Phone A059)

Tasks: #7, #25, #26, #31, #35

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-12 19:54:04 +04:00
parent 766c9df442
commit 22045bc5e6
5 changed files with 266 additions and 10 deletions

View File

@@ -917,6 +917,14 @@ pub enum SignalMessage {
/// federation link via `send_signal_to_peer`.
origin_relay_fp: String,
},
/// Relay-initiated quality directive: all participants should switch
/// to the recommended profile to match the weakest link.
QualityDirective {
recommended_profile: crate::QualityProfile,
#[serde(default, skip_serializing_if = "Option::is_none")]
reason: Option<String>,
},
}
/// How the callee responds to a direct call.