pub enum DecodePath {
Auto,
AnyHardware,
Hardware(Backend),
Software,
}Expand description
Which decode path a video session takes — the choice
CarrierVideoStreamDecoder::open_as is given.
§Three words and a pin, and what each permits
Auto: before the first picture, the platform’s hardware backends in probe order, the packets taken so far replayed across them; when none takes the stream, software, the same packets replayed into it. After it, the decoder that produced it.AnyHardware: the same probe, and never software — when no backend takes the stream,Error::AllBackendsFailedhands back the packets the probe took. After the first picture, the backend that produced it.Software: libavcodec’s own decoder, with no probe, before and after.Hardware(b), the pin: backendb, committed at open; nothing else is tried, before or after.
After the first picture nothing changes the road, on any path, and
nothing is classified. A decoder failure
(VideoDecodeError::Decode) is that picture’s own error, reported as
it was minted, and nothing of it is remembered, so the next call
reaches libavcodec. Whether a hardware session recovers is FFmpeg’s:
after a VideoToolbox restart that fails, every picture fails the same
way until a new parameter set re-arms the restart, and flush rebuilds
no hardware session. See VideoDecoder for the
lines.
§When to stop trusting a hardware session
A caller that sees a hardware session’s decoder failures persist
rebuilds: it opens a session on Software from the
same parameters and feeds it forward. When to do so is the caller’s
policy, not this crate’s, because it is the caller that sees the
failures on all three roads, the packets’ key flags and what it has
delivered. What the new session can be fed depends on the road the
failure came from:
send_packet: the failure names the packet in hand, and the new session is given that packet.receive_frame: the failure may concern a packet accepted earlier. FFmpeg decouples input from output and may hold several pictures (libavcodec/avcodec.h90–139 in FFmpeg 9.0.1), so no packet is named: the new session is given the next packet, and the caller accepts the gap.send_eof: the end has no packet to give a new session. What the hardware session still held is recoverable only from packets kept from before, or by a seek.
What a policy counts is the hardware session’s decoder failures,
VideoDecodeError::Decode. A VideoDecodeError::Convert is this
wrapper’s own: a decoded picture it could not convert into a frame (a
frame ceiling, a pixel format or plane layout it cannot carry, an
allocation). It is reported, not counted. One that failed on an
allocation parks the picture: the next receive_frame converts it
again, and until one delivers it send_packet and send_eof answer
Sent::MustDrain without reaching libavcodec. That is the wrapper’s
back pressure, not a failure.
The example in the crate documentation is the simplest such policy:
- It counts the hardware session’s decoder failures from all three roads, and only a delivered picture ends the count.
- At a threshold of its own it opens
Softwarefrom the same parameters and feeds it forward, road by road as above. Every picture the new session delivers is delivered as it is. - On software its failures are reported and the stream goes on: software is where the policy ends.
It keeps no packets, so the pictures from a failure to the next keyframe are lost: the new session holds no reference pictures, and libavcodec drops or conceals what comes before one. A caller that cannot afford that gap keeps packets and replays them with a picture identity of its own; that bookkeeping is the caller’s design, and the example does not show it.
The words differ in what they permit, not only where they start.
That is the difference the consumers of this door need. A determinism
comparison decodes one stream both ways and compares the pixels; a
run that silently swapped paths halfway would compare nothing and say
it had. An operator turning hardware off for a lane over a driver that
produces wrong pixels needs it to stay off. And a node that sends
hardware and software sessions to separate pools needs a hardware
session that never quietly becomes a software one — which is what
AnyHardware is for.
§Observability
is_hardware and
is_software read where a
session is, which stays a live reading — under
Auto it can change once, during the probe, and under
the others it answers what was chosen because nothing can move it.
This type deliberately grows no is_* predicates of its own,
where most vocabularies in this crate do. They would spell the
decoder’s two questions a second time with a different meaning —
path.is_software() is what was asked for and
decoder.is_software() is where it ended up, and under
Auto those genuinely differ. A caller that needs to
branch on the choice it made already holds the value and can
match it.
Variants§
Auto
Probe the platform’s hardware backends in order and fall back to software when none takes the stream before its first picture, the packets the probe consumed replayed into it so nothing is lost. After the first picture the session stays on the decoder that produced it.
What CarrierVideoStreamDecoder::open does.
AnyHardware
Any of the platform’s hardware backends, and never software.
The same probe as Auto: the backends in the
platform’s probe order, the packets taken before the first picture
replayed across them as each one is tried. Where Auto would then
open software, this arm refuses — at
open_as when no backend
opens (on a platform with no hardware backend at all, at once), and
on the road that met it when the probe exhausts later — with
Error::AllBackendsFailed carrying every backend’s attempt and the
packets the probe took, so the caller can replay them into a
software session of its own. After the first picture it is the
backend that produced it, as on every path.
is_hardware answers
true for the session’s whole life.
Hardware(Backend)
This hardware backend, or nothing. No other backend is probed and software is never opened.
A backend that cannot be opened for the stream fails the
open_as call. The backend is
committed from open, so every failure after it is that picture’s
own error, as on every path.
Software
Software, with no probe at all.
Opens libavcodec’s own decoder for the stream directly. There is
no hardware in this session to fail, so there is nothing for it to
fall back from — the state Auto reaches when its
probe exhausts, entered on purpose.