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§
Sourcefn send_packet(&mut self, packet: &Packet) -> Result<()>
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.
Sourcefn receive_frame(&mut self) -> Result<Frame>
fn receive_frame(&mut self) -> Result<Frame>
Pull the next decoded frame, if any. Returns Error::NeedMore when the
decoder needs another packet.
Provided Methods§
Sourcefn receive_arena_frame(&mut self) -> Result<Frame>
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.
Sourcefn reset(&mut self) -> Result<()>
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_packetdecodes 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.
Sourcefn set_execution_context(&mut self, _ctx: &ExecutionContext)
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.
Sourcefn output_pixel_format(&self) -> Option<PixelFormat>
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.
Sourcefn output_params(&self) -> Option<CodecParameters>
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:
- video —
width/heightas the frames have them (the cropped / display size of the emitted planes, not the coded macroblock-aligned size),pixel_format,frame_ratewhen the bitstream signals one,color_signalfrom the bitstream’s own signalling, andlayersfor multi-layer output; - audio —
sample_rate,channels,sample_format,channel_layout.
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.
Sourcefn output_params_generation(&self) -> u64
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 fromNonetoSomebefore 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 newoutput_params()answer become visible together, whenreceive_framereturns 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. Oncereceive_framehas 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.
resetafter 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".