Skip to main content

Pacer

Struct Pacer 

Source
pub struct Pacer { /* private fields */ }
Expand description

Delays each buffer until its presentation time, so downstream sees frames (or, upstream of a decoder, compressed packets) at real playback speed instead of as fast as demux/decode can produce them. A Filter: receives via Sink, waits in short interruptible sleeps inside consume, then pushes the same buffer through its own (single) src pad. A pending pause/seek/stop interrupts that wait so the owning worker can process control: pause retains the in-flight buffer for resume, while seek and stop discard it.

Normally place a crate::queue::Queue upstream so the paced waits do not stall the demux/decoder feeding it and those stages can run ahead into the queue. The type does not enforce that placement; without the queue, pacing simply blocks the upstream caller on the same thread.

Every Pacer in a pipeline (one per stream — video, audio, …) measures against the same crate::playback_clock::PlaybackClock, so they agree on one t=0 instead of each anchoring to its own first frame. That agreement is what keeps the picture with the sound: the offset a container gives its streams is part of their sync, and a pacer zeroing on its own stream would throw it away.

Which clock that is can change while it runs. A pipeline starts on the pause-aware wall clock and hands the position to an audio renderer once its endpoint is running, and a pacer follows: what it waits on is where playback has actually reached, not where a wall-clock deadline computed at the start says it should be.

Implementations§

Source§

impl Pacer

Source

pub fn new( name: impl Into<String>, time_base: Rational, ) -> Result<Self, PacerError>

Creates a pacer using time_base to convert input PTS values to wall time.

The clock it paces against is the pipeline’s and arrives when this is wired into one — see Element::attach_context.

Source

pub fn with_discontinuity_limit( name: impl Into<String>, time_base: Rational, limit: Duration, ) -> Result<Self, PacerError>

The same, for a stream whose timeline can restart under it.

A file’s timestamps only ever move forward from where they began, so a buffer due far ahead is a real gap in the stream and waiting it out is the correct thing to do. A live sender is not like that: a camera that reboots, or an RTP timestamp base that wraps, hands over a timestamp with no relation to the one before it, and a pacer that believes it sleeps for as long as the jump says — a still picture, no error, and nothing to reconnect from, since as far as the pipeline is concerned it is working.

Past limit such a jump is read as a new timeline: the origin re-anchors so the buffer that carried it is due now, and a warning says so. Both branches of one source see the same jump and re-anchor within a buffer of each other, so the picture keeps its sound.

Pick a limit longer than the longest gap the stream can really have — for most cameras a second or two of nothing is already a problem, not a pause. Shorter than the spacing between its own frames and every ordinary wait reads as a jump, which is this pacer no longer pacing at all.

Trait Implementations§

Source§

impl Element for Pacer

Source§

fn name(&self) -> Arc<str>

Returns a cheap clone (refcount bump, not a deep copy) of this element’s name — 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

Source§

fn pp_log(&self) -> &PpLog

This element’s identity for 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

Mutable access to the same field 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 attach_context(&mut self, context: &Arc<Context>)

Hands this element the pipeline it is being wired into, at the moment and for the reason 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 more
Source§

fn graph_id(&self) -> Option<ElementId>

A pre-reserved graph identity for elements that expose dynamic attachment handles. Most elements receive an ID from ChainBuilder and keep the default None implementation.
Source§

impl Sink for Pacer

Source§

fn input_contract(&self) -> InputContract

Pacing is a delay, not a transform: every kind is held until its own PTS comes due and then forwarded unchanged.

Source§

fn consume(&mut self, buf: MediaBuffer) -> Result<()>

Processes one buffer synchronously on the caller’s thread. Read more
Source§

fn control(&mut self, msg: ControlMsg) -> Result<()>

Reacts to a 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

Returns whether calling Self::consume can make progress now. Read more
Source§

impl Source for Pacer

Source§

fn src_pads(&mut self) -> &mut [SrcPad]

Returns every output pad owned by this element. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Pacer

§

impl !Sync for Pacer

§

impl !UnwindSafe for Pacer

§

impl Freeze for Pacer

§

impl Send for Pacer

§

impl Unpin for Pacer

§

impl UnsafeUnpin for Pacer

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

Source§

impl<T> Filter for T
where T: Source + Sink,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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