pub struct WebRtcTrackSink { /* private fields */ }webrtc only.Expand description
One outbound track. A plain Sink — no bespoke push API, it links
into a crate::pipeline::ChainBuilder exactly like
crate::elements::RtspSink or any other terminal sink.
consume() only ever hands off to WebRtcPeer::run’s own thread via a
channel send; the actual str0m write happens over there.
Its negotiated codec capabilities are available immediately through
WebRtcTrackSink::negotiated_codecs. The outbound selection is initialized
automatically for a track created by WebRtcHandle::add_track. A
send-capable track added by the remote peer instead requires one validated
WebRtcTrackSink::set_codec call before packets are consumed; omitting it
returns a typed error rather than guessing an RTP payload type.
Implementations§
Source§impl WebRtcTrackSink
impl WebRtcTrackSink
Sourcepub fn negotiated_codecs(&self) -> Vec<Codec>
pub fn negotiated_codecs(&self) -> Vec<Codec>
Returns the distinct codec families this track can currently send after SDP negotiation. The order is informational; select the codec produced by the application’s encoder.
A locally-created endpoint is handed out while its offer is still
pending, so its initial value is the offered list and is narrowed when
WebRtcHandle::set_answer applies the answer. A remotely-created
endpoint is already negotiated when it is handed out.
Sourcepub fn set_source_parameters(&mut self, parameters: &Parameters) -> Result<()>
pub fn set_source_parameters(&mut self, parameters: &Parameters) -> Result<()>
Declares what feeds this sink, from the parameters of whatever does —
an encoder, a demuxer’s stream, or another track’s
WebRtcStreamInfo::codec_parameters.
Everything this sink needs is in that one value, so nothing is asked for twice: the RTP payload type comes from the codec the parameters name, the headers to put in front of keyframes from their extradata, and whether payloads arrive length-prefixed from the shape of that extradata.
§Why the headers have to travel
An encoder opened with AV_CODEC_FLAG_GLOBAL_HEADER — which every
encoder in this crate is, so that a container has a CodecPrivate to
write — moves its SPS/PPS out of the bitstream and into
parameters(). A file is then complete, because the container carries
them; an RTP stream is not, because nothing in it does. The receiving
half of this driver builds its decoder parameters by watching for
SPS/PPS to go past (see stream_info), so without them a peer never
learns what it is being sent and simply times out waiting. They go in
front of every keyframe rather than once, which is what lets a peer
that joins late — or that lost the first of them — start decoding at
the next one.
§A demuxer’s parameters
A container demuxer describes H.264 with an avcC record, and its
packets are length-prefixed to match rather than Annex-B. Passing
those parameters is therefore two statements at once: the parameter
sets are these, and the payloads to come are length-prefixed. Both are
read out of the one record, and every payload is rewritten as Annex-B
on its way to RTP.
§Errors
WebRtcError::OutboundCodecNotNegotiated when this connection did
not retain the codec the parameters name,
WebRtcError::SourceCodecUnsupported when WebRTC does not carry it
at all, and WebRtcError::ParameterSetsNotSupported for HEVC or VVC
configuration in hvcC/vvcC form, which this sink cannot convert.
A failed call changes nothing, so the previous declaration stays
usable and already-enqueued packets keep the one they were sent with.
Parameters carrying no extradata are accepted as they are: an encoder that still writes its headers in-band needs none prepended, and most codecs have none to prepend.
Sourcepub fn set_codec(&mut self, codec: Codec) -> Result<()>
pub fn set_codec(&mut self, codec: Codec) -> Result<()>
Declares only the codec, for a caller with no parameters to hand — one pushing packets it assembled itself rather than an encoder’s or a demuxer’s.
Prefer WebRtcTrackSink::set_source_parameters wherever the source
has parameters(): this leaves the sink with no headers to put in
front of keyframes, which for H.264, HEVC and VVC means the packets
themselves must carry their parameter sets in-band. Sink::consume
checks that on the first keyframe rather than letting a peer wait for
configuration that is never coming.
Declaring only the codec means exactly that, including after a
WebRtcTrackSink::set_source_parameters that said more: whatever
that call left — headers to prepend, a length prefix to rewrite — is
dropped here. Keeping it would apply one source’s shape to another’s
packets, which for the length prefix means rejecting every Annex-B
packet that follows.
Returns WebRtcError::OutboundCodecNotNegotiated without changing
the previous selection when codec is unavailable.
Trait Implementations§
Source§impl Element for WebRtcTrackSink
impl Element for WebRtcTrackSink
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.Source§fn graph_id(&self) -> Option<ElementId>
fn graph_id(&self) -> Option<ElementId>
ChainBuilder and keep the default None implementation.Source§fn attach_context(&mut self, _context: &Arc<Context>)
fn attach_context(&mut self, _context: &Arc<Context>)
Element::pp_log_mut hands it the pipeline’s
identity: the clock, the playback clock and the bus are the
pipeline’s to give, not the caller’s to choose. Read moreSource§impl Sink for WebRtcTrackSink
impl Sink for WebRtcTrackSink
Source§fn input_contract(&self) -> InputContract
fn input_contract(&self) -> InputContract
A track carries encoded media to the peer; this sink has no encoder of its own, so a decoded frame has no route through it.
Source§fn consume(&mut self, buf: MediaBuffer) -> Result<()>
fn consume(&mut self, buf: MediaBuffer) -> Result<()>
Source§fn control(&mut self, _msg: ControlMsg) -> Result<()>
fn control(&mut self, _msg: ControlMsg) -> Result<()>
ControlMsg (pause/resume/stop) and, for anything
with a downstream of its own, forwards it on — same shape as
consume, just a separate channel from MediaBuffer so it can
reach every element (not just ones that already know how to
interpret a data buffer) and, at a crate::queue::Queue, jump
ahead of whatever data is backed up instead of waiting behind it.
No default: every Sink has to consciously decide what this means
for it, rather than silently dropping it.Source§fn ready_consume(&mut self) -> bool
fn ready_consume(&mut self) -> bool
Self::consume can make progress now. Read more