o_sfu_core/engine/room/source_policy/
action.rs1use super::super::media_graph::SubscriptionKey;
2use crate::engine::{
3 ConnectionId, UserId,
4 media_transport::{
5 ConsumerActivity, ConsumerRouteControl, SourcePacketGate, TransportConsumerRoute,
6 },
7 source_model::{
8 ConsumerSourceSelection, PolicyPauseReason, PublishedSourceId,
9 ReceiverVideoBudgetDiagnostics, SourceSelector,
10 },
11};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub(super) enum RouteBudgetOutcome {
15 Degraded,
16 Paused,
17 Resumed,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub(in crate::engine::room) struct ConsumerPacketSelectionUpdate {
22 pub(super) key: SubscriptionKey,
23 pub(super) source_id: PublishedSourceId,
24 pub(in crate::engine::room) route: TransportConsumerRoute,
25 pub(super) selector: SourceSelector,
26 pub(super) policy_pause_reason: Option<PolicyPauseReason>,
27 pub(super) budget: ReceiverVideoBudgetDiagnostics,
28 pub(super) outcome: Option<RouteBudgetOutcome>,
29 pub(super) pressure_observations: u8,
30 pub(super) upgrade_observations: u8,
31 pub(super) packet_gate: Option<SourcePacketGate>,
32 pub(super) route_activity_changed: bool,
33 pub(super) request_keyframe: bool,
34}
35
36impl ConsumerPacketSelectionUpdate {
37 pub(in crate::engine::room) fn route_activity(
38 key: SubscriptionKey,
39 source_id: PublishedSourceId,
40 route: TransportConsumerRoute,
41 current_selection: ConsumerSourceSelection,
42 policy_pause_reason: Option<PolicyPauseReason>,
43 ) -> Option<Self> {
44 (policy_pause_reason != current_selection.policy_pause_reason()).then(|| Self {
45 key,
46 source_id,
47 route,
48 selector: current_selection.selector(),
49 policy_pause_reason,
50 budget: current_selection.budget(),
51 outcome: None,
52 pressure_observations: current_selection.pressure_observations(),
53 upgrade_observations: current_selection.upgrade_observations(),
54 packet_gate: None,
55 route_activity_changed: true,
56 request_keyframe: false,
57 })
58 }
59
60 pub(super) const fn requires_media_transport_effect(&self) -> bool {
61 self.packet_gate.is_some() || self.route_activity_changed || self.request_keyframe
62 }
63
64 pub(super) const fn requires_follow_up(&self) -> bool {
65 self.pressure_observations > 0 || self.upgrade_observations > 0
66 }
67
68 pub(in crate::engine::room) fn route_control(&self) -> ConsumerRouteControl {
69 let mut control =
70 ConsumerRouteControl::new(self.route.clone()).request_keyframe(self.request_keyframe);
71 if self.route_activity_changed {
72 control = control.activity(ConsumerActivity::from_active(self.route_active()));
73 }
74 if let Some(packet_gate) = &self.packet_gate {
75 control = control.packet_gate(packet_gate.clone());
76 }
77 control
78 }
79
80 pub(in crate::engine::room) const fn route_active(&self) -> bool {
81 self.policy_pause_reason.is_none()
82 }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq)]
86pub(super) struct FeaturedUserUpdate {
87 pub(super) user_id: UserId,
88 pub(super) connection_id: ConnectionId,
89 pub(super) featured: Option<bool>,
90}
91
92impl FeaturedUserUpdate {
93 #[must_use]
94 pub(super) fn new(
95 user_id: UserId,
96 connection_id: ConnectionId,
97 featured: Option<bool>,
98 ) -> Self {
99 Self {
100 user_id,
101 connection_id,
102 featured,
103 }
104 }
105}