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 decode;
32pub mod encode;
33
34pub use bindings::_VADRMPRIMESurfaceDescriptor__bindgen_ty_1 as VADRMPRIMESurfaceDescriptorObject;
35pub use bindings::_VADRMPRIMESurfaceDescriptor__bindgen_ty_2 as VADRMPRIMESurfaceDescriptorLayer;
36pub use bindings::*;
37pub use buffer::*;
38pub use config::*;
39pub use context::*;
40pub use display::*;
41pub use generic_value::*;
42pub use image::*;
43pub use picture::*;
44pub use surface::*;
45pub use usage_hint::*;
46
47/// A frame resolution in pixels. (Vendored from discord/cros-codecs, BSD-3-Clause.)
48#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
49pub struct Resolution {
50	pub width: u32,
51	pub height: u32,
52}
53
54impl Resolution {
55	/// Whether `self` can contain `other`.
56	pub fn can_contain(&self, other: Self) -> bool {
57		self.width >= other.width && self.height >= other.height
58	}
59
60	pub fn get_area(&self) -> usize {
61		(self.width as usize) * (self.height as usize)
62	}
63}
64
65impl From<(u32, u32)> for Resolution {
66	fn from(value: (u32, u32)) -> Self {
67		Self {
68			width: value.0,
69			height: value.1,
70		}
71	}
72}
73
74impl From<Resolution> for (u32, u32) {
75	fn from(value: Resolution) -> Self {
76		(value.width, value.height)
77	}
78}
79
80use std::num::NonZeroI32;
81
82/// A `VAStatus` that is guaranteed to not be `VA_STATUS_SUCCESS`.
83#[derive(Debug)]
84pub struct VaError(NonZeroI32);
85
86impl VaError {
87	/// Returns the `VAStatus` of this error.
88	pub fn va_status(&self) -> VAStatus {
89		self.0.get() as VAStatus
90	}
91}
92
93impl std::fmt::Display for VaError {
94	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95		use std::ffi::CStr;
96
97		// Safe because `vaErrorStr` will return a pointer to a statically allocated, null
98		// terminated C string. The pointer is guaranteed to never be null.
99		let err_str = unsafe { CStr::from_ptr(bindings::va().vaErrorStr(self.0.get())) }
100			.to_str()
101			.unwrap();
102		f.write_str(err_str)
103	}
104}
105
106impl std::error::Error for VaError {}
107
108/// Checks a VA return value and returns a `VaError` if it is not `VA_STATUS_SUCCESS`.
109///
110/// This can be used on the return value of any VA function returning `VAStatus` in order to
111/// convert it to a proper Rust `Result`.
112fn va_check(code: VAStatus) -> Result<(), VaError> {
113	match code as u32 {
114		bindings::VA_STATUS_SUCCESS => Ok(()),
115		_ => Err(VaError(unsafe { NonZeroI32::new_unchecked(code) })),
116	}
117}