From: Kostya Shishkov Date: Fri, 20 Oct 2023 16:33:27 +0000 (+0200) Subject: nihed-cros-libva: use simple error enum instead of anyhow crate X-Git-Url: https://git.nihav.org/?a=commitdiff_plain;h=69e6ce021284f1ebaf148b38b236068d08249e0f;p=nihav-player.git nihed-cros-libva: use simple error enum instead of anyhow crate --- diff --git a/nihed-cros-libva/Cargo.toml b/nihed-cros-libva/Cargo.toml index b709fe0..cc5096b 100644 --- a/nihed-cros-libva/Cargo.toml +++ b/nihed-cros-libva/Cargo.toml @@ -7,7 +7,6 @@ authors = ["The Chromium OS Authors", "random nobody"] edition = "2021" [dependencies] -anyhow = "1" bitflags = "1.3" [build-dependencies] diff --git a/nihed-cros-libva/src/buffer.rs b/nihed-cros-libva/src/buffer.rs index 62f8f51..3d1cceb 100644 --- a/nihed-cros-libva/src/buffer.rs +++ b/nihed-cros-libva/src/buffer.rs @@ -16,10 +16,8 @@ pub use vp9::*; use std::rc::Rc; -use anyhow::Result; - use crate::bindings; -use crate::status::Status; +use crate::status::*; use crate::Context; /// Wrapper type representing a buffer created with `vaCreateBuffer`. @@ -31,7 +29,7 @@ pub struct Buffer { impl Buffer { /// Creates a new buffer by wrapping a `vaCreateBuffer` call. This is just a helper for /// [`Context::create_buffer`]. - pub(crate) fn new(context: Rc, mut type_: BufferType) -> Result { + pub(crate) fn new(context: Rc, mut type_: BufferType) -> VAResult { let mut buffer_id = 0; let (ptr, size) = match type_ { @@ -101,7 +99,7 @@ impl Buffer { // Safe because `self` represents a valid `VAContext`. `ptr` and `size` are also ensured to // be correct, as `ptr` is just a cast to `*c_void` from a Rust struct, and `size` is // computed from `std::mem::size_of_val`. - Status(unsafe { + (unsafe { bindings::vaCreateBuffer( context.display().handle(), context.id(), @@ -132,7 +130,7 @@ impl Drop for Buffer { // Safe because `self` represents a valid buffer, created with // vaCreateBuffers. let status = - Status(unsafe { bindings::vaDestroyBuffer(self.context.display().handle(), self.id) }) + (unsafe { bindings::vaDestroyBuffer(self.context.display().handle(), self.id) }) .check(); if status.is_err() { println!("vaDestroyBuffer failed: {}", status.unwrap_err()); diff --git a/nihed-cros-libva/src/config.rs b/nihed-cros-libva/src/config.rs index af1db85..4ae3fc7 100644 --- a/nihed-cros-libva/src/config.rs +++ b/nihed-cros-libva/src/config.rs @@ -4,12 +4,10 @@ use std::rc::Rc; -use anyhow::Result; - use crate::bindings; use crate::display::Display; use crate::generic_value::GenericValue; -use crate::status::Status; +use crate::status::*; /// A configuration for a given [`Display`]. pub struct Config { @@ -25,14 +23,14 @@ impl Config { mut attrs: Vec, profile: bindings::VAProfile::Type, entrypoint: bindings::VAEntrypoint::Type, - ) -> Result { + ) -> VAResult { let mut config_id = 0u32; // Safe because `self` represents a valid `VADisplay`. // // The `attrs` vector is also properly initialized and its actual size is passed to // `vaCreateConfig`, so it is impossible to write past the end of its storage by mistake. - Status(unsafe { + (unsafe { bindings::vaCreateConfig( display.handle(), profile, @@ -60,12 +58,12 @@ impl Config { // This function queries for all supported attributes for this configuration. In particular, if // the underlying hardware supports the creation of VA surfaces in various formats, then this // function will enumerate all pixel formats that are supported. - fn query_surface_attributes(&mut self) -> Result> { + fn query_surface_attributes(&mut self) -> VAResult> { // Safe because `self` represents a valid VAConfig. We first query how // much space is needed by the C API by passing in NULL in the first // call to `vaQuerySurfaceAttributes`. let attrs_len: std::os::raw::c_uint = 0; - Status(unsafe { + (unsafe { bindings::vaQuerySurfaceAttributes( self.display.handle(), self.id, @@ -79,7 +77,7 @@ impl Config { // Safe because we allocate a vector with the required capacity as // returned by the initial call to vaQuerySurfaceAttributes. We then // pass a valid pointer to it. - Status(unsafe { + (unsafe { bindings::vaQuerySurfaceAttributes( self.display.handle(), self.id, @@ -103,7 +101,7 @@ impl Config { pub fn query_surface_attributes_by_type( &mut self, attr_type: bindings::VASurfaceAttribType::Type, - ) -> Result> { + ) -> VAResult> { let surface_attributes = self.query_surface_attributes()?; surface_attributes @@ -118,7 +116,7 @@ impl Drop for Config { fn drop(&mut self) { // Safe because `self` represents a valid Config. let status = - Status(unsafe { bindings::vaDestroyConfig(self.display.handle(), self.id) }).check(); + (unsafe { bindings::vaDestroyConfig(self.display.handle(), self.id) }).check(); if status.is_err() { println!("vaDestroyConfig failed: {}", status.unwrap_err()); } diff --git a/nihed-cros-libva/src/context.rs b/nihed-cros-libva/src/context.rs index cc3136a..7d42917 100644 --- a/nihed-cros-libva/src/context.rs +++ b/nihed-cros-libva/src/context.rs @@ -4,13 +4,11 @@ use std::rc::Rc; -use anyhow::Result; - use crate::bindings; use crate::buffer::Buffer; use crate::buffer::BufferType; use crate::display::Display; -use crate::status::Status; +use crate::status::*; use crate::Config; use crate::Surface; @@ -30,7 +28,7 @@ impl Context { coded_height: i32, surfaces: Option<&Vec>, progressive: bool, - ) -> Result> { + ) -> VAResult> { let mut context_id = 0; let flags = if progressive { bindings::constants::VA_PROGRESSIVE as i32 @@ -46,7 +44,7 @@ impl Context { // Safe because `self` represents a valid VADisplay and render_targets // and ntargets are properly initialized. Note that render_targets==NULL // is valid so long as ntargets==0. - Status(unsafe { + (unsafe { bindings::vaCreateContext( display.handle(), config.id(), @@ -77,7 +75,7 @@ impl Context { } /// Create a new buffer of type `type_`. - pub fn create_buffer(self: &Rc, type_: BufferType) -> Result { + pub fn create_buffer(self: &Rc, type_: BufferType) -> VAResult { Buffer::new(Rc::clone(self), type_) } } @@ -86,7 +84,7 @@ impl Drop for Context { fn drop(&mut self) { // Safe because `self` represents a valid VAContext. let status = - Status(unsafe { bindings::vaDestroyContext(self.display.handle(), self.id) }).check(); + (unsafe { bindings::vaDestroyContext(self.display.handle(), self.id) }).check(); if status.is_err() { println!("vaDestroyContext failed: {}", status.unwrap_err()); } diff --git a/nihed-cros-libva/src/display.rs b/nihed-cros-libva/src/display.rs index 462bc3e..f5a5b66 100644 --- a/nihed-cros-libva/src/display.rs +++ b/nihed-cros-libva/src/display.rs @@ -9,14 +9,10 @@ use std::path::Path; use std::path::PathBuf; use std::rc::Rc; -use anyhow::anyhow; -use anyhow::Context as AnyhowContext; -use anyhow::Result; - use crate::bindings; use crate::config::Config; use crate::context::Context; -use crate::status::Status; +use crate::status::*; use crate::surface::Surface; use crate::UsageHint; @@ -80,29 +76,26 @@ impl Display { /// Opens and initializes a specific DRM `Display`. /// /// `path` is the path to a DRM device that supports VAAPI, e.g. `/dev/dri/renderD128`. - pub fn open_drm_display>(path: P) -> Result> { + pub fn open_drm_display>(path: P) -> VAResult> { let file = std::fs::File::options() .read(true) .write(true) .open(path.as_ref()) - .context(format!("failed to open {}", path.as_ref().display()))?; + .map_err(|_| VAError::InvalidValue)?; // Safe because fd represents a valid file descriptor and the pointer is checked for // NULL afterwards. let display = unsafe { bindings::vaGetDisplayDRM(file.as_raw_fd()) }; if display.is_null() { // The File will close the DRM fd on drop. - return Err(anyhow!( - "failed to obtain VA display from DRM device {}", - path.as_ref().display() - )); + return Err(VAError::InvalidDisplay); } let mut major = 0i32; let mut minor = 0i32; // Safe because we ensure that the display is valid (i.e not NULL) before calling // vaInitialize. The File will close the DRM fd on drop. - Status(unsafe { bindings::vaInitialize(display, &mut major, &mut minor) }).check()?; + (unsafe { bindings::vaInitialize(display, &mut major, &mut minor) }).check()?; Ok(Rc::new(Self { handle: display, @@ -133,14 +126,14 @@ impl Display { } /// Queries supported profiles by this display. - pub fn query_config_profiles(&self) -> Result> { + pub fn query_config_profiles(&self) -> VAResult> { // Safe because `self` represents a valid VADisplay. let mut max_num_profiles = unsafe { bindings::vaMaxNumProfiles(self.handle) }; let mut profiles = Vec::with_capacity(max_num_profiles as usize); // Safe because `self` represents a valid `VADisplay` and the vector has `max_num_profiles` // as capacity. - Status(unsafe { + (unsafe { bindings::vaQueryConfigProfiles( self.handle, profiles.as_mut_ptr(), @@ -182,14 +175,14 @@ impl Display { pub fn query_config_entrypoints( &self, profile: bindings::VAProfile::Type, - ) -> Result> { + ) -> VAResult> { // Safe because `self` represents a valid VADisplay. let mut max_num_entrypoints = unsafe { bindings::vaMaxNumEntrypoints(self.handle) }; let mut entrypoints = Vec::with_capacity(max_num_entrypoints as usize); // Safe because `self` represents a valid VADisplay and the vector has `max_num_entrypoints` // as capacity. - Status(unsafe { + (unsafe { bindings::vaQueryConfigEntrypoints( self.handle, profile, @@ -218,10 +211,10 @@ impl Display { profile: bindings::VAProfile::Type, entrypoint: bindings::VAEntrypoint::Type, attributes: &mut [bindings::VAConfigAttrib], - ) -> Result<()> { + ) -> VAResult<()> { // Safe because `self` represents a valid VADisplay. The slice length is passed to the C // function, so it is impossible to write past the end of the slice's storage by mistake. - Status(unsafe { + (unsafe { bindings::vaGetConfigAttributes( self.handle, profile, @@ -251,7 +244,7 @@ impl Display { height: u32, usage_hint: Option, num_surfaces: u32, - ) -> Result> { + ) -> VAResult> { Surface::new( Rc::clone(self), rt_format, @@ -279,7 +272,7 @@ impl Display { coded_height: i32, surfaces: Option<&Vec>, progressive: bool, - ) -> Result> { + ) -> VAResult> { Context::new( Rc::clone(self), config, @@ -301,12 +294,12 @@ impl Display { attrs: Vec, profile: bindings::VAProfile::Type, entrypoint: bindings::VAEntrypoint::Type, - ) -> Result { + ) -> VAResult { Config::new(Rc::clone(self), attrs, profile, entrypoint) } /// Returns available image formats for this display by wrapping around `vaQueryImageFormats`. - pub fn query_image_formats(&self) -> Result> { + pub fn query_image_formats(&self) -> VAResult> { // Safe because `self` represents a valid VADisplay. let mut num_image_formats = unsafe { bindings::vaMaxNumImageFormats(self.handle) }; let mut image_formats = Vec::with_capacity(num_image_formats as usize); @@ -314,7 +307,7 @@ impl Display { // Safe because `self` represents a valid VADisplay. The `image_formats` vector is properly // initialized and a valid size is passed to the C function, so it is impossible to write // past the end of their storage by mistake. - Status(unsafe { + (unsafe { bindings::vaQueryImageFormats( self.handle, image_formats.as_mut_ptr(), diff --git a/nihed-cros-libva/src/generic_value.rs b/nihed-cros-libva/src/generic_value.rs index 3900edc..989773d 100644 --- a/nihed-cros-libva/src/generic_value.rs +++ b/nihed-cros-libva/src/generic_value.rs @@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use anyhow::anyhow; -use anyhow::Result; - use crate::bindings; +use crate::status::VAError; /// A wrapper over `VAGenericValue` giving us safe access to the underlying union members. #[derive(Debug)] @@ -21,7 +19,7 @@ pub enum GenericValue { } impl TryFrom for GenericValue { - type Error = anyhow::Error; + type Error = VAError; fn try_from(value: bindings::VAGenericValue) -> Result { // Safe because we check the type before accessing the union. @@ -39,10 +37,7 @@ impl TryFrom for GenericValue { bindings::VAGenericValueType::VAGenericValueTypeFunc => { Ok(Self::Func(unsafe { value.value.fn_ })) } - other => Err(anyhow!( - "Conversion failed for unexpected VAGenericValueType: {}", - other - )), + _other => Err(VAError::InvalidValue), } } } diff --git a/nihed-cros-libva/src/image.rs b/nihed-cros-libva/src/image.rs index 8044145..f40059e 100644 --- a/nihed-cros-libva/src/image.rs +++ b/nihed-cros-libva/src/image.rs @@ -2,12 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use anyhow::Result; - use crate::bindings; use crate::picture::Picture; use crate::picture::PictureSync; -use crate::status::Status; +use crate::status::*; /// Wrapper around `VAImage` that is tied to the lifetime of a given `Picture`. /// @@ -50,7 +48,7 @@ impl<'a> Image<'a> { width: u32, height: u32, derive: bool, - ) -> Result { + ) -> VAResult { // An all-zero byte-pattern is a valid initial value for `VAImage`. let mut image: bindings::VAImage = Default::default(); let mut addr = std::ptr::null_mut(); @@ -66,7 +64,7 @@ impl<'a> Image<'a> { // Safe since `picture.inner.context` represents a valid `VAContext` and `image` has been // successfully created at this point. - match Status(unsafe { + match (unsafe { bindings::vaMapBuffer(picture.display().handle(), image.buf, &mut addr) }) .check() @@ -104,18 +102,18 @@ impl<'a> Image<'a> { format: &mut bindings::VAImageFormat, width: u32, height: u32, - ) -> Result<()> { + ) -> VAResult<()> { let dpy = picture.display().handle(); // Safe because `picture.inner.context` represents a valid // VAContext. - Status(unsafe { bindings::vaCreateImage(dpy, format, width as i32, height as i32, image) }) + (unsafe { bindings::vaCreateImage(dpy, format, width as i32, height as i32, image) }) .check()?; // Safe because `picture.inner.context` represents a valid VAContext, // `picture.surface` represents a valid VASurface and `image` represents // a valid `VAImage`. - if let Err(e) = Status(unsafe { + if let Err(e) = (unsafe { bindings::vaGetImage( dpy, picture.surface().id(), @@ -146,12 +144,12 @@ impl<'a> Image<'a> { fn derive_image( picture: &'a Picture, image: &mut bindings::VAImage, - ) -> Result { - let status = Status(unsafe { + ) -> VAResult { + let status = unsafe { bindings::vaDeriveImage(picture.display().handle(), picture.surface().id(), image) - }); + }; - if status.0 == bindings::constants::VA_STATUS_ERROR_OPERATION_FAILED as i32 { + if status == bindings::constants::VA_STATUS_ERROR_OPERATION_FAILED as i32 { // The implementation can't derive, try the create API instead. Ok(false) } else { diff --git a/nihed-cros-libva/src/lib.rs b/nihed-cros-libva/src/lib.rs index 8747b2b..83b459a 100644 --- a/nihed-cros-libva/src/lib.rs +++ b/nihed-cros-libva/src/lib.rs @@ -37,6 +37,7 @@ pub use display::*; pub use generic_value::*; pub use image::*; pub use picture::*; +pub use status::*; pub use surface::*; pub use usage_hint::*; diff --git a/nihed-cros-libva/src/picture.rs b/nihed-cros-libva/src/picture.rs index acb41b8..adf6a94 100644 --- a/nihed-cros-libva/src/picture.rs +++ b/nihed-cros-libva/src/picture.rs @@ -8,14 +8,11 @@ use std::cell::RefMut; use std::marker::PhantomData; use std::rc::Rc; -use anyhow::anyhow; -use anyhow::Result; - use crate::bindings; use crate::buffer::Buffer; use crate::context::Context; use crate::display::Display; -use crate::status::Status; +use crate::status::*; use crate::surface::Surface; // Use the sealed trait pattern to make sure that new states are not created in caller code. More @@ -143,10 +140,10 @@ impl Picture { } /// Wrapper around `vaBeginPicture`. - pub fn begin(self) -> Result> { + pub fn begin(self) -> VAResult> { // Safe because `self.inner.context` represents a valid VAContext and // `self.inner.surface` represents a valid VASurface. - Status(unsafe { + (unsafe { bindings::vaBeginPicture( self.inner.context.display().handle(), self.inner.context.id(), @@ -164,12 +161,12 @@ impl Picture { impl Picture { /// Wrapper around `vaRenderPicture`. - pub fn render(self) -> Result> { + pub fn render(self) -> VAResult> { // Safe because `self.inner.context` represents a valid `VAContext` and `self.inner.surface` // represents a valid `VASurface`. `buffers` point to a Rust struct and the vector length is // passed to the C function, so it is impossible to write past the end of the vector's // storage by mistake. - Status(unsafe { + (unsafe { bindings::vaRenderPicture( self.inner.context.display().handle(), self.inner.context.id(), @@ -188,9 +185,9 @@ impl Picture { impl Picture { /// Wrapper around `vaEndPicture`. - pub fn end(self) -> Result> { + pub fn end(self) -> VAResult> { // Safe because `self.inner.context` represents a valid `VAContext`. - Status(unsafe { + (unsafe { bindings::vaEndPicture( self.inner.context.display().handle(), self.inner.context.id(), @@ -206,7 +203,7 @@ impl Picture { impl Picture { /// Syncs the picture, ensuring that all pending operations are complete when this call returns. - pub fn sync(self) -> std::result::Result, (anyhow::Error, Self)> { + pub fn sync(self) -> std::result::Result, (VAError, Self)> { let res = self.inner.surface.borrow().sync(); match res { @@ -222,7 +219,7 @@ impl Picture { /// /// This call can be used to implement a non-blocking path, wherein a decoder queries the status /// of the surface after each decode operation instead of blocking on it. - pub fn query_status(&self) -> Result { + pub fn query_status(&self) -> VAResult { self.inner.surface.borrow_mut().query_status() } } @@ -252,10 +249,10 @@ impl Picture { impl Picture { /// Reclaim ownership of the Surface this picture has been created from, consuming the picture /// in the process. Useful if the Surface is part of a pool. - pub fn take_surface(self) -> Result { + pub fn take_surface(self) -> VAResult { match Rc::try_unwrap(self.inner.surface) { Ok(surface) => Ok(surface.into_inner()), - Err(_) => Err(anyhow!("Surface still in use")), + Err(_) => Err(VAError::SurfaceBusy), } } diff --git a/nihed-cros-libva/src/status.rs b/nihed-cros-libva/src/status.rs dissimilarity index 82% index 51781ab..0cf3f5b 100644 --- a/nihed-cros-libva/src/status.rs +++ b/nihed-cros-libva/src/status.rs @@ -1,30 +1,134 @@ -// Copyright 2022 The ChromiumOS Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -use std::ffi::CStr; - -use anyhow::anyhow; -use anyhow::Result; - -use crate::bindings; - -/// Wrapper over `VAStatus`, calling check() returns a Error if the status is not VA_STATUS_SUCCESS. -#[must_use = "VAStatus might not be VA_STATUS_SUCCESS."] -pub(crate) struct Status(pub bindings::VAStatus); - -impl Status { - /// Returns `Ok(())` if this status is successful, and an error otherwise. - pub(crate) fn check(&self) -> Result<()> { - if self.0 == bindings::constants::VA_STATUS_SUCCESS as i32 { - Ok(()) - } else { - // Safe because `vaErrorStr` will return a pointer to a statically allocated, null - // terminated C string. The pointer is guaranteed to never be null. - let err_str = unsafe { CStr::from_ptr(bindings::vaErrorStr(self.0)) } - .to_str() - .unwrap(); - Err(anyhow!("VA-API error: {}: {}", self.0, err_str)) - } - } -} +// Copyright 2022 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use crate::bindings; + +/// Return status. +pub type VAResult = Result; + +/// Non-successful return values of `VAStatus`. +#[derive(Clone, Copy, Debug, PartialEq)] +#[repr(u32)] +pub enum VAError { + /// Current operation has failed. + OperationFailed = bindings::constants::VA_STATUS_ERROR_OPERATION_FAILED, + /// Allocation failed. + AllocationFailed = bindings::constants::VA_STATUS_ERROR_ALLOCATION_FAILED, + /// Invalid display ID. + InvalidDisplay = bindings::constants::VA_STATUS_ERROR_INVALID_DISPLAY, + /// Invalid configuration. + InvalidConfig = bindings::constants::VA_STATUS_ERROR_INVALID_CONFIG, + /// Invalid context. + InvalidContext = bindings::constants::VA_STATUS_ERROR_INVALID_CONTEXT, + /// Invalid surface ID. + InvalidSurface = bindings::constants::VA_STATUS_ERROR_INVALID_SURFACE, + /// Invalid buffer. + InvalidBuffer = bindings::constants::VA_STATUS_ERROR_INVALID_BUFFER, + /// Invalid image. + InvalidImage = bindings::constants::VA_STATUS_ERROR_INVALID_IMAGE, + /// Invalid subpicture. + InvalidSubpicture = bindings::constants::VA_STATUS_ERROR_INVALID_SUBPICTURE, + /// Requested attribute is not supported. + AttrNotSupported = bindings::constants::VA_STATUS_ERROR_ATTR_NOT_SUPPORTED, + /// Maximum number of allowed elements has been exceeded. + MaxNumExceeded = bindings::constants::VA_STATUS_ERROR_MAX_NUM_EXCEEDED, + /// Unsupported codec profile. + UnsupportedProfile = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_PROFILE, + /// Unsupported entrypoint. + UnsupportedEntrypoint = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT, + /// Unsupported RT format. + UnsupportedRTFormat = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT, + /// Unsupported buffer type. + UnsupportedBuffertype = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE, + /// Surface is still being worked on. + SurfaceBusy = bindings::constants::VA_STATUS_ERROR_SURFACE_BUSY, + /// Requested flag is not supported. + FlagNotSupported = bindings::constants::VA_STATUS_ERROR_FLAG_NOT_SUPPORTED, + /// Invalid parameter. + InvalidParameter = bindings::constants::VA_STATUS_ERROR_INVALID_PARAMETER, + /// Requested resolution is not supported. + ResolutionNotSupported = bindings::constants::VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED, + /// Unimplemented feature. + Unimplemented = bindings::constants::VA_STATUS_ERROR_UNIMPLEMENTED, + /// Surface is still being displayed. + SurfaceInDisplaying = bindings::constants::VA_STATUS_ERROR_SURFACE_IN_DISPLAYING, + /// Invalid image format. + InvalidImageFormat = bindings::constants::VA_STATUS_ERROR_INVALID_IMAGE_FORMAT, + /// Generic decoding error. + DecodingError = bindings::constants::VA_STATUS_ERROR_DECODING_ERROR, + /// Generic encoding error. + EncodingError = bindings::constants::VA_STATUS_ERROR_ENCODING_ERROR, + /** + * An invalid/unsupported value was supplied. + * + * This is a catch-all error code for invalid or unsupported values. + * e.g. value exceeding the valid range, invalid type in the context + * of generic attribute values. + */ + InvalidValue = bindings::constants::VA_STATUS_ERROR_INVALID_VALUE, + /// An unsupported filter was supplied. + UnsupportedFilter = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_FILTER, + /// An invalid filter chain was supplied. + InvalidFilterChain = bindings::constants::VA_STATUS_ERROR_INVALID_FILTER_CHAIN, + /// Indicate HW busy (e.g. run multiple encoding simultaneously). + HWBusy = bindings::constants::VA_STATUS_ERROR_HW_BUSY, + /// An unsupported memory type was supplied. + UnsupportedMemoryType = bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE, + /// Indicate allocated buffer size is not enough for input or output + NotEnoughBuffer = bindings::constants::VA_STATUS_ERROR_NOT_ENOUGH_BUFFER, + /// Operation has timed out. + Timedout = bindings::constants::VA_STATUS_ERROR_TIMEDOUT, + /// Unknown error. + Unknown = bindings::constants::VA_STATUS_ERROR_UNKNOWN, +} + +impl std::fmt::Display for VAError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +pub(crate) trait ConvertStatus { + fn check(self) -> VAResult<()>; +} + +impl ConvertStatus for bindings::VAStatus { + fn check(self) -> VAResult<()> { + match self as u32 { + bindings::constants::VA_STATUS_SUCCESS => Ok(()), + bindings::constants::VA_STATUS_ERROR_OPERATION_FAILED => Err(VAError::OperationFailed), + bindings::constants::VA_STATUS_ERROR_ALLOCATION_FAILED => Err(VAError::AllocationFailed), + bindings::constants::VA_STATUS_ERROR_INVALID_DISPLAY => Err(VAError::InvalidDisplay), + bindings::constants::VA_STATUS_ERROR_INVALID_CONFIG => Err(VAError::InvalidConfig), + bindings::constants::VA_STATUS_ERROR_INVALID_CONTEXT => Err(VAError::InvalidContext), + bindings::constants::VA_STATUS_ERROR_INVALID_SURFACE => Err(VAError::InvalidSurface), + bindings::constants::VA_STATUS_ERROR_INVALID_BUFFER => Err(VAError::InvalidBuffer), + bindings::constants::VA_STATUS_ERROR_INVALID_IMAGE => Err(VAError::InvalidImage), + bindings::constants::VA_STATUS_ERROR_INVALID_SUBPICTURE => Err(VAError::InvalidSubpicture), + bindings::constants::VA_STATUS_ERROR_ATTR_NOT_SUPPORTED => Err(VAError::AttrNotSupported), + bindings::constants::VA_STATUS_ERROR_MAX_NUM_EXCEEDED => Err(VAError::MaxNumExceeded), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_PROFILE => Err(VAError::UnsupportedProfile), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT => Err(VAError::UnsupportedEntrypoint), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT => Err(VAError::UnsupportedRTFormat), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE => Err(VAError::UnsupportedBuffertype), + bindings::constants::VA_STATUS_ERROR_SURFACE_BUSY => Err(VAError::SurfaceBusy), + bindings::constants::VA_STATUS_ERROR_FLAG_NOT_SUPPORTED => Err(VAError::FlagNotSupported), + bindings::constants::VA_STATUS_ERROR_INVALID_PARAMETER => Err(VAError::InvalidParameter), + bindings::constants::VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED => Err(VAError::ResolutionNotSupported), + bindings::constants::VA_STATUS_ERROR_UNIMPLEMENTED => Err(VAError::Unimplemented), + bindings::constants::VA_STATUS_ERROR_SURFACE_IN_DISPLAYING => Err(VAError::SurfaceInDisplaying), + bindings::constants::VA_STATUS_ERROR_INVALID_IMAGE_FORMAT => Err(VAError::InvalidImageFormat), + bindings::constants::VA_STATUS_ERROR_DECODING_ERROR => Err(VAError::DecodingError), + bindings::constants::VA_STATUS_ERROR_ENCODING_ERROR => Err(VAError::EncodingError), + bindings::constants::VA_STATUS_ERROR_INVALID_VALUE => Err(VAError::InvalidValue), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_FILTER => Err(VAError::UnsupportedFilter), + bindings::constants::VA_STATUS_ERROR_INVALID_FILTER_CHAIN => Err(VAError::InvalidFilterChain), + bindings::constants::VA_STATUS_ERROR_HW_BUSY => Err(VAError::HWBusy), + bindings::constants::VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE => Err(VAError::UnsupportedMemoryType), + bindings::constants::VA_STATUS_ERROR_NOT_ENOUGH_BUFFER => Err(VAError::NotEnoughBuffer), + bindings::constants::VA_STATUS_ERROR_TIMEDOUT => Err(VAError::Timedout), + _ => Err(VAError::Unknown), + } + } +} diff --git a/nihed-cros-libva/src/surface.rs b/nihed-cros-libva/src/surface.rs index 8c626ce..d16fedc 100644 --- a/nihed-cros-libva/src/surface.rs +++ b/nihed-cros-libva/src/surface.rs @@ -4,11 +4,9 @@ use std::rc::Rc; -use anyhow::Result; - use crate::bindings; use crate::display::Display; -use crate::status::Status; +use crate::status::*; use crate::UsageHint; /// An owned VA surface that is tied to the lifetime of a particular VADisplay @@ -30,7 +28,7 @@ impl Surface { height: u32, usage_hint: Option, num_surfaces: u32, - ) -> Result> { + ) -> VAResult> { let mut attrs = vec![]; if let Some(usage_hint) = usage_hint { @@ -66,7 +64,7 @@ impl Surface { // Safe because `self` represents a valid VADisplay. The `surface` and `attrs` vectors are // properly initialized and valid sizes are passed to the C function, so it is impossible to // write past the end of their storage by mistake. - Status(unsafe { + (unsafe { bindings::vaCreateSurfaces( display.handle(), rt_format, @@ -101,9 +99,9 @@ impl Surface { /// Blocks until all pending operations on the render target have been completed. Upon return it /// is safe to use the render target for a different picture. - pub fn sync(&self) -> Result<()> { + pub fn sync(&self) -> VAResult<()> { // Safe because `self` represents a valid VASurface. - Status(unsafe { bindings::vaSyncSurface(self.display.handle(), self.id) }).check() + (unsafe { bindings::vaSyncSurface(self.display.handle(), self.id) }).check() } /// Convenience function to return a VASurfaceID vector. Useful to interface with the C API @@ -113,10 +111,10 @@ impl Surface { } /// Wrapper over `vaQuerySurfaceStatus` to find out any pending ops on the render target. - pub fn query_status(&self) -> Result { + pub fn query_status(&self) -> VAResult { let mut status: bindings::VASurfaceStatus::Type = 0; // Safe because `self` represents a valid VASurface. - Status(unsafe { + (unsafe { bindings::vaQuerySurfaceStatus(self.display.handle(), self.id, &mut status) }) .check()?;