oxpulse_sfu_kit/client/tracks.rs
1//! Track-side data types.
2//!
3//! Describes what a peer publishes (`TrackIn*`) or receives from another peer
4//! (`TrackOut*`). Kept separate from `client/mod.rs` so the state machine
5//! can focus on `Rtc`-driven event dispatch.
6
7use std::sync::{Arc, Weak};
8use std::time::Instant;
9
10use str0m::media::{MediaKind, Mid};
11
12use crate::propagate::ClientId;
13
14/// An incoming track advertised by a client.
15///
16/// The originating client owns the strong `Arc`; every other client that
17/// subscribes holds a `Weak`. When the publisher disconnects the `Arc` drops
18/// and all subscriber `Weak`s become invalid.
19#[derive(Debug)]
20pub struct TrackIn {
21 /// The peer that is publishing this track.
22 pub origin: ClientId,
23 /// str0m media identifier.
24 pub mid: Mid,
25 /// Audio or video.
26 pub kind: MediaKind,
27 /// `true` if the publishing client is a relay from another SFU edge.
28 ///
29 /// Set at track-open time from the publisher's `is_relay()` status.
30 /// Used by the subscriber's keyframe-request path to emit
31 /// `Propagated::UpstreamKeyframeRequest` (added in relay-rerouting task)
32 /// instead of a direct PLI/FIR.
33 pub relay_source: bool,
34}
35
36#[derive(Debug)]
37pub(crate) struct TrackInEntry {
38 pub id: Arc<TrackIn>,
39 pub last_keyframe_request: Option<Instant>,
40}
41
42#[allow(dead_code)]
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub(crate) enum TrackOutState {
45 ToOpen,
46 Negotiating(Mid),
47 Open(Mid),
48}
49
50#[derive(Debug)]
51pub(crate) struct TrackOut {
52 pub track_in: Weak<TrackIn>,
53 pub state: TrackOutState,
54}
55
56impl TrackOut {
57 pub(crate) fn mid(&self) -> Option<Mid> {
58 match self.state {
59 TrackOutState::ToOpen => None,
60 TrackOutState::Negotiating(m) | TrackOutState::Open(m) => Some(m),
61 }
62 }
63}