gstreamer_video/
video_hdr.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, mem, ptr, str};
4
5use crate::ffi;
6use glib::translate::*;
7
8#[doc(alias = "GstVideoContentLightLevel")]
9#[derive(Copy, Clone)]
10pub struct VideoContentLightLevel(ffi::GstVideoContentLightLevel);
11
12impl VideoContentLightLevel {
13    pub fn new(max_content_light_level: u16, max_frame_average_light_level: u16) -> Self {
14        skip_assert_initialized!();
15
16        VideoContentLightLevel(ffi::GstVideoContentLightLevel {
17            max_content_light_level,
18            max_frame_average_light_level,
19            _gst_reserved: [ptr::null_mut(); 4],
20        })
21    }
22
23    pub fn max_content_light_level(&self) -> u16 {
24        self.0.max_content_light_level
25    }
26
27    pub fn set_max_content_light_level(&mut self, max_content_light_level: u16) {
28        self.0.max_content_light_level = max_content_light_level;
29    }
30
31    pub fn max_frame_average_light_level(&self) -> u16 {
32        self.0.max_frame_average_light_level
33    }
34
35    pub fn set_max_frame_average_light_level(&mut self, max_frame_average_light_level: u16) {
36        self.0.max_frame_average_light_level = max_frame_average_light_level;
37    }
38
39    #[doc(alias = "gst_video_content_light_level_add_to_caps")]
40    pub fn add_to_caps(&self, caps: &mut gst::CapsRef) {
41        unsafe {
42            ffi::gst_video_content_light_level_add_to_caps(&self.0, caps.as_mut_ptr());
43        }
44    }
45
46    #[doc(alias = "gst_video_content_light_level_from_caps")]
47    pub fn from_caps(caps: &gst::CapsRef) -> Result<Self, glib::BoolError> {
48        skip_assert_initialized!();
49
50        unsafe {
51            let mut info = mem::MaybeUninit::uninit();
52            let res: bool = from_glib(ffi::gst_video_content_light_level_from_caps(
53                info.as_mut_ptr(),
54                caps.as_ptr(),
55            ));
56
57            if res {
58                Ok(VideoContentLightLevel(info.assume_init()))
59            } else {
60                Err(glib::bool_error!(
61                    "Failed to parse VideoContentLightLevel from caps"
62                ))
63            }
64        }
65    }
66}
67
68impl<'a> TryFrom<&'a gst::CapsRef> for VideoContentLightLevel {
69    type Error = glib::BoolError;
70
71    fn try_from(value: &'a gst::CapsRef) -> Result<Self, Self::Error> {
72        skip_assert_initialized!();
73
74        Self::from_caps(value)
75    }
76}
77
78impl PartialEq for VideoContentLightLevel {
79    #[doc(alias = "gst_video_content_light_level_is_equal")]
80    fn eq(&self, other: &Self) -> bool {
81        #[cfg(feature = "v1_20")]
82        unsafe {
83            from_glib(ffi::gst_video_content_light_level_is_equal(
84                &self.0, &other.0,
85            ))
86        }
87        #[cfg(not(feature = "v1_20"))]
88        {
89            self.0.max_content_light_level == other.0.max_content_light_level
90                && self.0.max_frame_average_light_level == other.0.max_frame_average_light_level
91        }
92    }
93}
94
95impl Eq for VideoContentLightLevel {}
96
97impl str::FromStr for VideoContentLightLevel {
98    type Err = glib::error::BoolError;
99
100    #[doc(alias = "gst_video_content_light_level_from_string")]
101    fn from_str(s: &str) -> Result<Self, Self::Err> {
102        assert_initialized_main_thread!();
103
104        unsafe {
105            let mut colorimetry = mem::MaybeUninit::uninit();
106            let valid: bool = from_glib(ffi::gst_video_content_light_level_from_string(
107                colorimetry.as_mut_ptr(),
108                s.to_glib_none().0,
109            ));
110            if valid {
111                Ok(Self(colorimetry.assume_init()))
112            } else {
113                Err(glib::bool_error!("Invalid colorimetry info"))
114            }
115        }
116    }
117}
118
119impl fmt::Debug for VideoContentLightLevel {
120    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121        f.debug_struct("VideoContentLightLevel")
122            .field("max_content_light_level", &self.0.max_content_light_level)
123            .field(
124                "max_frame_average_light_level",
125                &self.0.max_frame_average_light_level,
126            )
127            .finish()
128    }
129}
130
131impl fmt::Display for VideoContentLightLevel {
132    #[doc(alias = "gst_video_content_light_level_to_string")]
133    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134        let s = unsafe {
135            glib::GString::from_glib_full(ffi::gst_video_content_light_level_to_string(&self.0))
136        };
137        f.write_str(&s)
138    }
139}
140
141#[doc(alias = "GstVideoMasteringDisplayInfo")]
142#[derive(Copy, Clone)]
143pub struct VideoMasteringDisplayInfo(ffi::GstVideoMasteringDisplayInfo);
144
145impl VideoMasteringDisplayInfo {
146    pub fn new(
147        display_primaries: [VideoMasteringDisplayInfoCoordinate; 3],
148        white_point: VideoMasteringDisplayInfoCoordinate,
149        max_display_mastering_luminance: u32,
150        min_display_mastering_luminance: u32,
151    ) -> Self {
152        skip_assert_initialized!();
153
154        VideoMasteringDisplayInfo(ffi::GstVideoMasteringDisplayInfo {
155            display_primaries: unsafe {
156                mem::transmute::<
157                    [VideoMasteringDisplayInfoCoordinate; 3],
158                    [ffi::GstVideoMasteringDisplayInfoCoordinates; 3],
159                >(display_primaries)
160            },
161            white_point: unsafe {
162                mem::transmute::<
163                    VideoMasteringDisplayInfoCoordinate,
164                    ffi::GstVideoMasteringDisplayInfoCoordinates,
165                >(white_point)
166            },
167            max_display_mastering_luminance,
168            min_display_mastering_luminance,
169            _gst_reserved: [ptr::null_mut(); 4],
170        })
171    }
172
173    pub fn display_primaries(&self) -> [VideoMasteringDisplayInfoCoordinate; 3] {
174        unsafe { mem::transmute(self.0.display_primaries) }
175    }
176
177    pub fn set_display_primaries(
178        &mut self,
179        display_primaries: [VideoMasteringDisplayInfoCoordinate; 3],
180    ) {
181        self.0.display_primaries = unsafe {
182            mem::transmute::<
183                [VideoMasteringDisplayInfoCoordinate; 3],
184                [ffi::GstVideoMasteringDisplayInfoCoordinates; 3],
185            >(display_primaries)
186        };
187    }
188
189    pub fn white_point(&self) -> VideoMasteringDisplayInfoCoordinate {
190        unsafe { mem::transmute(self.0.white_point) }
191    }
192
193    pub fn set_white_point(&mut self, white_point: VideoMasteringDisplayInfoCoordinate) {
194        self.0.white_point = unsafe {
195            mem::transmute::<
196                VideoMasteringDisplayInfoCoordinate,
197                ffi::GstVideoMasteringDisplayInfoCoordinates,
198            >(white_point)
199        };
200    }
201
202    pub fn max_display_mastering_luminance(&self) -> u32 {
203        self.0.max_display_mastering_luminance
204    }
205
206    pub fn set_max_display_mastering_luminance(&mut self, max_display_mastering_luminance: u32) {
207        self.0.max_display_mastering_luminance = max_display_mastering_luminance;
208    }
209
210    pub fn min_display_mastering_luminance(&self) -> u32 {
211        self.0.min_display_mastering_luminance
212    }
213
214    pub fn set_min_display_mastering_luminance(&mut self, min_display_mastering_luminance: u32) {
215        self.0.min_display_mastering_luminance = min_display_mastering_luminance;
216    }
217
218    #[doc(alias = "gst_video_mastering_display_info_add_to_caps")]
219    pub fn add_to_caps(&self, caps: &mut gst::CapsRef) {
220        unsafe {
221            ffi::gst_video_mastering_display_info_add_to_caps(&self.0, caps.as_mut_ptr());
222        }
223    }
224
225    #[doc(alias = "gst_video_mastering_display_info_from_caps")]
226    pub fn from_caps(caps: &gst::CapsRef) -> Result<Self, glib::BoolError> {
227        skip_assert_initialized!();
228
229        unsafe {
230            let mut info = mem::MaybeUninit::uninit();
231            let res: bool = from_glib(ffi::gst_video_mastering_display_info_from_caps(
232                info.as_mut_ptr(),
233                caps.as_ptr(),
234            ));
235
236            if res {
237                Ok(VideoMasteringDisplayInfo(info.assume_init()))
238            } else {
239                Err(glib::bool_error!(
240                    "Failed to parse VideoMasteringDisplayInfo from caps"
241                ))
242            }
243        }
244    }
245}
246
247impl<'a> TryFrom<&'a gst::CapsRef> for VideoMasteringDisplayInfo {
248    type Error = glib::BoolError;
249
250    fn try_from(value: &'a gst::CapsRef) -> Result<Self, Self::Error> {
251        skip_assert_initialized!();
252
253        Self::from_caps(value)
254    }
255}
256
257impl PartialEq for VideoMasteringDisplayInfo {
258    #[doc(alias = "gst_video_mastering_display_info_is_equal")]
259    fn eq(&self, other: &Self) -> bool {
260        unsafe {
261            from_glib(ffi::gst_video_mastering_display_info_is_equal(
262                &self.0, &other.0,
263            ))
264        }
265    }
266}
267
268impl Eq for VideoMasteringDisplayInfo {}
269
270impl str::FromStr for VideoMasteringDisplayInfo {
271    type Err = glib::error::BoolError;
272
273    #[doc(alias = "gst_video_mastering_display_info_from_string")]
274    fn from_str(s: &str) -> Result<Self, Self::Err> {
275        assert_initialized_main_thread!();
276
277        unsafe {
278            let mut colorimetry = mem::MaybeUninit::uninit();
279            let valid: bool = from_glib(ffi::gst_video_mastering_display_info_from_string(
280                colorimetry.as_mut_ptr(),
281                s.to_glib_none().0,
282            ));
283            if valid {
284                Ok(Self(colorimetry.assume_init()))
285            } else {
286                Err(glib::bool_error!("Invalid colorimetry info"))
287            }
288        }
289    }
290}
291
292impl fmt::Debug for VideoMasteringDisplayInfo {
293    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
294        f.debug_struct("VideoMasteringDisplayInfo")
295            .field("display_primaries", &self.display_primaries())
296            .field("white_point", &self.white_point())
297            .field(
298                "max_display_mastering_luminance",
299                &self.0.max_display_mastering_luminance,
300            )
301            .field(
302                "min_display_mastering_luminance",
303                &self.0.min_display_mastering_luminance,
304            )
305            .finish()
306    }
307}
308
309impl fmt::Display for VideoMasteringDisplayInfo {
310    #[doc(alias = "gst_video_mastering_display_info_to_string")]
311    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
312        let s = unsafe {
313            glib::GString::from_glib_full(ffi::gst_video_mastering_display_info_to_string(&self.0))
314        };
315        f.write_str(&s)
316    }
317}
318
319#[repr(C)]
320#[derive(Copy, Clone, PartialEq, Eq)]
321#[doc(alias = "GstVideoMasteringDisplayInfoCoordinates")]
322pub struct VideoMasteringDisplayInfoCoordinate {
323    pub x: u16,
324    pub y: u16,
325}
326
327impl VideoMasteringDisplayInfoCoordinate {
328    pub fn new(x: f32, y: f32) -> Self {
329        skip_assert_initialized!();
330
331        Self {
332            x: (x * 50000.0) as u16,
333            y: (y * 50000.0) as u16,
334        }
335    }
336
337    pub fn x(&self) -> f32 {
338        self.x as f32 / 50000.0
339    }
340
341    pub fn y(&self) -> f32 {
342        self.y as f32 / 50000.0
343    }
344
345    pub fn set_x(&mut self, x: f32) {
346        self.x = (x * 50000.0) as u16;
347    }
348
349    pub fn set_y(&mut self, y: f32) {
350        self.y = (y * 50000.0) as u16;
351    }
352}
353
354impl fmt::Debug for VideoMasteringDisplayInfoCoordinate {
355    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
356        f.debug_struct("VideoMasteringDisplayInfoCoordinate")
357            .field("x", &self.x())
358            .field("y", &self.y())
359            .finish()
360    }
361}