gstreamer_video/
video_info_dma_drm.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, marker::PhantomData, mem, ops, ptr, str};
4
5use glib::translate::*;
6use gst::prelude::*;
7
8use crate::{ffi, VideoFormat, VideoInfo};
9
10#[doc(alias = "gst_video_dma_drm_fourcc_from_format")]
11pub fn dma_drm_fourcc_from_format(v: VideoFormat) -> Result<u32, glib::BoolError> {
12    skip_assert_initialized!();
13    unsafe {
14        let res = ffi::gst_video_dma_drm_fourcc_from_format(v.into_glib());
15        if res == 0 {
16            Err(glib::bool_error!("Unsupported video format"))
17        } else {
18            Ok(res)
19        }
20    }
21}
22
23#[doc(alias = "gst_video_dma_drm_fourcc_to_format")]
24pub fn dma_drm_fourcc_to_format(v: u32) -> Result<VideoFormat, glib::BoolError> {
25    skip_assert_initialized!();
26    unsafe {
27        let res = ffi::gst_video_dma_drm_fourcc_to_format(v);
28        if res == ffi::GST_VIDEO_FORMAT_UNKNOWN {
29            Err(glib::bool_error!("Unsupported fourcc"))
30        } else {
31            Ok(from_glib(res))
32        }
33    }
34}
35
36#[doc(alias = "gst_video_dma_drm_fourcc_to_string")]
37pub fn dma_drm_fourcc_to_string(fourcc: u32, modifier: u64) -> glib::GString {
38    skip_assert_initialized!();
39    unsafe {
40        glib::GString::from_glib_full(ffi::gst_video_dma_drm_fourcc_to_string(fourcc, modifier))
41    }
42}
43
44#[doc(alias = "gst_video_dma_drm_fourcc_from_string")]
45pub fn dma_drm_fourcc_from_str(v: &str) -> Result<(u32, u64), glib::BoolError> {
46    skip_assert_initialized!();
47    unsafe {
48        let mut modifier = mem::MaybeUninit::uninit();
49        let res =
50            ffi::gst_video_dma_drm_fourcc_from_string(v.to_glib_none().0, modifier.as_mut_ptr());
51        if res == 0 {
52            Err(glib::bool_error!("Can't parse fourcc string"))
53        } else {
54            Ok((res, modifier.assume_init()))
55        }
56    }
57}
58
59#[cfg(feature = "v1_26")]
60#[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
61#[doc(alias = "gst_video_dma_drm_format_from_gst_format")]
62pub fn dma_drm_format_from_gst_format(v: VideoFormat) -> Result<(u32, u64), glib::BoolError> {
63    skip_assert_initialized!();
64    unsafe {
65        let mut modifier = mem::MaybeUninit::uninit();
66        let res =
67            ffi::gst_video_dma_drm_format_from_gst_format(v.into_glib(), modifier.as_mut_ptr());
68        if res == 0 {
69            Err(glib::bool_error!("Unsupported video format"))
70        } else {
71            Ok((res, modifier.assume_init()))
72        }
73    }
74}
75
76#[cfg(feature = "v1_26")]
77#[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
78#[doc(alias = "gst_video_dma_drm_format_to_gst_format")]
79pub fn dma_drm_format_to_gst_format(
80    fourcc: u32,
81    modifier: u64,
82) -> Result<VideoFormat, glib::BoolError> {
83    skip_assert_initialized!();
84    unsafe {
85        let res = ffi::gst_video_dma_drm_format_to_gst_format(fourcc, modifier);
86        if res == ffi::GST_VIDEO_FORMAT_UNKNOWN {
87            Err(glib::bool_error!("Unsupported fourcc format / modifier"))
88        } else {
89            Ok(from_glib(res))
90        }
91    }
92}
93
94#[doc(alias = "gst_video_is_dma_drm_caps")]
95pub fn is_dma_drm_caps(caps: &gst::CapsRef) -> bool {
96    skip_assert_initialized!();
97    unsafe { from_glib(ffi::gst_video_is_dma_drm_caps(caps.as_ptr())) }
98}
99
100/// Information describing a DMABuf image properties. It wraps [`VideoInfo`][crate::VideoInfo] and
101/// adds DRM information such as drm-fourcc and drm-modifier, required for
102/// negotiation and mapping.
103#[doc(alias = "GstVideoInfoDmaDrm")]
104#[derive(Clone)]
105#[repr(transparent)]
106pub struct VideoInfoDmaDrm(pub(crate) ffi::GstVideoInfoDmaDrm);
107
108impl ops::Deref for VideoInfoDmaDrm {
109    type Target = VideoInfo;
110
111    fn deref(&self) -> &Self::Target {
112        unsafe { &*(&self.0.vinfo as *const ffi::GstVideoInfo as *const VideoInfo) }
113    }
114}
115
116impl fmt::Debug for VideoInfoDmaDrm {
117    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118        f.debug_struct("VideoInfoDmaDrm")
119            .field("info", &**self)
120            .field("drm_fourcc", &self.0.drm_fourcc)
121            .field("drm_modifier", &self.0.drm_modifier)
122            .finish()
123    }
124}
125
126impl VideoInfoDmaDrm {
127    /// Allocate a new [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm] that is also initialized with
128    /// [`init()`][Self::init()].
129    ///
130    /// # Returns
131    ///
132    /// a new [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm].
133    /// Free it with `gst_video_info_dma_drm_free()`.
134    pub fn new(info: VideoInfo, fourcc: u32, modifier: u64) -> VideoInfoDmaDrm {
135        assert_initialized_main_thread!();
136
137        VideoInfoDmaDrm(ffi::GstVideoInfoDmaDrm {
138            vinfo: info.0,
139            drm_fourcc: fourcc,
140            drm_modifier: modifier,
141            _gst_reserved: [0; 20],
142        })
143    }
144
145    #[inline]
146    pub fn is_valid(&self) -> bool {
147        !self.0.vinfo.finfo.is_null()
148            && self.0.vinfo.width > 0
149            && self.0.vinfo.height > 0
150            && self.0.vinfo.size > 0
151    }
152
153    /// Parse `caps` to generate a [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm]. Please note that the
154    /// `caps` should be a dma drm caps. The `gst_video_is_dma_drm_caps()` can
155    /// be used to verify it before calling this function.
156    /// ## `caps`
157    /// a [`gst::Caps`][crate::gst::Caps]
158    ///
159    /// # Returns
160    ///
161    /// A [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm],
162    ///  or [`None`] if `caps` couldn't be parsed.
163    #[doc(alias = "gst_video_info_dma_drm_from_caps")]
164    pub fn from_caps(caps: &gst::CapsRef) -> Result<Self, glib::error::BoolError> {
165        skip_assert_initialized!();
166
167        unsafe {
168            let mut info = mem::MaybeUninit::uninit();
169            if from_glib(ffi::gst_video_info_dma_drm_from_caps(
170                info.as_mut_ptr(),
171                caps.as_ptr(),
172            )) {
173                Ok(Self(info.assume_init()))
174            } else {
175                Err(glib::bool_error!(
176                    "Failed to create VideoInfoDmaDrm from caps"
177                ))
178            }
179        }
180    }
181
182    /// Convert the values of `self` into a [`gst::Caps`][crate::gst::Caps]. Please note that the
183    /// `caps` returned will be a dma drm caps which sets format field to DMA_DRM,
184    /// and contains a new drm-format field. The value of drm-format field is
185    /// composed of a drm fourcc and a modifier, such as NV12:0x0100000000000002.
186    ///
187    /// # Returns
188    ///
189    /// a new [`gst::Caps`][crate::gst::Caps] containing the
190    /// info in `self`.
191    #[doc(alias = "gst_video_info_dma_drm_to_caps")]
192    pub fn to_caps(&self) -> Result<gst::Caps, glib::error::BoolError> {
193        unsafe {
194            let result = from_glib_full(ffi::gst_video_info_dma_drm_to_caps(mut_override(&self.0)));
195            match result {
196                Some(c) => Ok(c),
197                None => Err(glib::bool_error!(
198                    "Failed to create caps from VideoInfoDmaDrm"
199                )),
200            }
201        }
202    }
203
204    /// Fills `drm_info` if `info`'s format has a valid drm format and `modifier` is also
205    /// valid
206    /// ## `info`
207    /// a [`VideoInfo`][crate::VideoInfo]
208    /// ## `modifier`
209    /// the associated modifier value.
210    ///
211    /// # Returns
212    ///
213    /// [`true`] if `drm_info` is filled correctly.
214    ///
215    /// ## `drm_info`
216    /// [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm]
217    #[doc(alias = "gst_video_info_dma_drm_from_video_info")]
218    pub fn from_video_info(
219        video_info: &crate::VideoInfo,
220        modifier: u64,
221    ) -> Result<Self, glib::error::BoolError> {
222        skip_assert_initialized!();
223
224        unsafe {
225            let mut info = mem::MaybeUninit::uninit();
226            if from_glib(ffi::gst_video_info_dma_drm_from_video_info(
227                info.as_mut_ptr(),
228                video_info.to_glib_none().0,
229                modifier,
230            )) {
231                Ok(Self(info.assume_init()))
232            } else {
233                Err(glib::bool_error!(
234                    "Failed to create VideoInfoDmaDrm from VideoInfo"
235                ))
236            }
237        }
238    }
239
240    /// Convert the [`VideoInfoDmaDrm`][crate::VideoInfoDmaDrm] into a traditional [`VideoInfo`][crate::VideoInfo] with
241    /// recognized video format. For DMA kind memory, the non linear DMA format
242    /// should be recognized as [`VideoFormat::DmaDrm`][crate::VideoFormat::DmaDrm]. This helper function
243    /// sets `info`'s video format into the default value according to `self`'s
244    /// drm_fourcc field.
245    ///
246    /// # Returns
247    ///
248    /// [`true`] if `info` is converted correctly.
249    ///
250    /// ## `info`
251    /// [`VideoInfo`][crate::VideoInfo]
252    #[doc(alias = "gst_video_info_dma_drm_to_video_info")]
253    pub fn to_video_info(&self) -> Result<crate::VideoInfo, glib::error::BoolError> {
254        unsafe {
255            let mut video_info = mem::MaybeUninit::uninit();
256            if from_glib(ffi::gst_video_info_dma_drm_to_video_info(
257                mut_override(&self.0),
258                video_info.as_mut_ptr(),
259            )) {
260                Ok(crate::VideoInfo(video_info.assume_init()))
261            } else {
262                Err(glib::bool_error!(
263                    "Failed to create VideoInfo from VideoInfoDmaDrm"
264                ))
265            }
266        }
267    }
268
269    #[inline]
270    pub fn fourcc(&self) -> u32 {
271        self.0.drm_fourcc
272    }
273
274    #[inline]
275    pub fn modifier(&self) -> u64 {
276        self.0.drm_modifier
277    }
278}
279
280impl PartialEq for VideoInfoDmaDrm {
281    #[doc(alias = "gst_video_info_is_equal")]
282    fn eq(&self, other: &Self) -> bool {
283        unsafe {
284            from_glib(ffi::gst_video_info_is_equal(&self.0.vinfo, &other.0.vinfo))
285                && self.0.drm_fourcc == other.0.drm_fourcc
286                && self.0.drm_modifier == other.0.drm_modifier
287        }
288    }
289}
290
291impl Eq for VideoInfoDmaDrm {}
292
293unsafe impl Send for VideoInfoDmaDrm {}
294unsafe impl Sync for VideoInfoDmaDrm {}
295
296impl glib::types::StaticType for VideoInfoDmaDrm {
297    #[inline]
298    fn static_type() -> glib::types::Type {
299        unsafe { glib::translate::from_glib(ffi::gst_video_info_dma_drm_get_type()) }
300    }
301}
302
303impl glib::value::ValueType for VideoInfoDmaDrm {
304    type Type = Self;
305}
306
307#[doc(hidden)]
308unsafe impl<'a> glib::value::FromValue<'a> for VideoInfoDmaDrm {
309    type Checker = glib::value::GenericValueTypeOrNoneChecker<Self>;
310
311    unsafe fn from_value(value: &'a glib::Value) -> Self {
312        skip_assert_initialized!();
313        from_glib_none(glib::gobject_ffi::g_value_get_boxed(value.to_glib_none().0)
314            as *mut ffi::GstVideoInfoDmaDrm)
315    }
316}
317
318#[doc(hidden)]
319impl glib::value::ToValue for VideoInfoDmaDrm {
320    fn to_value(&self) -> glib::Value {
321        let mut value = glib::Value::for_value_type::<Self>();
322        unsafe {
323            glib::gobject_ffi::g_value_set_boxed(
324                value.to_glib_none_mut().0,
325                self.to_glib_none().0 as *mut _,
326            )
327        }
328        value
329    }
330
331    fn value_type(&self) -> glib::Type {
332        Self::static_type()
333    }
334}
335
336#[doc(hidden)]
337impl glib::value::ToValueOptional for VideoInfoDmaDrm {
338    fn to_value_optional(s: Option<&Self>) -> glib::Value {
339        skip_assert_initialized!();
340        let mut value = glib::Value::for_value_type::<Self>();
341        unsafe {
342            glib::gobject_ffi::g_value_set_boxed(
343                value.to_glib_none_mut().0,
344                s.to_glib_none().0 as *mut _,
345            )
346        }
347        value
348    }
349}
350
351#[doc(hidden)]
352impl From<VideoInfoDmaDrm> for glib::Value {
353    fn from(v: VideoInfoDmaDrm) -> glib::Value {
354        skip_assert_initialized!();
355        glib::value::ToValue::to_value(&v)
356    }
357}
358
359#[doc(hidden)]
360impl glib::translate::Uninitialized for VideoInfoDmaDrm {
361    #[inline]
362    unsafe fn uninitialized() -> Self {
363        mem::zeroed()
364    }
365}
366
367#[doc(hidden)]
368impl glib::translate::GlibPtrDefault for VideoInfoDmaDrm {
369    type GlibType = *mut ffi::GstVideoInfoDmaDrm;
370}
371
372#[doc(hidden)]
373impl<'a> glib::translate::ToGlibPtr<'a, *const ffi::GstVideoInfoDmaDrm> for VideoInfoDmaDrm {
374    type Storage = PhantomData<&'a Self>;
375
376    #[inline]
377    fn to_glib_none(&'a self) -> glib::translate::Stash<'a, *const ffi::GstVideoInfoDmaDrm, Self> {
378        glib::translate::Stash(&self.0, PhantomData)
379    }
380
381    fn to_glib_full(&self) -> *const ffi::GstVideoInfoDmaDrm {
382        unimplemented!()
383    }
384}
385
386#[doc(hidden)]
387impl glib::translate::FromGlibPtrNone<*const ffi::GstVideoInfoDmaDrm> for VideoInfoDmaDrm {
388    #[inline]
389    unsafe fn from_glib_none(ptr: *const ffi::GstVideoInfoDmaDrm) -> Self {
390        Self(ptr::read(ptr))
391    }
392}
393
394#[doc(hidden)]
395impl glib::translate::FromGlibPtrNone<*mut ffi::GstVideoInfoDmaDrm> for VideoInfoDmaDrm {
396    #[inline]
397    unsafe fn from_glib_none(ptr: *mut ffi::GstVideoInfoDmaDrm) -> Self {
398        Self(ptr::read(ptr))
399    }
400}
401
402#[doc(hidden)]
403impl glib::translate::FromGlibPtrFull<*mut ffi::GstVideoInfoDmaDrm> for VideoInfoDmaDrm {
404    #[inline]
405    unsafe fn from_glib_full(ptr: *mut ffi::GstVideoInfoDmaDrm) -> Self {
406        let info = from_glib_none(ptr);
407        glib::ffi::g_free(ptr as *mut _);
408        info
409    }
410}