Skip to main content

VaapiEncoder

Struct VaapiEncoder 

Source
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: u64

The 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: bool

Whether 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: u32

The 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: bool

Whether 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: bool

Whether the next frame opens a sequence: a key frame carrying the sequence parameters and the rate control.

§declared_level: u32

The 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: NoReorder

The 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

Source

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.

Source

pub(crate) fn on_device( device: Arc<Device>, settings: &CaptureSettings, codec: Codec, input: Input, ) -> Result<Self, String>

new on an open device.

Source

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

Source

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.

Source

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.

Source

pub fn codec(&self) -> Codec

Source

pub fn is_fullcolor(&self) -> bool

Whether this session negotiated 4:4:4 chroma.

Source

pub fn bit_depth(&self) -> u32

The bits per sample the session opened at.

Source

pub fn surface_format_name(&self) -> String

The name of the surface format frames reach the codec in, for the session log.

Source

pub fn is_full_range(&self) -> bool

A hardware session converts at limited range.

Source

pub fn vendor(&self) -> &str

The driver behind the session, as libva names it.

Source

pub fn low_power(&self) -> bool

Whether the codec runs on the low-power entry point.

Source

pub fn last_reference(&self) -> Reference

The frame the last encoded frame predicted from.

Source

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).

Source

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.

Source

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.

Source

pub fn is_cbr(&self) -> bool

Whether the session runs a constant rate.

Source

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.

Source

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.

Source

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.

Source

pub fn measure(&mut self)

Measure the next frame’s reconstruction against its source (last_psnr).

Source

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.

Source

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.

Source

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.

Source

fn constant_rate(&self) -> ConstantRate

How this driver’s rate control is bounded (ConstantRate).

Source

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).

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

pub fn hold_quantizer(&mut self, crf: u32)

Source

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.

Source

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.

Source

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.

Source

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.

Source

fn forget_import(&mut self, surface: VASurfaceID)

Release the import behind surface, which a failed encode leaves in doubt.

Source

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.

Source

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.

Source

fn encode_surface( &mut self, source: VASurfaceID, frame_number: u64, crf: u32, force_idr: bool, ) -> Result<Vec<u8>, String>

Encode the picture on source: convert it, then issue the frame with its parameter buffers and packed headers, wait for it, and frame the coded bytes for the wire.

Source

fn issue(&mut self, buffers: &Buffers, out: &mut Vec<u8>) -> Result<(), String>

Render buffers as one picture on the encode context, wait for it, and append the coded bytes to out.

Trait Implementations§

Source§

impl Drop for VaapiEncoder

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for VaapiEncoder

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more