Skip to main content

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