Skip to main content

PacketLoopState

Struct PacketLoopState 

Source
pub(super) struct PacketLoopState {
    pub(super) users: KeyedSlotStore<TransportSessionKey, RtcSessionState, SessionSlot>,
    pub(super) routes: RouteTable,
    pub(super) session_media: BTreeMap<TransportSessionKey, SessionMediaLookup>,
    pub(super) rid_readiness_scratch: RidReadinessScratch,
    pub(super) incoming_bitrate_counters: BTreeMap<TransportMediaId, Arc<MediaBitrateCounter>>,
    pub(super) remote_addr_demux: RemoteAddrDemux,
    pub(super) mid_registry: KeyedSlotStore<TransportMediaId, RegisteredMediaHandle, MediaSlot>,
    pub(super) dirty_sessions: Vec<SlotHandle<SessionSlot>>,
    pub(super) session_timeouts: BTreeMap<SlotHandle<SessionSlot>, Instant>,
    pub(super) timeout_queue: BinaryHeap<Reverse<(Instant, SlotHandle<SessionSlot>)>>,
    pub(super) next_media_id: u64,
}
Expand description

authoritative mutable state for one RTC packet-loop worker

the packet loop owns this value without a mutex control commands, UDP ingress, str0m polling and relay fanout all pass through one mutable borrow so the media indexes can be updated together

command-facing APIs keep stable transport ids while hot queues use generation-checked handles

Fields§

§users: KeyedSlotStore<TransportSessionKey, RtcSessionState, SessionSlot>

live worker-local RTC sessions

§routes: RouteTable

source-scoped packet routing, relay and recovery state

§session_media: BTreeMap<TransportSessionKey, SessionMediaLookup>

session-scoped media lookup vectors for packet source resolution

§rid_readiness_scratch: RidReadinessScratch

reusable selected-RID readiness scratch vectors

§incoming_bitrate_counters: BTreeMap<TransportMediaId, Arc<MediaBitrateCounter>>

packet-loop write handles for incoming media bitrate accounting

§remote_addr_demux: RemoteAddrDemux

worker-local UDP ingress demux hints

§mid_registry: KeyedSlotStore<TransportMediaId, RegisteredMediaHandle, MediaSlot>

primary media handle table keyed by stable transport media id

§dirty_sessions: Vec<SlotHandle<SessionSlot>>

sessions that must be polled before the worker waits again

§session_timeouts: BTreeMap<SlotHandle<SessionSlot>, Instant>

latest str0m timeout deadline per live session handle

§timeout_queue: BinaryHeap<Reverse<(Instant, SlotHandle<SessionSlot>)>>

timeout heap that may contain stale entries invalidated by session_timeouts

§next_media_id: u64

next worker-local media id from the disjoint range assigned at boot

Implementations§

Source§

impl PacketLoopState

Source

pub(super) fn register_incoming_bitrate_counter( &mut self, transport_media_id: TransportMediaId, counter: Arc<MediaBitrateCounter>, )

Source

pub(super) fn remove_incoming_bitrate_counter( &mut self, transport_media_id: TransportMediaId, )

Source

pub(super) fn record_incoming_bitrate( &self, transport_media_id: TransportMediaId, now: Instant, payload_bytes: usize, ) -> Option<IncomingBitrateObservation>

Source§

impl PacketLoopState

Source

pub(super) fn register_media_handle( &mut self, handle: RegisteredMediaHandle, ) -> TransportMediaId

Source

pub(super) fn resolve_mid( &self, transport_media_id: TransportMediaId, ) -> Option<Mid>

Source

pub(super) fn media_handle( &self, transport_media_id: TransportMediaId, ) -> Option<&RegisteredMediaHandle>

Source

pub(super) fn producer_media_snapshot( &self, session_key: &TransportSessionKey, ) -> Vec<(TransportMediaId, Mid)>

Source

pub(super) fn consumer_media_snapshot( &self, session_key: &TransportSessionKey, ) -> Vec<(TransportMediaId, Mid, TransportMediaId)>

Source

pub(super) fn session_has_other_media_mid( &self, session_key: &TransportSessionKey, mid: Mid, excluded_transport_media_id: TransportMediaId, ) -> bool

Source

pub(super) fn remove_media_handle( &mut self, transport_media_id: TransportMediaId, ) -> Option<RegisteredMediaHandle>

remove one media handle and every dependent reverse index owned by it

producer removal clears source packet policy, incoming bitrate counters, decoder-refresh metadata, live RID state and SSRC lookups consumer removal clears only the consumer MID lookup because route and local rewrite teardown are owned by media lifecycle code

Source

pub(super) fn session_has_registered_media( &self, session_key: &TransportSessionKey, ) -> bool

Source

fn prune_empty_session_media(&mut self, session_key: &TransportSessionKey)

Source

pub(super) fn take_expired_speaker_rooms( &mut self, now: Instant, ) -> BTreeSet<RoomInstanceId>

Source

pub(super) fn src_media_for_mid( &self, src_key: &TransportSessionKey, source_mid: Mid, ) -> Option<TransportMediaId>

Source

pub(super) fn src_media_for_ssrc( &self, src_key: &TransportSessionKey, source_ssrc: Ssrc, ) -> Option<TransportMediaId>

Source

