Skip to main content

Pipeline

Struct Pipeline 

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

Top-level pipeline: one or more sources (see PipelineBuilder, with everything reachable from each source’s own src pads already linked) plus the bus every source reports events on and the Clock every crate::elements::Pacer in it shares.

run() is asynchronous: it starts every source on its own background thread and returns immediately, rather than blocking the caller for the whole play-through. Returned as Arc<Pipeline> (that’s what Pipeline::new/PipelineBuilder::build return) — the background threads deliberately do not retain an owning handle, so dropping the last external Arc can stop them. The Arc also lets Pipeline::pause/ Pipeline::resume/Pipeline::stop be called from another thread while it’s running.

There’s no separate “is it done yet” query or callback: watch Pipeline::bus instead. BusReceiver::iter/ BusReceiver::log_events block until every Bus sender has been dropped. Under the normal ownership path that happens once every source’s background thread (and everything reachable from it) has fully finished, so draining the bus doubles as “wait for completion” — with more than one source, that means waiting for all of them, not just the first to reach Eos. A caller that clones the Context supplied to a source’s own wire closure also retains its Bus sender; in that case bus draining intentionally remains blocked until that extra context is dropped. A source-level failure (returned from crate::element::SourceElement::run itself, as opposed to one reported from inside a Queue) shows up there too, as a BusEvent::Error under that source’s own name, since there’s no synchronous return path left to carry it.

A Pipeline isn’t reusable once run() has been called (whether it finished via every source’s natural Eos, Pipeline::finish, or Pipeline::stop) — a second run() call is a no-op; build a fresh Pipeline for another play-through.

Implementations§

Source§

impl Pipeline

Source

pub fn new<S: SourceElement + 'static>( id: impl Into<String>, source: S, wire: impl FnOnce(&mut S, &Arc<Context>) -> Result<()>, ) -> Result<Arc<Self>>

id names this pipeline — stamped into the source’s own pp_log as its pipeline_id right away, and folded into the Context handed to wire (see super::ChainBuilder’s own docs).

wire is called once with the freshly created source and a Context bundling this pipeline’s Bus, id, PipelineGraph (already seeded with the source itself), and Clock (share it with every crate::elements::Pacer via Clock::clone — one clock per pipeline, so every paced branch agrees on the same t=0 and the same pause/resume timeline) — everything a super::ChainBuilder/ crate::elements::Tee needs, in one Arc clone instead of four separate arguments. wire creates detached chains and attaches them through Context::attach. Pads left unattached drop data.

The single-source special case of PipelineBuilder — see its own docs for combining more than one live source (e.g. a video capture and an audio capture) into one Pipeline.

Source

pub fn id(&self) -> &str

This pipeline’s own id, as passed to Pipeline::new.

Source

pub fn bus(&self) -> &BusReceiver

Source

pub fn graph(&self) -> GraphSnapshot

Returns a consistent node/edge snapshot of the live graph. Detached branches do not appear; a successful attach or detach increments its revision exactly once.

Source

pub fn elements(&self) -> Vec<NodeInfo>

Source

pub fn topology(&self) -> String

Human-readable rundown of Pipeline::elements: one line per branch — each element nothing else in the graph feeds into (a terminal sink, or an empty crate::elements::Tee with no sinks attached yet) — formatted Type(name) - Type(name) - ... by walking that element’s upstream chain back to the source. Multiple branches (fan-out across more than one src pad, or a Tee) are joined by newlines.

Source

pub fn clock(&self) -> &Arc<Clock>

The clock every Pacer in this pipeline paces against — see Pipeline::pause for why callers don’t usually need to touch this directly.

Source

pub fn playback_clock(&self) -> &Arc<PlaybackClock>

Media-position clock shared by audio output and video scheduling.

Source

pub fn run(&self)

Starts driving the source on a background thread and returns immediately — see the type-level docs for how to learn when it’s actually done. A no-op if this Pipeline is already running or has already finished a previous run — this type has no “reset” path; build a fresh Pipeline for another play-through.

Source

pub fn pause(&self)

Blocks until every element downstream of every source has paused — see crate::control::drain_control (source side) and crate::queue::Queue’s worker loop (each thread boundary). Also pauses this pipeline’s Clock before that synchronous cascade starts, so time spent waiting for a busy downstream element to acknowledge Pause is frozen too and a Pacer doesn’t see a jump once resumed. No-op if run() isn’t currently in progress on another thread.

Source

pub fn resume(&self)

Undoes Pipeline::pause. Resumes the Clock first, so it’s already shifted forward by the time Pacers start receiving frames again.

Source

pub fn stop(&self)

Performs an early, full stop — abandons buffered work rather than draining to a natural Eos. This call is synchronous: it sends ControlMsg::Stop to every source in turn and waits for each one’s own cascade to finish before moving to the next — sequential, not parallel, across sources (fine for the handful of sources this is meant for). It therefore cannot preempt an arbitrary source read or Sink::consume call already blocked inside user or external-library code; the call returns only after that work gives the control cascade a turn. After it returns, watch Pipeline::bus for every source’s background thread to finish. Not reusable afterward — build a new Pipeline for the next play-through.

Source

pub fn finish(&self)

Gracefully completes every source and waits for the whole graph to drain. Each source stops producing and places MediaBuffer::Eos behind its already-produced data; queues preserve that order, stateful codecs flush delayed output, and muxers finalize only after their EOS arrives.

Unlike Pipeline::stop, this does not abandon queued work. If the pipeline is paused, it resumes the control cascade first so a full paused queue cannot prevent its ordered EOS from being enqueued. The call returns only after every source thread (and the Queue workers each source owns) has finished. The pipeline is not reusable afterward.

Source

pub fn seek(&self, target: Duration)

Jumps to an absolute position from the start of the media. Blocks until every source has repositioned (see crate::element::SourceElement::seek) and every element downstream of each has reacted (a Queue drops its stale backlog, a decoder flushes, a Pacer re-anchors both its pts reference and this pipeline’s Clock) — same synchronous cascade as pause/ resume/stop. One-shot, unlike pause: nothing further to undo afterward, playback just continues from the new position. No-op if run() isn’t currently in progress on another thread.

Signals the clock’s interrupt epoch before starting the synchronous cascade so a Pacer in a long wait can return its worker promptly. The clock’s playback anchor is still reset later, inside Sink::control on Pacer, after that in-flight frame is out of the way.

A source that doesn’t support seeking (e.g. a live capture) reports that via its own crate::element::SourceElement::seek returning an error — surfaced on Pipeline::bus as a BusEvent::Error under that source’s name, same as any other per-source failure, rather than failing this call outright or skipping that source silently.

Trait Implementations§

Source§

impl Drop for Pipeline

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. 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
§

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,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

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.

§

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