pub enum FrameEncoder {
Nvenc(NvencEncoder),
Vaapi(VaapiEncoder),
Vpx(VpxEncoder),
Hevc(HevcEncoder),
Av1(SvtAv1Encoder),
V4l2m2m(V4l2M2mEncoder),
}Expand description
One full-frame encoder session, whichever backend produced it, so the render and delivery code passes “the frame encoder” around without caring which vendor path or library produced the frames.
Variants§
Nvenc(NvencEncoder)
Vaapi(VaapiEncoder)
A VA-API session on a render node, hardware.
Vpx(VpxEncoder)
libvpx VP8 or VP9, software.
Hevc(HevcEncoder)
x265 or kvazaar, software.
Av1(SvtAv1Encoder)
SVT-AV1, software.
V4l2m2m(V4l2M2mEncoder)
A stateful V4L2 M2M encoder, driven through the kernel interface directly.
Implementations§
Source§impl FrameEncoder
impl FrameEncoder
Sourcepub fn is_hardware(&self) -> bool
pub fn is_hardware(&self) -> bool
Whether the session encodes on a GPU or a hardware engine.
Sourcepub fn fixed_rate_control(&self) -> Option<&'static str>
pub fn fixed_rate_control(&self) -> Option<&'static str>
The rate control the session runs whatever mode it was given, for a backend that has one
alone: a V4L2 M2M device offers variable bitrate only, and Tegra’s encoder is driven at a
constant one. None where the session runs the mode it was given.
Sourcepub fn backend_name(&self) -> &'static str
pub fn backend_name(&self) -> &'static str
The backend as the logs name it: NVENC, VAAPI, or the software library.
Sourcepub fn dmabuf_planes(&self) -> usize
pub fn dmabuf_planes(&self) -> usize
The planes of one dmabuf the session imports as it stands: VA-API’s descriptor maps up to four, each to the object it lies in (a compressed layout’s metadata is a plane beside the pixels); NVENC imports the first plane through EGL, so a buffer of more is composited.
Sourcepub fn is_fullcolor(&self) -> bool
pub fn is_fullcolor(&self) -> bool
Whether the session negotiated 4:4:4 chroma.
Sourcepub fn bit_depth(&self) -> u32
pub fn bit_depth(&self) -> u32
The bits per sample the session negotiated: 10 on a VA-API session that opened a 10-bit profile and on a software one whose library codes them, 8 everywhere else.
Sourcepub fn is_full_range(&self) -> bool
pub fn is_full_range(&self) -> bool
Whether the session signals full range: a software 4:4:4 of x264’s kind, and the V4L2 M2M sessions whose firmware converts at full range and offers no way to ask for another.
Sourcepub fn reconfigure_rate(
&mut self,
settings: &CaptureSettings,
) -> Result<(), String>
pub fn reconfigure_rate( &mut self, settings: &CaptureSettings, ) -> Result<(), String>
Apply a live bitrate / VBV / frame-rate change. Err means the session lost its codec
context and has to be rebuilt.
Sourcepub fn encode_host(
&mut self,
pixels: &[u8],
stride: usize,
rgba: bool,
frame_number: u64,
qp: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_host( &mut self, pixels: &[u8], stride: usize, rgba: bool, frame_number: u64, qp: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
Encode one packed host frame (stride bytes per row; rgba names R,G,B,A byte order,
otherwise B,G,R,A) at quantizer qp, as a key frame when force_idr.
Sourcepub fn encode_client_host(
&mut self,
pixels: &[u8],
stride: usize,
rgba: bool,
frame_number: u64,
qp: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_client_host( &mut self, pixels: &[u8], stride: usize, rgba: bool, frame_number: u64, qp: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
encode_host for rows a client owns and may unmap after the call, as the wl_shm buffer
a Wayland capture encodes as it stands: NVENC uploads them without page-locking them
(NvencEncoder::encode_client_packed), and every other session reads them as
encode_host does.
Sourcepub fn hash_next_upload(&mut self, rows: u32) -> bool
pub fn hash_next_upload(&mut self, rows: u32) -> bool
Hash the next host frame’s bands of rows rows where the encoder holds it, beside its
encode (NVENC: NvencEncoder::hash_next_upload); false where it cannot, which leaves the
hash to the caller.
Sourcepub fn take_upload_hashes(&mut self) -> Option<Vec<u64>>
pub fn take_upload_hashes(&mut self) -> Option<Vec<u64>>
The band hashes hash_next_upload asked for, once the frame is coded.
Sourcepub fn last_quality(&self) -> Option<u32>
pub fn last_quality(&self) -> Option<u32>
The quality index (the H.26x quantizer scale video_crf uses) the last frame was coded at,
where the session reports its quantizer: what a constant-rate session’s picture is worth
against the paint-over quality.
Sourcepub fn last_size(&self) -> Option<usize>
pub fn last_size(&self) -> Option<usize>
The bytes of the last frame the rate control coded, held frames aside, where the session
reports them (NVENC, VA-API, x265 and kvazaar, libvpx’s VP9): what tells a constant-rate
cleanup that runs through the rate control whether it has converged on a still screen
(pipeline::decide_hw_fullframe), with last_quality where the session reports that
too.
Sourcepub fn measure(&mut self)
pub fn measure(&mut self)
Have the next frame’s reconstruction measured against its source, where the session
can (last_psnr).
Sourcepub fn measures(&self) -> bool
pub fn measures(&self) -> bool
Whether measure has the session measure a frame: VA-API, which reads its
reconstruction back, where the driver’s surfaces let it.
Sourcepub fn last_psnr(&self) -> Option<f32>
pub fn last_psnr(&self) -> Option<f32>
The luma PSNR of the last frame measured (measure), where the session reads its
reconstruction back: VA-API. What a constant-rate cleanup through the rate control
ends on where it has one, since a picture that stopped improving needs no more frames
whatever quantizer the driver reports.
Sourcepub fn cap(&mut self, bytes: usize)
pub fn cap(&mut self, bytes: usize)
Take the next frame back where it comes out past bytes and code it again within them:
a band held at a quantizer (hold_quantizer) in a shorter band, a frame of the rate
control’s at the coarsest quantizer, refining nothing. NVENC, which leaves the frame out of
the predictions as one a client lost, does. VA-API codes the frame at the rate that spends
bytes in the cleanup’s frame time instead (follows_cap); elsewhere the frame stands as
coded.
Sourcepub fn follows_cap(&self) -> bool
pub fn follows_cap(&self) -> bool
Whether a still screen’s cleanup frame is coded at the rate its cap runs at (cap), so
the cleanup judges it against that rate’s budget: VA-API at a constant rate, which takes
a new target with a picture, and libvpx’s VP9, which takes one live. NVENC takes a frame
back instead.
Sourcepub fn reach_finer(&self) -> u32
pub fn reach_finer(&self) -> u32
The quantizer steps finer than the paint-over one at which the rate control’s frames come
to the paint-over quality, where a constant-rate cleanup runs through it: the software
HEVC encoders’ predicted frames at a quantizer leave the motion’s coarse blocks as they
are, and x265’s cleanup ended at 45-46 dB at the paint-over quantizer where its key frame
there decodes at 50 (HevcEncoder::reach_finer). Elsewhere none.
Sourcepub fn ends_cleanup_on_key(&self) -> bool
pub fn ends_cleanup_on_key(&self) -> bool
Whether a constant-rate cleanup through the rate control ends on a key frame held at the
paint-over quantizer after a large change and a longer stillness: where the rate control
cannot refine a still screen in the frames’ budget and the session says nothing of how far
it got (VaapiEncoder::ends_cleanup_on_key). Elsewhere a refresh or the rate control’s
own frames do, and a key frame would only cost more (libvpx’s VP9 key frame of 1080p text
came out at 231 kB and 30.9 dB at its coarsest).
Sourcepub fn refit(&self) -> Option<f64>
pub fn refit(&self) -> Option<f64>
Where the last frame was taken back and coded again (cap): how far its held band then
reached, or 0 for a frame of the rate control’s.
Sourcepub fn take_lost_cleanup(&mut self) -> bool
pub fn take_lost_cleanup(&mut self) -> bool
Whether a frame left a held band out of every prediction with no band of its own to take
it back into since this was last asked: NVENC, whose anchors predict from the newest frame
every client was sent (NvencEncoder::take_lost_cleanup).
Sourcepub fn band_size(&self) -> Option<usize>
pub fn band_size(&self) -> Option<usize>
The bytes of the last frame held at a quantizer (0 before one), where the session holds a
band of a frame at it (hold_quantizer): NVENC’s H.264, HEVC and AV1 sessions, through a
QP delta map, and libvpx’s VP8, through a region-of-interest map.
Sourcepub fn refines(&self) -> Option<Refiner>
pub fn refines(&self) -> Option<Refiner>
How the session refines blocks of a frame of its rate control’s at a quality of their
own (refine_blocks, ledger::Refiner), so a refined block comes to what the region’s
own cleanup reaches; None where it does not: NVENC’s H.264, HEVC, and AV1 through the
QP delta map (nvenc::REFINE_FINER), libvpx’s VP8 through its region-of-interest map
(vpx::REFINE_FINER, which says why not VP9), x265 through its per-block quantizer
offsets and kvazaar through its per-tree-block map (HevcEncoder::refine_finer). x264’s
session refines within software::encode_cpu (ledger::REFINE_FINER).
Sourcepub fn constant_blocks(&mut self, constant: &[bool])
pub fn constant_blocks(&mut self, constant: &[bool])
Mark the blocks of the next frame, in raster order, that held still and are clean
(BlockLedger::constant), which a session codes as skips without analysis where its
library takes such a map and the frame predicts from the one before: libvpx’s VP8 and
VP9 through their active map, x265 through its constant-block map, and SVT-AV1 through
the map its input copy reads. An empty slice marks none, and a session takes the map
only on a frame of its rate control’s, never on a key frame or a held one.
Sourcepub fn refine_blocks(&mut self, refinement: &Refinement)
pub fn refine_blocks(&mut self, refinement: &Refinement)
Code the blocks refinement names in the next frame, where it is the rate control’s, at
its target quality (ledger), where refines.
Sourcepub fn holds_quantizer(&self) -> bool
pub fn holds_quantizer(&self) -> bool
Whether hold_quantizer holds a frame at the quantizer asked for under the session’s rate
control: NVENC, libvpx’s VP8, and SVT-AV1 at a constant rate (where the release takes a
new target with a picture) do; x265, VA-API, and libvpx’s VP9 only at a constant
quantizer (their holds_quantizer and hold_quantizer say why not at a constant rate,
VP9’s that its rate control refines a still screen within the rate); kvazaar, Tegra,
and a stateful V4L2 device take no quantizer from the caller. The cleanup of a
constant-quality session moves the session’s quality instead of holding a frame
(pipeline::decide_constant_quality), so this is read at a constant rate.
Sourcepub fn capped(&self) -> bool
pub fn capped(&self) -> bool
Whether the session runs its constant quality under the peak it was asked for: NVENC,
libvpx, and SVT-AV1 where asked, SVT-AV1 where the release forces a picture’s quantizer
and keeps the sequence’s otherwise (svtav1_sequence_qp); x265, kvazaar, and VA-API never,
and the V4L2 and Tegra devices run at the rate whatever the mode (their module docblocks).
Sourcepub fn rate_bound(&self, cbr: bool) -> bool
pub fn rate_bound(&self, cbr: bool) -> bool
Whether a rate binds the session: a constant rate, or a constant quality whose peak bound
its last frame (NVENC through its constant rate, libvpx above its pinned quantizer, SVT-AV1
at a quantizer the peak raised), each
of which codes a frame coarser than its quality, so its refinement and block ledger follow
what its rate control coded (pipeline::plan_refinement). Under a peak that does not bind,
a capped session refines as its uncapped quality does.
Sourcepub fn coded_capped(&self) -> bool
pub fn coded_capped(&self) -> bool
Whether the frame just coded was coded under a capped constant quality’s binding peak,
coarser than the rate factor would have chosen (ledger::BlockLedger::coded): NVENC
through its constant rate, libvpx above its pinned quantizer, SVT-AV1 at a quantizer the
peak raised.
Sourcepub fn idle(&mut self)
pub fn idle(&mut self)
A tick that codes no frame: a capped constant quality’s peak drains for it as for an
empty frame, so a still screen lets the peak go and its refresh starts
(ledger::BlockLedger::refresh).
Sourcepub fn defer_blocks(&mut self, plan: Option<&BlockPlan>)
pub fn defer_blocks(&mut self, plan: Option<&BlockPlan>)
Hold the blocks plan names as skips in the next frame: the coarse blocks a capped
constant quality’s refresh leaves for later frames (ledger::BlockLedger::refresh).
NVENC, which takes no skips, holds them at its coarsest quantizer through its QP delta
map; an encoder that takes skips (constant_blocks) has them among those.
Sourcepub fn reopens_on_quality(&self) -> bool
pub fn reopens_on_quality(&self) -> bool
Whether a change of the session’s constant quality re-opens it, so the frame it applies
to is a key frame: x265 and kvazaar take no new quality while they run, and SVT-AV1 none
until a capped session’s peak binds (SvtAv1Encoder::reopens_on_quality). The cleanup of a
constant-quality session counts such a refresh as its key frame.
Sourcepub fn cleans_up_with_key(&self) -> bool
pub fn cleans_up_with_key(&self) -> bool
Whether a constant-rate cleanup ends on a key frame after a large change and a longer
stillness (pipeline::decide_hw_fullframe). SVT-AV1 holds only a key frame, so that is its
cleanup. libvpx’s VP8 holds the refresh before it, predicted frames that restore the
picture whole (in bands where the rate leaves room, VpxEncoder::band_size), and its key
frame only sent the picture again: 1080p text at 0.25 Mbit/s
went quiet on 1.3 MB without it against 2.7, at the same 42 dB, since the key frame came
out capped coarser than the picture (216 kB at 21.6 dB) and a second refresh restored it.
Sourcepub fn hold_quantizer(&mut self, crf: u32, band: Option<(f64, f64)>)
pub fn hold_quantizer(&mut self, crf: u32, band: Option<(f64, f64)>)
Encode the next frame at the quantizer the quality index crf selects whatever the rate
control, and leave the session’s own rate control and quality as they were for the frame
after: the cleanup of a still screen, where holds_quantizer. A session whose engine takes
no quantizer from the caller (Tegra, a stateful V4L2 device) codes that frame under its own
rate control. band, the share of the picture from and to in raster order, confines the
quantizer to that band where band_size says the session holds one, the rest of the frame
held at the coarsest quantizer.
Sourcepub fn delivered_units(
&self,
data: Vec<u8>,
encoded: u16,
) -> Vec<(Vec<u8>, u16, Reference)>
pub fn delivered_units( &self, data: Vec<u8>, encoded: u16, ) -> Vec<(Vec<u8>, u16, Reference)>
The data one call returned, cut at the units it carries, each with its own frame’s id and
reference: whole and labeled encoded from a session that hands back the frame it
encoded, one unit per earlier frame from one that hands them back late (Tegra), so what a
consumer reports lost is the unit it dropped and nothing else.
Sourcepub fn push_held(&mut self, frame_number: u64) -> Result<Vec<u8>, String>
pub fn push_held(&mut self, frame_number: u64) -> Result<Vec<u8>, String>
The frame the last delivered frame predicted from. The access unit a still screen leaves inside an engine that emits a frame only once the next is queued: empty from every other backend, whose units come with their frame.
pub fn holds_frame(&self) -> bool
pub fn last_reference(&self) -> Reference
Sourcepub fn invalidate_reference(&mut self, frame_id: u16) -> bool
pub fn invalidate_reference(&mut self, frame_id: u16) -> bool
Leave frame frame_id and every frame after it out of the predictions, so the next
frame decodes for a client that lost it. False when the session cannot, and the caller
codes a key frame instead.
Sourcepub fn take_report(&mut self, report: ReferenceReport) -> bool
pub fn take_report(&mut self, report: ReferenceReport) -> bool
Apply what the consumers say of a frame: a loss as invalidate_reference, a frame every
one of them holds or was sent to a session keeping long-term references
(ReferenceWindow::acknowledge). False where the session codes a key frame instead.
Sourcepub fn encode_dmabuf(
&mut self,
dmabuf: &Dmabuf,
frame_number: u64,
qp: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_dmabuf( &mut self, dmabuf: &Dmabuf, frame_number: u64, qp: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
Encode one Wayland dmabuf in place (a zero-copy session).
Sourcepub fn encode_dmabuf_after_blit(
&mut self,
dmabuf: &Dmabuf,
frame_number: u64,
qp: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_dmabuf_after_blit( &mut self, dmabuf: &Dmabuf, frame_number: u64, qp: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
encode_dmabuf, for a buffer the X server signals the session’s blit semaphore after
blitting into (blit_semaphore_fd): the frame’s GPU work waits on it on the GPU.
Auto Trait Implementations§
impl !Sync for FrameEncoder
impl Freeze for FrameEncoder
impl RefUnwindSafe for FrameEncoder
impl Send for FrameEncoder
impl Unpin for FrameEncoder
impl UnsafeUnpin for FrameEncoder
impl UnwindSafe for FrameEncoder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more