gstreamer_allocators/
drm_dumb_allocator.rs

1use std::{fmt, mem, os::unix::prelude::IntoRawFd};
2
3use glib::{prelude::*, translate::*};
4use gst::{Memory, MemoryRef};
5
6use crate::{ffi, DRMDumbAllocator, DmaBufMemory};
7
8gst::memory_object_wrapper!(
9    DRMDumbMemory,
10    DRMDumbMemoryRef,
11    gst::ffi::GstMemory,
12    |mem: &gst::MemoryRef| { unsafe { from_glib(ffi::gst_is_drm_dumb_memory(mem.as_mut_ptr())) } },
13    Memory,
14    MemoryRef
15);
16
17impl fmt::Debug for DRMDumbMemory {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        DRMDumbMemoryRef::fmt(self, f)
20    }
21}
22
23impl fmt::Debug for DRMDumbMemoryRef {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        MemoryRef::fmt(self, f)
26    }
27}
28
29impl DRMDumbMemoryRef {
30    #[doc(alias = "gst_drm_dumb_memory_get_handle")]
31    pub fn fd(&self) -> u32 {
32        skip_assert_initialized!();
33        unsafe { ffi::gst_drm_dumb_memory_get_handle(self.as_mut_ptr()) }
34    }
35
36    #[doc(alias = "gst_drm_dumb_memory_export_dmabuf")]
37    pub fn export_dmabuf(&self) -> Result<DmaBufMemory, glib::BoolError> {
38        skip_assert_initialized!();
39        unsafe {
40            Option::<DmaBufMemory>::from_glib_full(ffi::gst_drm_dumb_memory_export_dmabuf(
41                self.as_mut_ptr(),
42            ))
43            .ok_or_else(|| glib::bool_error!("Failed to export as dmabuf"))
44        }
45    }
46}
47
48impl DRMDumbAllocator {
49    /// Creates a new [`DRMDumbAllocator`][crate::DRMDumbAllocator] for the specific file desciptor. This
50    /// function can fail if the file descriptor is not a DRM device or if
51    /// the DRM device does not support DUMB allocation.
52    /// ## `drm_fd`
53    /// file descriptor of the DRM device
54    ///
55    /// # Returns
56    ///
57    /// a new DRM Dumb allocator. Use `gst_object_unref()`
58    ///  to release the allocator after usage.
59    #[doc(alias = "gst_drm_dumb_allocator_new_with_fd")]
60    #[doc(alias = "new_with_fd")]
61    pub fn with_fd<A: IntoRawFd>(drm_fd: A) -> Result<DRMDumbAllocator, glib::BoolError> {
62        assert_initialized_main_thread!();
63        unsafe {
64            Option::<gst::Allocator>::from_glib_full(ffi::gst_drm_dumb_allocator_new_with_fd(
65                drm_fd.into_raw_fd(),
66            ))
67            .map(|o| o.unsafe_cast())
68            .ok_or_else(|| glib::bool_error!("Failed to create allocator"))
69        }
70    }
71
72    /// Allocated a DRM buffer object for the specific `drm_fourcc`, `width` and
73    /// `height`. Note that the DRM Dumb allocation interface is agnostic to the
74    /// pixel format. This `drm_fourcc` is converted into a bpp (bit-per-pixel)
75    /// number and the height is scaled according to the sub-sampling.
76    /// ## `drm_fourcc`
77    /// the DRM format to allocate for
78    /// ## `width`
79    /// padded width for this allocation
80    /// ## `height`
81    /// padded height for this allocation
82    ///
83    /// # Returns
84    ///
85    /// a new DRM Dumb [`gst::Memory`][crate::gst::Memory]. Use `gst_memory_unref()`
86    ///  to release the memory after usage.
87    ///
88    /// ## `out_pitch`
89    /// the pitch as returned by the driver
90    #[doc(alias = "gst_drm_dumb_allocator_alloc")]
91    pub unsafe fn alloc(
92        &self,
93        drm_fourcc: u32,
94        width: u32,
95        height: u32,
96    ) -> Result<(gst::Memory, u32), glib::BoolError> {
97        skip_assert_initialized!();
98        let mut out_pitch = mem::MaybeUninit::uninit();
99        Option::<_>::from_glib_full(ffi::gst_drm_dumb_allocator_alloc(
100            self.to_glib_none().0,
101            drm_fourcc,
102            width,
103            height,
104            out_pitch.as_mut_ptr(),
105        ))
106        .ok_or_else(|| glib::bool_error!("Failed to allocate memory"))
107        .map(|mem| (mem, unsafe { out_pitch.assume_init() }))
108    }
109}