1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::{fmt, os::unix::prelude::RawFd};

use glib::{prelude::*, translate::*};
use gst::{Memory, MemoryRef};

use crate::{ffi, FdAllocator, FdMemoryFlags};

gst::memory_object_wrapper!(
    FdMemory,
    FdMemoryRef,
    gst::ffi::GstMemory,
    |mem: &gst::MemoryRef| { unsafe { from_glib(ffi::gst_is_fd_memory(mem.as_mut_ptr())) } },
    Memory,
    MemoryRef,
);

impl fmt::Debug for FdMemory {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        FdMemoryRef::fmt(self, f)
    }
}

impl fmt::Debug for FdMemoryRef {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("FdMemory")
            .field("ptr", &self.as_ptr())
            .field("allocator", &self.allocator())
            .field("parent", &self.parent())
            .field("maxsize", &self.maxsize())
            .field("align", &self.align())
            .field("offset", &self.offset())
            .field("size", &self.size())
            .field("flags", &self.flags())
            .field("fd", &self.fd())
            .finish()
    }
}

impl FdMemoryRef {
    #[doc(alias = "gst_fd_memory_get_fd")]
    pub fn fd(&self) -> RawFd {
        skip_assert_initialized!();
        unsafe { ffi::gst_fd_memory_get_fd(self.as_mut_ptr()) }
    }
}

impl FdAllocator {
    /// Return a `GstMemory` that wraps a generic file descriptor.
    /// ## `allocator`
    /// allocator to be used for this memory
    /// ## `fd`
    /// file descriptor
    /// ## `size`
    /// memory size
    /// ## `flags`
    /// extra [`FdMemoryFlags`][crate::FdMemoryFlags]
    ///
    /// # Returns
    ///
    /// a GstMemory based on `allocator`.
    /// When the buffer will be released the allocator will close the `fd` unless
    /// the [`FdMemoryFlags::DONT_CLOSE`][crate::FdMemoryFlags::DONT_CLOSE] flag is specified.
    /// The memory is only mmapped on [`gst::Buffer::map()`][crate::gst::Buffer::map()] request.
    #[doc(alias = "gst_fd_allocator_alloc")]
    pub unsafe fn alloc(
        &self,
        fd: RawFd,
        size: usize,
        flags: FdMemoryFlags,
    ) -> Result<gst::Memory, glib::BoolError> {
        skip_assert_initialized!();
        Option::<_>::from_glib_full(ffi::gst_fd_allocator_alloc(
            self.unsafe_cast_ref::<gst::Allocator>().to_glib_none().0,
            fd,
            size,
            flags.into_glib(),
        ))
        .ok_or_else(|| glib::bool_error!("Failed to allocate memory"))
    }
}