pub struct WebRtcPeer { /* private fields */ }webrtc only.Expand description
The Driver — owns the [Rtc] session and its UdpSocket, and
drives str0m’s sans-I/O poll loop on the dedicated thread
crate::driver::DriverRunner::run gives it. Not a
crate::element::SourceElement/crate::element::Source: it has no src_pads()
dataflow graph of its own — see Driver’s own docs for why a
connection with dynamically-appearing, independently bidirectional
tracks doesn’t fit that shape. Whatever it produces or consumes flows
through the separate WebRtcTrackSink/WebRtcTrackSource pairs it
mints per track instead (see below).
rtc/socket must already be connected: the initial SDP offer/answer
and ICE candidate setup happen via str0m directly, in the caller’s own
code, before WebRtcPeer::new. WebRtcPeer only takes over after
signaling has established the connection; it does not provide a signaling
server itself.
Every track — whether it’s one this side requested via
WebRtcHandle::add_track or one the remote peer added (str0m’s
Event::MediaAdded, which — critically — never fires for a track this
side added itself) — is attached the same way, the moment its Mid
exists: a WebRtcTrackSink (to reply on) and a WebRtcTrackSource
(whatever the remote side sends on it) are minted together and handed
out through WebRtcHandle::next_track, no closure required. A single
Direction::SendRecv track therefore needs exactly one
WebRtcHandle::add_track call (on either side) and one
next_track() on each side — no separate outbound API, and no
special-casing for which side happened to originate it.
(Direction::SendOnly/RecvOnly still work the same way; the unused
half of the pair — a WebRtcTrackSource nothing ever sends on, or a
WebRtcTrackSink str0m has no send capability for — is simply inert,
not an error.) This is the same idea as
crate::elements::TeeHandle::attach’s dynamic attachment, just
without Tee’s Mutex (nothing but this one thread ever touches
tracks_in).
Implementations§
Source§impl WebRtcPeer
impl WebRtcPeer
Sourcepub fn new(
name: impl Into<String>,
rtc: Rtc,
socket: UdpSocket,
on_offer: impl FnMut(SdpOffer) + Send + 'static,
on_keyframe_request: impl FnMut(TrackId) + Send + 'static,
) -> (Self, WebRtcHandle)
pub fn new( name: impl Into<String>, rtc: Rtc, socket: UdpSocket, on_offer: impl FnMut(SdpOffer) + Send + 'static, on_keyframe_request: impl FnMut(TrackId) + Send + 'static, ) -> (Self, WebRtcHandle)
rtc/socket must already be connected — see the type-level docs.
on_offer receives every renegotiation offer this element generates
(via WebRtcHandle::add_track) for the caller to ship over its
own signaling transport; on_keyframe_request reports which
outbound track the remote peer wants a keyframe for (forward this to
whatever’s encoding that track). Newly-attached tracks themselves
come from WebRtcHandle::next_track, not a constructor argument.
Trait Implementations§
Source§impl Driver for WebRtcPeer
impl Driver for WebRtcPeer
Source§fn run(&mut self, stop: &StopReceiver, bus: &Bus) -> Result<()>
fn run(&mut self, stop: &StopReceiver, bus: &Bus) -> Result<()>
Drives str0m’s poll loop. Every iteration: apply any commands from
WebRtcHandle/WebRtcTrackSink, start a renegotiation if a track
is waiting, drain str0m’s own output (writing/dispatching as it
goes), check stop, then block on the UDP socket for at most
POLL_INTERVAL — capped below whatever str0m itself asked for, so
the command channel and stop are never starved for longer than
that even when nothing else is happening. There’s no true
multi-way wait across the command channel, stop, and a raw
socket the way crate::elements::AppSource manages across two
crossbeam_channels (a UdpSocket isn’t select!-able), so this
is bounded polling instead — worst case POLL_INTERVAL of extra
latency for Stop/a fresh add_track, not unboundedly stuck.
stop/the connection dying both clear tracks_in immediately, so
every already-handed-out WebRtcTrackSource sees its data channel
disconnect and ends with a final Eos right away, instead of
waiting for this whole WebRtcPeer to be dropped later by whatever
owns its DriverRunner. Neither WebRtcPeer nor its
WebRtcTrackSources have a Pause/Seek concept — see
Driver’s own docs for why that’s not just an oversight: freezing
this loop would starve ICE keepalives/DTLS retransmits, likely
dropping the connection rather than gracefully suspending it.
Source§impl Element for WebRtcPeer
impl Element for WebRtcPeer
Source§fn name(&self) -> Arc<str> ⓘ
fn name(&self) -> Arc<str> ⓘ
crate::bus::BusEvent stores names as
Arc<str> for exactly this reason: a hot path like
crate::queue::Queue posting BusEvent::Dropped once per
overflowed buffer shouldn’t pay for a fresh heap allocation every
time it wants to report which element it is.Source§fn element_type(&self) -> ElementType
fn element_type(&self) -> ElementType
ElementType.Source§fn pp_log(&self) -> &PpLog
fn pp_log(&self) -> &PpLog
crate::bus::Bus::post — same
id/name as Element::name, just already wrapped as the
crate::pp_log::PpLog its pp_info!/pp_warn!/pp_error! macros need. A
stored private field, not built fresh per call, for the same reason
name() returns a cheap Arc<str> clone instead of a fresh String
— see its own docs.Source§fn pp_log_mut(&mut self) -> &mut PpLog
fn pp_log_mut(&mut self) -> &mut PpLog
Element::pp_log reads — used by
crate::pipeline::ChainBuilder to stamp the owning
crate::pipeline::Pipeline’s id onto every element that
passes through it, via element_pp_log. Not meant to be called
from anywhere else.