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