pub struct VaapiEncoder {Show 44 fields
codec: Codec,
input: Input,
device: Arc<Device>,
config: VAConfigID,
context: VAContextID,
vpp_config: VAConfigID,
vpp_context: VAContextID,
vpp_standards: (VAProcColorStandardType, VAProcColorStandardType),
negotiated: Negotiated,
fourcc: u32,
rt_format: u32,
surface_width: u32,
surface_height: u32,
low_power: bool,
recon: Vec<VASurfaceID>,
converted: Vec<VASurfaceID>,
host: Option<HostUpload>,
imports: Vec<(i32, DmaBufIdentity, VASurfaceID)>,
coded: VABufferID,
arm: Arm,
references: Option<References>,
frame_count: u64,
key_count: u64,
surfaces_of: HashMap<u64, VASurfaceID>,
last_reference: Reference,
rate: RateSettings,
qp: u32,
held: Option<u32>,
refinement: Option<Refinement>,
roi: Vec<VAEncROI>,
frame_cap: bool,
last_bytes: Option<usize>,
cleanup_bps: Option<u32>,
sent_bps: u32,
last_quality: Option<u32>,
measure: bool,
last_psnr: Option<f32>,
measures: bool,
quality_level: Option<u32>,
sequence_start: bool,
declared_level: u32,
omit_headers: bool,
fresh: bool,
reorder: NoReorder,
}Expand description
One VA-API encoder session, hardware, for one capture.
Fields§
§codec: Codec§input: Input§device: Arc<Device>§config: VAConfigID§context: VAContextID§vpp_config: VAConfigID§vpp_context: VAContextID§vpp_standards: (VAProcColorStandardType, VAProcColorStandardType)The color standard the video processor is told to convert from and to.
negotiated: Negotiated§fourcc: u32§rt_format: u32§surface_width: u32§surface_height: u32§low_power: bool§recon: Vec<VASurfaceID>The reconstruction surfaces, one more than the frames the decoder holds.
converted: Vec<VASurfaceID>The converted picture the encoder reads.
host: Option<HostUpload>§imports: Vec<(i32, DmaBufIdentity, VASurfaceID)>The surface over each dmabuf a zero-copy session encoded, by fd, oldest first, at most
DMABUF_IMPORTS (dmabuf_surface).
coded: VABufferID§arm: Arm§references: Option<References>§frame_count: u64The frames encoded and the count at the last key frame, which a session that tracks no references keeps itself; a tracked one keeps both in its references.
key_count: u64§surfaces_of: HashMap<u64, VASurfaceID>The surface each held frame was reconstructed into, by timestamp.
last_reference: Reference§rate: RateSettings§qp: u32§held: Option<u32>The quantizer the next frame is held at (hold_quantizer).
refinement: Option<Refinement>The blocks the next frame of the rate control’s refines (refine_blocks), and the
regions of interest of the frame being issued (roi_parameter).
roi: Vec<VAEncROI>§frame_cap: boolWhether the driver caps each coded frame at the size a constant-rate session names.
last_bytes: Option<usize>The bytes of the last coded frame, padding aside.
cleanup_bps: Option<u32>The rate the next frame is coded at, a cleanup frame’s (cap), where it differs from the session’s.
sent_bps: u32The rate the driver was last told, by a sequence or a cleanup frame.
last_quality: Option<u32>The quality index of the average quantizer the driver reported for it.
measure: boolWhether the next frame is measured, the last measurement (last_psnr), and whether
the driver’s surfaces have been readable so far (measures).
last_psnr: Option<f32>§measures: bool§quality_level: Option<u32>The quality level asked of the driver: the highest it takes, its fastest, where libva’s level 1 is the best quality and the slowest; None where it reports none.
sequence_start: boolWhether the next frame opens a sequence: a key frame carrying the sequence parameters and the rate control.
declared_level: u32The level the last sequence named (Arm::level), which a constant-rate target taken
with a picture has to stay within.
omit_headers: bool§fresh: bool§reorder: NoReorderThe reorder bound the H.264 stream is held to. A driver may write its own sequence parameter set in place of the session’s (radeonsi’s VCE did before Mesa 25.0, declaring no restriction or a depth of three), and the session submits every picture in the order it is shown, so the bound is written whatever the driver’s picture order count.
Implementations§
Source§impl VaapiEncoder
impl VaapiEncoder
Sourcepub fn new(
settings: &CaptureSettings,
codec: Codec,
input: Input,
) -> Result<Self, String>
pub fn new( settings: &CaptureSettings, codec: Codec, input: Input, ) -> Result<Self, String>
Stand up a session for codec on the render node the settings select, fed through
input, with the libva of this process.
Sourcepub(crate) fn on_device(
device: Arc<Device>,
settings: &CaptureSettings,
codec: Codec,
input: Input,
) -> Result<Self, String>
pub(crate) fn on_device( device: Arc<Device>, settings: &CaptureSettings, codec: Codec, input: Input, ) -> Result<Self, String>
new on an open device.
Sourcefn open(
device: &Arc<Device>,
settings: &CaptureSettings,
codec: Codec,
input: Input,
profile: VAProfile,
entrypoint: VAEntrypoint,
fourcc: u32,
fullcolor: bool,
bit_depth: u32,
) -> Result<Self, String>
fn open( device: &Arc<Device>, settings: &CaptureSettings, codec: Codec, input: Input, profile: VAProfile, entrypoint: VAEntrypoint, fourcc: u32, fullcolor: bool, bit_depth: u32, ) -> Result<Self, String>
One bring-up on fourcc surfaces: the encode configuration and its attributes, the
surfaces, the encode and processing contexts, and the codec arm.
Source§impl VaapiEncoder
impl VaapiEncoder
Sourcefn open_vpp(&mut self, device: &Device, input: Input) -> Result<(), String>
fn open_vpp(&mut self, device: &Device, input: Input) -> Result<(), String>
The video processor: a configuration and a context on the converted surface, and the
color standards it is told to convert between, chosen the way libavfilter’s scale_vaapi
chooses them: explicit color properties where the driver takes them, else the standard
nearest to the matrix and range asked for.
Sourcefn declared_color(&self) -> ColorDescription
fn declared_color(&self) -> ColorDescription
The color the session declares: BT.709, whose primaries and transfer the sRGB desktop source already carries, at limited range; VP8 is held to BT.601, the only matrix its keyframe header’s one color-space bit can name.
pub fn codec(&self) -> Codec
Sourcepub fn is_fullcolor(&self) -> bool
pub fn is_fullcolor(&self) -> bool
Whether this session negotiated 4:4:4 chroma.
Sourcepub fn surface_format_name(&self) -> String
pub fn surface_format_name(&self) -> String
The name of the surface format frames reach the codec in, for the session log.
Sourcepub fn is_full_range(&self) -> bool
pub fn is_full_range(&self) -> bool
A hardware session converts at limited range.
Sourcepub fn last_reference(&self) -> Reference
pub fn last_reference(&self) -> Reference
The frame the last encoded frame predicted from.
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 (ReferenceWindow::acknowledge, ReferenceSlots::acknowledge).
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. False where the
session tracks none, and the caller codes a key frame instead.
Sourcepub fn reconfigure_rate(
&mut self,
settings: &CaptureSettings,
) -> Result<(), String>
pub fn reconfigure_rate( &mut self, settings: &CaptureSettings, ) -> Result<(), String>
Take a rate or frame-rate change. A constant-rate target that moved alone goes out with
the next picture’s rate control, as a still screen’s cleanup rate does (encode), so
congestion control steering the target costs no key frame. Any other change, or a target
the declared level does not admit, opens a sequence with the new rate control, as a key
frame: the decoder learns a level only from a sequence header.
Sourcepub fn last_size(&self) -> Option<usize>
pub fn last_size(&self) -> Option<usize>
The bytes of the last frame coded, the driver’s padding aside: what tells a constant-rate cleanup the rate control has nothing left to refine.
Sourcepub fn last_quality(&self) -> Option<u32>
pub fn last_quality(&self) -> Option<u32>
The quality index the rate control last coded a frame at: for H.264 and HEVC where the
driver reports a picture’s average quantizer with its coded buffer (iHD does), for AV1
and VP9 the base_q_idx it wrote into the frame header. A picture that is mostly skipped
blocks reports near the quantizer its slices open at, so the figure is trusted for
having reached a quality, never for the lack of it.
Sourcepub fn measures(&self) -> bool
pub fn measures(&self) -> bool
Whether measure yields a measurement: until a surface turns out unreadable, as the
reconstruction of iHD’s packed 4:4:4 does, kept at another geometry than its source.
Sourcepub fn measure(&mut self)
pub fn measure(&mut self)
Measure the next frame’s reconstruction against its source (last_psnr).
Sourcepub fn last_psnr(&self) -> Option<f32>
pub fn last_psnr(&self) -> Option<f32>
The luma PSNR, in dB, of the last frame measured: its reconstruction against the
converted picture it was coded from, both read back on every PSNR_ROW_STEPth row.
What tells a constant-rate cleanup whether the driver’s rate control is still refining
a still screen, whatever the driver says of its quantizer; None where a surface cannot
be read as the picture’s rows.
Sourcefn luma_rows(&self, surface: VASurfaceID) -> Option<(u32, u16, Vec<u8>)>
fn luma_rows(&self, surface: VASurfaceID) -> Option<(u32, u16, Vec<u8>)>
The sampled luma rows of surface, as 8-bit samples (the high eight bits of a 10-bit
one), with the format and the rows the driver keeps it in.
Sourcefn picture_psnr(&self, recon: VASurfaceID) -> Option<f32>
fn picture_psnr(&self, recon: VASurfaceID) -> Option<f32>
The luma PSNR of recon against the converted picture, over the sampled rows; None
where the driver keeps the reconstruction in another layout than the source, which
would read as noise: iHD’s of 10-bit HEVC and VP9 reports P016 for p010, its packed
4:4:4 one fewer rows, and either measured under UNREADABLE_DB.
Sourcefn constant_rate(&self) -> ConstantRate
fn constant_rate(&self) -> ConstantRate
How this driver’s rate control is bounded (ConstantRate).
Sourcepub fn ends_cleanup_on_key(&self) -> bool
pub fn ends_cleanup_on_key(&self) -> bool
Whether a constant-rate cleanup ends on a key frame held at the paint-over quantizer
(FrameEncoder::ends_cleanup_on_key): where the driver says no quantizer of its H.264 or
HEVC frames (radeonsi) and the session’s frame budget is under
REFINE_BITS_PER_PIXEL (refines).
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): at
a constant rate, where the driver takes a new target with a picture.
Sourcepub fn cap(&mut self, bytes: usize)
pub fn cap(&mut self, bytes: usize)
Code the next frame, a still screen’s cleanup, at the rate that spends bytes in
pipeline::CLEANUP_FRAME_S, and its buffer as long as the session’s
(rate_control_at); the frame after goes back to the session’s rate. The session’s own
rate holds a 1080p page at 60 fps 0.5 Mbit/s to frames of 1 kB, which refine nothing
(18 dB), where a cleanup at a 2 Mbit/s path’s rate reaches 52 dB.
Sourcepub fn refines(&self) -> Option<Refiner>
pub fn refines(&self) -> Option<Refiner>
Encode the next frame at the quantizer the quality index crf selects, and leave the
session’s own quantizer for the frame after: the cleanup of a still screen, at a constant
quantizer. A constant-rate session codes the frame under its rate control: radeonsi drops
per-frame quantizer bounds (a key frame held by them came out starved in the session’s
small buffer, 26 dB), and a key frame given a budget of its own through a restarted rate
control came out coarser than the picture the driver’s rate control refines a still
screen to by itself (51 against 61 dB at 8 Mbit/s), so FrameEncoder::holds_quantizer
says no there. A key frame held there, the cleanup of a session whose rate control
cannot refine (ends_cleanup_on_key), is coded with the budget held_key_bits gives it,
sent with the picture.
How the session refines blocks of a frame of its rate control’s (refine_blocks): an
H.264 session whose driver takes regions of interest with a quantizer delta, one region a
run of blocks along a row (Negotiated::roi_regions), each at most REFINE_REACH steps
off the frame’s quality. HEVC takes none: on Intel’s iHD (N97) refined regions took 1080p
text beside a video from 41.4 dB to 25.4 at 8 Mbit/s and the video from 34.7 to 30.3, and
from 47.6 to 44.5 at a constant quantizer, where the driver’s HEVC path carries the
regions as a delta map it lays out wrong.
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 of the rate control’s at its target
quality, as regions of interest (roi_parameter).
Sourcefn roi_parameter(&mut self, refinement: &Refinement, out: &mut Buffers)
fn roi_parameter(&mut self, refinement: &Refinement, out: &mut Buffers)
The regions of interest of refinement into out: a rectangle a run of its blocks
along a row, each at the quantizer delta from the rate control’s last to the target,
within REFINE_REACH. The driver reads the rectangles through the parameter’s pointer
when the picture is issued, so they live in the session until then.
pub fn hold_quantizer(&mut self, crf: u32)
Sourcefn rate_control_at(&self, out: &mut Buffers, bps: u32)
fn rate_control_at(&self, out: &mut Buffers, bps: u32)
The rate control of a sequence: the target, buffer, and frame rate a constant-rate
session holds, with no filler data up to the target and each frame capped at the buffer
where the driver takes a cap and codes under one (ConstantRate), and the frame rate
and quality level of any.
Sourcepub fn encode_host(
&mut self,
pixels: &[u8],
stride: usize,
rgba: bool,
frame_number: u64,
crf: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_host( &mut self, pixels: &[u8], stride: usize, rgba: bool, frame_number: u64, crf: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
Encode one packed host frame (stride bytes per row, in the byte order the session
was built for) at the quality index crf: uploaded straight from the caller’s rows
onto the host surface and converted on the GPU.
Sourcepub fn encode_dmabuf(
&mut self,
dmabuf: &Dmabuf,
frame_number: u64,
crf: u32,
force_idr: bool,
) -> Result<Vec<u8>, String>
pub fn encode_dmabuf( &mut self, dmabuf: &Dmabuf, frame_number: u64, crf: u32, force_idr: bool, ) -> Result<Vec<u8>, String>
Encode one Wayland DRM-PRIME dmabuf: imported as a VA surface in place for the frame and converted on the GPU.
Sourcefn dmabuf_surface(&mut self, dmabuf: &Dmabuf) -> Result<VASurfaceID, String>
fn dmabuf_surface(&mut self, dmabuf: &Dmabuf) -> Result<VASurfaceID, String>
The VA surface over dmabuf, imported once and kept while its fd names the same buffer
(DmaBufIdentity). A capture cycles a few buffers, and a surface made anew each frame
costs the driver a fresh bind of the buffer into the GPU’s address space on every
submission: on a discrete Arc at 1080p and 240 fps, a quarter of the capture thread’s CPU
and 0.3 ms of each encode. The surface holds its own reference to the buffer, so a dropped
capture buffer is released once its entry is evicted or the session ends.
Sourcefn forget_import(&mut self, surface: VASurfaceID)
fn forget_import(&mut self, surface: VASurfaceID)
Release the import behind surface, which a failed encode leaves in doubt.
Sourcefn import_dmabuf(&mut self, dmabuf: &Dmabuf) -> Result<VASurfaceID, String>
fn import_dmabuf(&mut self, dmabuf: &Dmabuf) -> Result<VASurfaceID, String>
A VA surface over a dmabuf: through the PRIME 2 descriptor, which carries the format modifier, else the older external-buffer one.
Sourcefn convert(&mut self, source: VASurfaceID) -> Result<(), String>
fn convert(&mut self, source: VASurfaceID) -> Result<(), String>
Convert source onto the encoder’s surface: BT.709 primaries and transfer in, full
range, the declared matrix out at limited range, chroma sited at the center of each
block, which is where the software convert puts it. The picture lands unscaled at the
origin of the aligned surface, whose margin past it the stream crops.
Trait Implementations§
Source§impl Drop for VaapiEncoder
impl Drop for VaapiEncoder
impl Send for VaapiEncoder
Auto Trait Implementations§
impl Freeze for VaapiEncoder
impl RefUnwindSafe for VaapiEncoder
impl Sync for VaapiEncoder
impl Unpin for VaapiEncoder
impl UnsafeUnpin for VaapiEncoder
impl UnwindSafe for VaapiEncoder
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> DowncastSync for T
impl<T> DowncastSync for T
§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