pub(super) fn source_rid_for_ssrc( &self, src_key: &TransportSessionKey, source_ssrc: Ssrc, ) -> Option<Rid>

Source

pub(super) fn learn_producer_ssrc_binding( &mut self, session_key: &TransportSessionKey, transport_media_id: TransportMediaId, ssrc: Ssrc, rid: Option<Rid>, ) -> bool

learn the SSRC chosen by a RID-only publisher from RTP header metadata

chrome can answer simulcast offers with RIDs but no SSRC attributes str0m can still demux the first packets through MID/RID header extensions the adapter must persist that discovery here because later packets may only carry the SSRC without this late binding, packet routing, RID gate metadata and bitrate accounting lose the producer as soon as the browser stops repeating mid/rid extensions

the binding is accepted only for the already resolved producer media id a same-session SSRC collision with a different media id is treated as a suspicious transport fact and ignored rather than stealing ownership

Source

pub(super) fn learn_producer_ssrc_from_pkt( &mut self, source: &ForwardedPacketSource, transport_media_id: TransportMediaId, ssrc: Ssrc, rid: Option<Rid>, ) -> bool

Source

fn learn_producer_ssrc_from_handle( &mut self, session_handle: SlotHandle<SessionSlot>, transport_media_id: TransportMediaId, ssrc: Ssrc, rid: Option<Rid>, ) -> bool

Source

pub(super) fn active_consumer_kf_target( &self, consumer_key: &TransportSessionKey, consumer_mid: Mid, feedback_rid: Option<Rid>, ) -> Option<ConsumerKeyframeTarget>

resolve consumer RTCP feedback to the currently active producer target

this is the packet-loop feedback path missing indexes, removed routes and inactive routes are treated as stale feedback because those can race with teardown after str0m emits a request

selected destination gates override the feedback RID so RID-less browser PLI stays scoped to the routed simulcast layer

Source

pub(super) fn set_consumer_dst_idx( &mut self, consumer_key: &TransportSessionKey, consumer_mid: Mid, consumer_media: TransportMediaId, src_media: TransportMediaId, dst_idx: Option<usize>, )

updates the cached destination slot for one consumer MID binding

callers pass both sides of the route identity so a late repair from an old route cannot relink a MID to a different source

Source

pub(super) fn consumer_dst_idx( &self, consumer_key: &TransportSessionKey, consumer_mid: Mid, consumer_media: TransportMediaId, src_media: TransportMediaId, ) -> Option<usize>

Source

fn source_room_instance_id( &self, src_media: TransportMediaId, ) -> Option<RoomInstanceId>

Source

pub(super) fn remove_session_media_handles( &mut self, session_key: &TransportSessionKey, ) -> Vec<(TransportMediaId, RegisteredMediaHandle)>

Source

pub(super) fn refresh_producer_ssrcs( &mut self, session_key: &TransportSessionKey, mid: Mid, parameters: &MediaStream, )

Source

pub(super) fn apply_producer_nack_policy( &mut self, session_key: &TransportSessionKey, transport_media_id: TransportMediaId, )

Reapplies NACK suppression because SDP answers can recreate StreamRx.

Source

pub(super) fn clear_producer_ssrcs_for_mid( &mut self, session_key: &TransportSessionKey, mid: Mid, )

Source

fn clear_producer_ssrcs( &mut self, session_key: &TransportSessionKey, transport_media_id: TransportMediaId, )

Source§

impl PacketLoopState

Source

pub(super) fn mark_session_dirty(&mut self, session_key: &TransportSessionKey)

schedule a live session for the next packet-loop poll

missing sessions are ignored because teardown may race with already queued wakeups each live session can appear at most once until Self::collect_ready_sessions clears its dirty bit

Source

pub(super) fn has_dirty_sessions(&self) -> bool

report whether the worker has session work that is due immediately

Source

pub(super) fn collect_ready_sessions( &mut self, now: Instant, ready_sessions: &mut Vec<SlotHandle<SessionSlot>>, )

drain dirty sessions and due str0m timeouts into caller-owned scratch

this method is the session scheduler for the packet loop it clears dirty bits for live sessions, skips removed sessions and lazily discards timeout heap entries whose deadline no longer matches Self::session_timeouts

stale handles are skipped before replacement sessions can be polled

the output is sorted and deduplicated so a session that is both dirty and timed out is polled once in the current turn

Source

pub(super) fn update_session_timeout_by_handle( &mut self, session_handle: SlotHandle<SessionSlot>, next_timeout: Option<Instant>, )

replace the next str0m timeout deadline by worker-local handle

stale handles are ignored because the session has already left this worker or the slot now belongs to a later generation

Source

pub(super) fn next_timeout_deadline(&mut self) -> Option<Instant>

return the earliest live str0m timeout deadline

stale heap entries are removed while searching this includes entries for handles whose slot generation no longer names a live session callers may invoke this before awaiting because it does not borrow any session state after returning

Source

pub(super) fn clear_session_schedule( &mut self, session_key: &TransportSessionKey, )

remove all explicit scheduler state for a session being torn down

stale timeout heap entries can remain because the deadline map no longer validates them stale handles are also rejected by generation checks before polling

Trait Implementations§

Source§

impl Default for PacketLoopState

Source§

fn default() -> PacketLoopState

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,