]> git.nihav.org Git - nihav-player.git/blobdiff - nihed-cros-libva/src/display.rs
use NAPacketiser::attach_stream() where appropriate
[nihav-player.git] / nihed-cros-libva / src / display.rs
index f5a5b66200318985f3fc5b096acf6bfa2b609318..7cff18fa3ab6ab80fa182e669f04a3f3abc2eb6d 100644 (file)
@@ -12,9 +12,10 @@ use std::rc::Rc;
 use crate::bindings;
 use crate::config::Config;
 use crate::context::Context;
+use crate::formats::{RTFormat, VAFourcc};
 use crate::status::*;
 use crate::surface::Surface;
-use crate::UsageHint;
+use crate::UsageHints;
 
 /// Iterates over existing DRM devices.
 ///
@@ -55,6 +56,10 @@ impl Iterator for DrmDeviceIterator {
     }
 }
 
+unsafe extern "C" fn null_msg_cb(_ctx: *mut std::ffi::c_void, _message: *const std::ffi::c_char) {
+//    let msg = CStr::from_ptr(message).to_string_lossy();
+}
+
 /// A VADisplay opened over DRM.
 ///
 /// A Display is the starting point to using libva. This struct is essentially a safe wrapper over
@@ -77,6 +82,9 @@ impl Display {
     ///
     /// `path` is the path to a DRM device that supports VAAPI, e.g. `/dev/dri/renderD128`.
     pub fn open_drm_display<P: AsRef<Path>>(path: P) -> VAResult<Rc<Self>> {
+        Self::open_drm_display_internal(path, false)
+    }
+    fn open_drm_display_internal<P: AsRef<Path>>(path: P, silent: bool) -> VAResult<Rc<Self>> {
         let file = std::fs::File::options()
             .read(true)
             .write(true)
@@ -91,12 +99,26 @@ impl Display {
             return Err(VAError::InvalidDisplay);
         }
 
+        if silent {
+            // Safe because we ensure that the display is valid (i.e not NULL) before call.
+            unsafe {
+                bindings::vaSetInfoCallback(display, Some(null_msg_cb), std::ptr::null_mut());
+            }
+        }
+
         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.
         (unsafe { bindings::vaInitialize(display, &mut major, &mut minor) }).check()?;
 
+        if silent {
+            // Safe because we ensure that the display is valid (i.e not NULL) before call.
+            unsafe {
+                bindings::vaSetInfoCallback(display, None, std::ptr::null_mut());
+            }
+        }
+
         Ok(Rc::new(Self {
             handle: display,
             drm_file: file,
@@ -120,6 +142,26 @@ impl Display {
         None
     }
 
+    /// Opens the first device that succeeds and returns its `Display`.
+    ///
+    /// The only difference from ordinary `open` is that it does not print debug information
+    /// about libva version and opened driver.
+    ///
+    /// If an error occurs on a given device, it is ignored and the next one is tried until one
+    /// succeeds or we reach the end of the iterator.
+    pub fn open_silently() -> Option<Rc<Self>> {
+        let devices = DrmDeviceIterator::default();
+
+        // Try all the DRM devices until one succeeds.
+        for device in devices {
+            if let Ok(display) = Self::open_drm_display_internal(device, true) {
+                return Some(display);
+            }
+        }
+
+        None
+    }
+
     /// Returns the handle of this display.
     pub(crate) fn handle(&self) -> bindings::VADisplay {
         self.handle
@@ -230,7 +272,7 @@ impl Display {
     ///
     /// # Arguments
     ///
-    /// * `rt_format` - The desired surface format. See `VA_RT_FORMAT_*`
+    /// * `rt_format` - The desired surface format.
     /// * `va_fourcc` - The desired pixel format (optional). See `VA_FOURCC_*`
     /// * `width` - Width for the create surfaces
     /// * `height` - Height for the created surfaces
@@ -238,11 +280,11 @@ impl Display {
     /// * `num_surfaces` - Number of surfaces to create
     pub fn create_surfaces(
         self: &Rc<Self>,
-        rt_format: u32,
-        va_fourcc: Option<u32>,
+        rt_format: RTFormat,
+        va_fourcc: Option<VAFourcc>,
         width: u32,
         height: u32,
-        usage_hint: Option<UsageHint>,
+        usage_hints: Option<UsageHints>,
         num_surfaces: u32,
     ) -> VAResult<Vec<Surface>> {
         Surface::new(
@@ -251,7 +293,7 @@ impl Display {
             va_fourcc,
             width,
             height,
-            usage_hint,
+            usage_hints,
             num_surfaces,
         )
     }