T5.1: PriorityMode enum + SetPriorityMode signal; extend QualityProfile with video fields

This commit is contained in:
Siavash Sameni
2026-05-12 12:21:11 +04:00
parent 001d94f9ae
commit 276ecc660e
13 changed files with 227 additions and 13 deletions

View File

@@ -130,6 +130,18 @@ pub struct QualityProfile {
pub frame_duration_ms: u8,
/// Number of source frames per FEC block.
pub frames_per_block: u8,
/// Bandwidth-allocation priority between audio and video.
#[serde(default)]
pub priority_mode: crate::PriorityMode,
/// Target video bitrate in kbps (set by quality controller, not handshake).
#[serde(default)]
pub video_bitrate_kbps: Option<u32>,
/// Target video resolution as (width, height).
#[serde(default)]
pub video_resolution: Option<(u16, u16)>,
/// Target video frame rate.
#[serde(default)]
pub video_fps: Option<u8>,
}
impl QualityProfile {
@@ -139,6 +151,10 @@ impl QualityProfile {
fec_ratio: 0.2,
frame_duration_ms: 20,
frames_per_block: 5,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Degraded conditions: Opus 6kbps, moderate FEC.
@@ -147,6 +163,10 @@ impl QualityProfile {
fec_ratio: 0.5,
frame_duration_ms: 40,
frames_per_block: 10,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Catastrophic conditions: Codec2 1.2kbps, heavy FEC.
@@ -155,6 +175,10 @@ impl QualityProfile {
fec_ratio: 1.0,
frame_duration_ms: 40,
frames_per_block: 8,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Studio low: Opus 32kbps, minimal FEC.
@@ -163,6 +187,10 @@ impl QualityProfile {
fec_ratio: 0.1,
frame_duration_ms: 20,
frames_per_block: 5,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Studio: Opus 48kbps, minimal FEC.
@@ -171,6 +199,10 @@ impl QualityProfile {
fec_ratio: 0.1,
frame_duration_ms: 20,
frames_per_block: 5,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Studio high: Opus 64kbps, minimal FEC.
@@ -179,6 +211,10 @@ impl QualityProfile {
fec_ratio: 0.1,
frame_duration_ms: 20,
frames_per_block: 5,
priority_mode: crate::PriorityMode::AudioFirst,
video_bitrate_kbps: None,
video_resolution: None,
video_fps: None,
};
/// Estimated total bandwidth in kbps including FEC overhead.

View File

@@ -19,6 +19,7 @@ pub mod error;
pub mod jitter;
pub mod media_type;
pub mod packet;
pub mod priority_mode;
pub mod quality;
pub mod session;
pub mod traits;
@@ -34,6 +35,7 @@ pub use packet::{
MediaPacket, MiniFrameContext, MiniFrameContextV2, MiniHeader, MiniHeaderV2, PresenceUser,
QualityReport, RoomParticipant, SignalMessage, TrunkEntry, TrunkFrame, default_signal_version,
};
pub use priority_mode::PriorityMode;
pub use quality::{AdaptiveQualityController, NetworkContext, Tier};
pub use session::{Session, SessionEvent, SessionState};
pub use traits::*;

View File

@@ -1197,6 +1197,15 @@ pub enum SignalMessage {
seqs: Vec<u32>,
},
/// Mid-call priority-mode override (PRD-video-quality-priority T5.1).
SetPriorityMode {
/// Signal format version (default 1).
#[serde(default = "default_signal_version")]
version: u8,
/// New priority mode to apply.
mode: crate::PriorityMode,
},
/// Picture Loss Indication — decoder can't proceed, needs a fresh keyframe.
/// Used instead of Nack when RTT is too high for retransmission to help.
PictureLossIndication {

View File

@@ -0,0 +1,24 @@
//! Priority mode for bandwidth allocation between audio and video.
//!
//! See `docs/PRD/PRD-video-quality-priority.md` for the full design.
use serde::{Deserialize, Serialize};
/// Bandwidth-allocation policy between audio and video.
///
/// Carried on [`QualityProfile`](crate::QualityProfile) and mutable at
/// runtime via [`SignalMessage::SetPriorityMode`](crate::SignalMessage).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
pub enum PriorityMode {
/// Audio gets its floor first; video gets the remainder.
/// Default for voice/video calls.
#[default]
AudioFirst,
/// Video gets its floor first; audio degrades to Opus 16k floor.
VideoFirst,
/// Audio clamped to 16 kbps (intelligible speech); video gets remainder.
/// Falls back to slide mode when bandwidth drops below SD floor.
ScreenShare,
/// Proportional split (~15 % audio, ~85 % video).
Balanced,
}