Skip to main content

Demuxer

Trait Demuxer 

Source
pub trait Demuxer {
    type Adapter: DemuxAdapter;
    type Buffer: AsRef<[u8]>;
    type TrackHandle: Clone + Deref<Target = TrackInfo<Self::Adapter>>;
    type Error;

    // Required methods
    fn tracks(&self) -> &[Self::TrackHandle];
    fn next_packet(
        &mut self,
    ) -> Result<Option<DemuxedPacket<Self::Adapter, Self::Buffer>>, Self::Error>;
    fn seek(&mut self, target: Timestamp) -> Result<(), Self::Error>;
}
Expand description

An opened container session: the track table, a pull loop, and a seek.

§Delivery order

next_packet returns packets in interleaved file order — the order the container stores them in, tracks mixed together exactly as written. Ok(None) means end of file, and once it is returned it stays returned until a seek moves the session somewhere else.

§Why Option and not Received

The decoders’ three-state answer has a state this face does not: needs-input cannot happen to a demuxer. A demuxer is pulled, not fed — there is no caller-supplied input it could be waiting on, so a NeedsInput arm here would be a state no backend can ever produce and every consumer would still have to write a match arm for. Ok(None) is the same fact in the shape that fits: two states, two values, and the packet itself riding in the Ok arm rather than into a dst.

What the two faces share is the law, not the type: a protocol state never travels in Err. End of file is not a failure here for the same reason Received::Ended is not one there.

§The attachment contract

An Attachment track delivers exactly one packet, before any timed packet. Attachments are not on the timeline, so a consumer must be able to collect them all before it starts consuming time — a subtitle renderer needs its fonts before the first cue, and a thumbnailer wants the cover art without reading the file to its end. Backends satisfy this by synthesising the packet when the container keeps the payload outside the packet stream (fonts, whose bytes live in the track’s codec extradata) and by hoisting the natural one when it exists (cover art, which is a real packet the container stores).

A track’s identity — the filename it was attached under, its MIME type — is on TrackInfo, not repeated on every packet.

§Seeking

seek obeys three laws:

  1. It flushes session state. Anything buffered from before the seek is discarded; the next next_packet reads from the new position.
  2. It lands on the nearest keyframe at or before the target. Never after. A decoder fed from a landing point past the target would have no reference frame, so “at or before” is a correctness requirement, not a preference — the caller discards the packets between the landing point and the target itself.
  3. Attachments are never replayed. An attachment already delivered is not delivered again, however many times the session seeks. One attachment track yields one packet for the life of the session — a seek moves the timeline, and attachments are not on it.

§The track table

tracks is a non-destructive read, and a session holds its table for its whole life: the rows a caller reads before the first pull are the same rows the session classifies every packet against, and they are still there after end of file. Reading the table therefore has no ordering rule at all — before the first packet, between two of them, after EOF, twice, never.

The table is shared, not handed over. TrackInfo has no Clone (see its own doc for the message-carrier law), so a caller that needs a row beyond a borrow of &self — to fan it out, or simply to hold it across the &mut self of the pull loop — clones a TrackHandle instead.

This face used to carry a take_tracks that moved the table out of the session. It is gone, root and branch: a demuxer that has given its table away can no longer say which track a packet belongs to, and the one backend that implemented it classified against the very Vec the move emptied — so following the documented order made every packet in a healthy file vanish. A read that costs the session the state it runs on is not a door worth having.

§What is not here

Opening. See the module docs.

Required Associated Types§

Source

type Adapter: DemuxAdapter

Backend-specific vocabulary.

Source

type Buffer: AsRef<[u8]>

Buffer type held by the packets this session produces.

Source

type TrackHandle: Clone + Deref<Target = TrackInfo<Self::Adapter>>

A shareable handle on one row of the track table.

The row is read through the handle, and a consumer that needs to keep a row past a borrow of the session clones the handle. The backend picks the carrier, the same way it picks Buffer: a heap-backed, thread-crossing backend binds Arc<TrackInfo<..>>, a single-threaded one binds Rc, and one whose rows live in memory it already borrows binds &TrackInfo<..> — which is what keeps this whole tier allocator-free.

Clone on a handle must be a refcount bump or a copied borrow, never a deep copy of the row — the message-carrier law TrackInfo states. An implementor is what upholds it; the bound is what makes upholding it the path of least resistance, since TrackInfo is not Clone, Box<TrackInfo<_>> therefore is not either, and no #[derive(Clone)] reaches a carrier that owns a row outright. A deep copy here would have to be hand-written against the law.

Source

type Error

Demuxer-specific error type.

Required Methods§

Source

fn tracks(&self) -> &[Self::TrackHandle]

Returns the container’s track table.

Position i describes TrackIndex::new(i) — the coordinate every DemuxedPacket carries.

Non-destructive, and callable whenever: see the track table on the trait.

Source

fn next_packet( &mut self, ) -> Result<Option<DemuxedPacket<Self::Adapter, Self::Buffer>>, Self::Error>

Pulls the next packet in interleaved file order, or Ok(None) at end of file.

Source

fn seek(&mut self, target: Timestamp) -> Result<(), Self::Error>

Seeks to target, landing on the nearest keyframe at or before it.

See the three laws on the trait.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§