1use std::sync::Arc;
6
7use log::error;
8use thiserror::Error;
9
10use crate::bindings;
11use crate::display::Display;
12use crate::generic_value::GenericValue;
13use crate::va_check;
14use crate::GenericValueError;
15use crate::VaError;
16
17pub struct Config {
19 display: Arc<Display>,
20 id: bindings::VAConfigID,
21}
22
23#[derive(Debug, Error)]
24pub enum QuerySurfaceAttributesError {
25 #[error("error while calling vaQuerySurfaceAttributes: {0}")]
26 VaError(#[from] VaError),
27 #[error("error while converting attribute: {0}")]
28 GenericValueError(#[from] GenericValueError),
29}
30
31impl Config {
32 pub(crate) fn new(
35 display: Arc<Display>,
36 mut attrs: Vec<bindings::VAConfigAttrib>,
37 profile: bindings::VAProfile::Type,
38 entrypoint: bindings::VAEntrypoint::Type,
39 ) -> Result<Self, VaError> {
40 let mut config_id = 0u32;
41
42 va_check(unsafe {
47 bindings::vaCreateConfig(
48 display.handle(),
49 profile,
50 entrypoint,
51 attrs.as_mut_ptr(),
52 attrs.len() as i32,
53 &mut config_id,
54 )
55 })?;
56
57 Ok(Self { display, id: config_id })
58 }
59
60 pub(crate) fn id(&self) -> bindings::VAConfigID {
62 self.id
63 }
64
65 fn query_surface_attributes(&mut self) -> Result<Vec<bindings::VASurfaceAttrib>, VaError> {
71 let attrs_len: std::os::raw::c_uint = 0;
75 va_check(unsafe {
76 bindings::vaQuerySurfaceAttributes(
77 self.display.handle(),
78 self.id,
79 std::ptr::null_mut(),
80 &attrs_len as *const _ as *mut std::os::raw::c_uint,
81 )
82 })?;
83
84 let mut attrs = Vec::with_capacity(attrs_len as usize);
85 va_check(unsafe {
89 bindings::vaQuerySurfaceAttributes(
90 self.display.handle(),
91 self.id,
92 attrs.as_mut_ptr(),
93 &attrs_len as *const _ as *mut std::os::raw::c_uint,
94 )
95 })?;
96
97 unsafe {
100 attrs.set_len(attrs_len as usize);
101 }
102
103 Ok(attrs)
104 }
105
106 pub fn query_surface_attributes_by_type(
109 &mut self,
110 attr_type: bindings::VASurfaceAttribType::Type,
111 ) -> Result<Vec<GenericValue>, QuerySurfaceAttributesError> {
112 let surface_attributes = self.query_surface_attributes()?;
113
114 surface_attributes
115 .into_iter()
116 .filter(|attr| attr.type_ == attr_type)
117 .map(|attr| GenericValue::try_from(attr.value).map_err(QuerySurfaceAttributesError::GenericValueError))
118 .collect()
119 }
120}
121
122impl Drop for Config {
123 fn drop(&mut self) {
124 let status = va_check(unsafe { bindings::vaDestroyConfig(self.display.handle(), self.id) });
126
127 if status.is_err() {
128 error!("vaDestroyConfig failed: {}", status.unwrap_err());
129 }
130 }
131}