Skip to main content

moq_vaapi/
lib.rs

1// Copyright 2022 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Implements a lightweight and safe interface over `libva`.
6//!
7//! The starting point to using this crate is to open a [`Display`], from which a [`Context`] and
8//! [`Surface`]s can be allocated and used for doing actual work.
9
10// Most of this crate is derived from discord/cros-libva + discord/cros-codecs
11// (BSD-3-Clause). Don't subject upstream code to this workspace's strict lints;
12// the build script also emits custom `libva_*_or_higher` cfgs.
13#![allow(dead_code, unused_imports, unexpected_cfgs, mismatched_lifetime_syntaxes)]
14#![allow(clippy::all)]
15
16mod bindings;
17pub mod buffer;
18mod config;
19mod context;
20mod display;
21mod generic_value;
22mod image;
23mod picture;
24mod surface;
25mod usage_hint;
26
27// Vendored from discord/cros-codecs (BSD-3-Clause): the backend-agnostic H.264
28// bitstream layer (SPS/PPS/slice synthesis) plus a thin VA-API encode driver.
29pub mod bitstream_utils;
30pub mod codec;
31pub mod encode;
32
33pub use bindings::_VADRMPRIMESurfaceDescriptor__bindgen_ty_1 as VADRMPRIMESurfaceDescriptorObject;
34pub use bindings::_VADRMPRIMESurfaceDescriptor__bindgen_ty_2 as VADRMPRIMESurfaceDescriptorLayer;
35pub use bindings::*;
36pub use buffer::*;
37pub use config::*;
38pub use context::*;
39pub use display::*;
40pub use generic_value::*;
41pub use image::*;
42pub use picture::*;
43pub use surface::*;
44pub use usage_hint::*;
45
46/// A frame resolution in pixels. (Vendored from discord/cros-codecs, BSD-3-Clause.)
47#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
48pub struct Resolution {
49	pub width: u32,
50	pub height: u32,
51}
52
53impl Resolution {
54	/// Whether `self` can contain `other`.
55	pub fn can_contain(&self, other: Self) -> bool {
56		self.width >= other.width && self.height >= other.height
57	}
58
59	pub fn get_area(&self) -> usize {
60		(self.width as usize) * (self.height as usize)
61	}
62}
63
64impl From<(u32, u32)> for Resolution {
65	fn from(value: (u32, u32)) -> Self {
66		Self {
67			width: value.0,
68			height: value.1,
69		}
70	}
71}
72
73impl From<Resolution> for (u32, u32) {
74	fn from(value: Resolution) -> Self {
75		(value.width, value.height)
76	}
77}
78
79use std::num::NonZeroI32;
80
81/// A `VAStatus` that is guaranteed to not be `VA_STATUS_SUCCESS`.
82#[derive(Debug)]
83pub struct VaError(NonZeroI32);
84
85impl VaError {
86	/// Returns the `VAStatus` of this error.
87	pub fn va_status(&self) -> VAStatus {
88		self.0.get() as VAStatus
89	}
90}
91
92impl std::fmt::Display for VaError {
93	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94		use std::ffi::CStr;
95
96		// Safe because `vaErrorStr` will return a pointer to a statically allocated, null
97		// terminated C string. The pointer is guaranteed to never be null.
98		let err_str = unsafe { CStr::from_ptr(bindings::vaErrorStr(self.0.get())) }
99			.to_str()
100			.unwrap();
101		f.write_str(err_str)
102	}
103}
104
105impl std::error::Error for VaError {}
106
107/// Checks a VA return value and returns a `VaError` if it is not `VA_STATUS_SUCCESS`.
108///
109/// This can be used on the return value of any VA function returning `VAStatus` in order to
110/// convert it to a proper Rust `Result`.
111fn va_check(code: VAStatus) -> Result<(), VaError> {
112	match code as u32 {
113		bindings::VA_STATUS_SUCCESS => Ok(()),
114		_ => Err(VaError(unsafe { NonZeroI32::new_unchecked(code) })),
115	}
116}