Skip to main content

Decoder

Trait Decoder 

Source
pub trait Decoder: Send {
    // Required methods
    fn codec_id(&self) -> &CodecId;
    fn send_packet(&mut self, packet: &Packet) -> Result<()>;
    fn receive_frame(&mut self) -> Result<Frame>;
    fn flush(&mut self) -> Result<()>;

    // Provided methods
    fn receive_arena_frame(&mut self) -> Result<Frame> { ... }
    fn reset(&mut self) -> Result<()> { ... }
    fn set_execution_context(&mut self, _ctx: &ExecutionContext) { ... }
    fn output_pixel_format(&self) -> Option<PixelFormat> { ... }
    fn output_params(&self) -> Option<CodecParameters> { ... }
    fn output_params_generation(&self) -> u64 { ... }
}
Expand description

A packet-to-frame decoder.

Required Methods§

Source

fn codec_id(&self) -> &CodecId

Identifier of the codec this decoder handles.

Source

fn send_packet(&mut self, packet: &Packet) -> Result<()>

Feed one compressed packet. May or may not produce a frame immediately — call receive_frame in a loop afterwards.

Source

fn receive_frame(&mut self) -> Result<Frame>

Pull the next decoded frame, if any. Returns Error::NeedMore when the decoder needs another packet.

Source

fn flush(&mut self) -> Result<()>

Signal end-of-stream. After this, receive_frame will drain buffered frames and eventually return Error::Eof.

Provided Methods§

Source

fn receive_arena_frame(&mut self) -> Result<Frame>

Pull the next decoded frame as an arena-backed arena::sync::Frame.

Decoders that build their output through an arena::sync::ArenaPool override this to return the pooled arena::sync::Frame directly, with no per-plane memcpy out — the caller gets true zero-copy plane access via arena::sync::FrameInner::plane.

The default implementation delegates to Self::receive_frame and copies the video planes into a freshly-leased one-shot arena::sync::ArenaPool. This makes the method an additive change for every existing Decoder impl: callers using the new API still work, but pay one memcpy per plane.

Audio / subtitle frames: the arena::sync::Frame body is video-only (planes + arena::sync::FrameHeader with width/height/pixel format). The default implementation returns Error::Unsupported for non-video frames; an audio decoder that wants to expose receive_arena_frame() must override it with its own arena-backed audio-frame type once the framework gains one. Until then, audio decoders should keep using Self::receive_frame.

Source

fn reset(&mut self) -> Result<()>

Discard all carry-over state so the decoder can resume from a new bitstream position without producing stale output. Called by the player after a container seek.

Unlike flush (which signals end-of-stream and drains buffered frames), reset is expected to:

  • drop every buffered input packet and pending output frame;
  • zero any per-stream filter / predictor / overlap memory so the next send_packet decodes as if it were the first;
  • leave the codec id and stream parameters untouched.

The default is a conservative “drain-then-forget”: call flush and ignore any remaining frames. Stateful codecs (LPC predictors, backward-adaptive gain, IMDCT overlap, reference pictures, …) should override this to wipe their internal state explicitly — otherwise the first ~N output samples after a seek will be glitchy until the state re-adapts.

Source

fn set_execution_context(&mut self, _ctx: &ExecutionContext)

Advisory: announce the runtime environment (today: a thread budget for codec-internal parallelism). Called at most once, before the first send_packet. Default no-op; codecs that want to run slice-/GOP-/tile-parallel override this to capture the budget. Ignoring the hint is always safe — callers must still work with a decoder that runs serial.

Source

fn output_pixel_format(&self) -> Option<PixelFormat>

Pixel layout of the video frames this decoder emits, stated before the first frame — from the codec’s configuration record in extradata, from a negotiated hardware session, or from the decoder’s fixed output policy. Some is a fact about the frames to come and takes precedence over the container’s CodecParameters::pixel_format (a stream label is a claim the container made; the decoder is the one producing the planes). None — the default — means “not known yet: trust the stream parameters”, and a decoder whose output depends on the first packet (an untagged file that decides its layout per picture) answers None until it has seen one and the real layout afterwards.

Pipelines and gateways read it to label frames from codec-only registrations and to pick the conversion into an encoder’s accepted_pixel_formats; a frame whose plane shape disagrees with the stated layout is the decoder’s defect, not the consumer’s. The answer may change between frames only for a decoder that documents it.

This is the narrow, older form of output_params, whose default derives from it. New decoders implement output_params (the whole output description) and forward this method to it; consumers should prefer output_params.

Source

fn output_params(&self) -> Option<CodecParameters>

The decoder’s resolved description of the frames it emits — the stream-level home for what Frames deliberately do not repeat (a VideoFrame / AudioFrame carries no width, height, format or rate: the shape does not change 60 times a second, so it is stated once, here, and re-stated only when it changes).

Fields a decoder fills when it knows them:

Fields the decoder does not know stay None / unspecified; container-side fields (extradata, bit_rate, tag, language, blobs, options, limits) are not the decoder’s to answer and are ignored by CodecParameters::merge_output_params, the helper that folds this answer into a stream’s parameters.

Some is a fact about the frames and takes precedence over the container’s claim for every field it sets. None means “not known yet: trust the stream parameters”. A decoder answers as soon as it has parsed what defines the output — its configuration record in extradata at construction, or the first sequence / frame header — ideally before the first frame is returned, and at the latest once receive_frame has returned the first frame. From then on the answer describes the frame most recently returned by receive_frame (and the ones after it, until output_params_generation changes).

Default and the relation to output_pixel_format: the default implementation derives from output_pixel_format() — Some of a video CodecParameters carrying only codec_id and pixel_format when that answers Some, None otherwise — so every decoder that implements the older narrow query is described here for free. The direction is one-way: output_params reads output_pixel_format, never the other way round (no default recursion). A decoder that implements output_params itself should also forward output_pixel_format to it (self.output_params().and_then(|p| p.pixel_format)) so callers of the narrow query keep seeing the same answer. Consumers should query output_params — it is the complete answer.

Source

fn output_params_generation(&self) -> u64

A cheap change signal for output_params: an integer that changes whenever the output description changes mid-stream (a resolution switch at a keyframe, a new pixel format at a new sequence header, a sample-rate change in a chained stream). Consumers keep the last value they saw and compare one integer after each successful receive_frame; only when it differs do they re-read output_params(). Frames carry nothing extra.

The contract:

  • Consumers always read output_params() once after the first frame (or before it, if they need the shape up front) — resolving the description from None to Some before or at the first frame is not a change and needs no bump.
  • After the first frame has been returned, a decoder whose output description changes increments the value (wrapping, so it only ever needs != comparison) at a frame boundary: the bump and the new output_params() answer become visible together, when receive_frame returns the first frame with the new shape — not when the decoder parses the header announcing it, because frames of the old shape may still be queued in its reorder buffer. Once receive_frame has returned a frame, output_params() describes that frame.
  • It never changes while the description stays the same, and a bump always comes with a changed description.
  • reset after a seek may change it (the new position can be in a segment of a different shape) under the same rule: visible with the first frame returned afterwards.

The default 0 — “never changes” — is correct for every decoder whose output shape is fixed for the stream’s lifetime. OutputParamsWatch packages the consumer side in one call.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§