Skip to main content

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
5#[cfg(feature = "v1_30")]
6use crate::VideoHDRFormat;
7use crate::ffi;
8use glib::translate::*;
9#[cfg(feature = "v1_30")]
10use gst::{MetaAPI, MetaAPIExt};
11
12#[doc(alias = "GstVideoContentLightLevel")]
13#[derive(Copy, Clone)]
14pub struct VideoContentLightLevel(ffi::GstVideoContentLightLevel);
15
16impl VideoContentLightLevel {
17    pub fn new(max_content_light_level: u16, max_frame_average_light_level: u16) -> Self {
18        skip_assert_initialized!();
19
20        VideoContentLightLevel(ffi::GstVideoContentLightLevel {
21            max_content_light_level,
22            max_frame_average_light_level,
23            _gst_reserved: [ptr::null_mut(); 4],
24        })
25    }
26
27    pub fn max_content_light_level(&self) -> u16 {
28        self.0.max_content_light_level
29    }
30
31    pub fn set_max_content_light_level(&mut self, max_content_light_level: u16) {
32        self.0.max_content_light_level = max_content_light_level;
33    }
34
35    pub fn max_frame_average_light_level(&self) -> u16 {
36        self.0.max_frame_average_light_level
37    }
38
39    pub fn set_max_frame_average_light_level(&mut self, max_frame_average_light_level: u16) {
40        self.0.max_frame_average_light_level = max_frame_average_light_level;
41    }
42
43    #[doc(alias = "gst_video_content_light_level_add_to_caps")]
44    pub fn add_to_caps(&self, caps: &mut gst::CapsRef) {
45        unsafe {
46            ffi::gst_video_content_light_level_add_to_caps(&self.0, caps.as_mut_ptr());
47        }
48    }
49
50    #[doc(alias = "gst_video_content_light_level_from_caps")]
51    pub fn from_caps(caps: &gst::CapsRef) -> Result<Self, glib::BoolError> {
52        skip_assert_initialized!();
53
54        unsafe {
55            let mut info = mem::MaybeUninit::uninit();
56            let res: bool = from_glib(ffi::gst_video_content_light_level_from_caps(
57                info.as_mut_ptr(),
58                caps.as_ptr(),
59            ));
60
61            if res {
62                Ok(VideoContentLightLevel(info.assume_init()))
63            } else {
64                Err(glib::bool_error!(
65                    "Failed to parse VideoContentLightLevel from caps"
66                ))
67            }
68        }
69    }
70}
71
72impl<'a> TryFrom<&'a gst::CapsRef> for VideoContentLightLevel {
73    type Error = glib::BoolError;
74
75    fn try_from(value: &'a gst::CapsRef) -> Result<Self, Self::Error> {
76        skip_assert_initialized!();
77
78        Self::from_caps(value)
79    }
80}
81
82impl PartialEq for VideoContentLightLevel {
83    #[doc(alias = "gst_video_content_light_level_is_equal")]
84    fn eq(&self, other: &Self) -> bool {
85        #[cfg(feature = "v1_20")]
86        unsafe {
87            from_glib(ffi::gst_video_content_light_level_is_equal(
88                &self.0, &other.0,
89            ))
90        }
91        #[cfg(not(feature = "v1_20"))]
92        {
93            self.0.max_content_light_level == other.0.max_content_light_level
94                && self.0.max_frame_average_light_level == other.0.max_frame_average_light_level
95        }
96    }
97}
98
99impl Eq for VideoContentLightLevel {}
100
101impl str::FromStr for VideoContentLightLevel {
102    type Err = glib::error::BoolError;
103
104    #[doc(alias = "gst_video_content_light_level_from_string")]
105    fn from_str(s: &str) -> Result<Self, Self::Err> {
106        assert_initialized_main_thread!();
107
108        unsafe {
109            let mut colorimetry = mem::MaybeUninit::uninit();
110            let valid: bool = from_glib(ffi::gst_video_content_light_level_from_string(
111                colorimetry.as_mut_ptr(),
112                s.to_glib_none().0,
113            ));
114            if valid {
115                Ok(Self(colorimetry.assume_init()))
116            } else {
117                Err(glib::bool_error!("Invalid colorimetry info"))
118            }
119        }
120    }
121}
122
123impl fmt::Debug for VideoContentLightLevel {
124    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
125        f.debug_struct("VideoContentLightLevel")
126            .field("max_content_light_level", &self.0.max_content_light_level)
127            .field(
128                "max_frame_average_light_level",
129                &self.0.max_frame_average_light_level,
130            )
131            .finish()
132    }
133}
134
135impl fmt::Display for VideoContentLightLevel {
136    #[doc(alias = "gst_video_content_light_level_to_string")]
137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        let s = unsafe {
139            glib::GString::from_glib_full(ffi::gst_video_content_light_level_to_string(&self.0))
140        };
141        f.write_str(&s)
142    }
143}
144
145#[doc(alias = "GstVideoMasteringDisplayInfo")]
146#[derive(Copy, Clone)]
147pub struct VideoMasteringDisplayInfo(ffi::GstVideoMasteringDisplayInfo);
148
149impl VideoMasteringDisplayInfo {
150    pub fn new(
151        display_primaries: [VideoMasteringDisplayInfoCoordinate; 3],
152        white_point: VideoMasteringDisplayInfoCoordinate,
153        max_display_mastering_luminance: u32,
154        min_display_mastering_luminance: u32,
155    ) -> Self {
156        skip_assert_initialized!();
157
158        VideoMasteringDisplayInfo(ffi::GstVideoMasteringDisplayInfo {
159            display_primaries: unsafe {
160                mem::transmute::<
161                    [VideoMasteringDisplayInfoCoordinate; 3],
162                    [ffi::GstVideoMasteringDisplayInfoCoordinates; 3],
163                >(display_primaries)
164            },
165            white_point: unsafe {
166                mem::transmute::<
167                    VideoMasteringDisplayInfoCoordinate,
168                    ffi::GstVideoMasteringDisplayInfoCoordinates,
169                >(white_point)
170            },
171            max_display_mastering_luminance,
172            min_display_mastering_luminance,
173            _gst_reserved: [ptr::null_mut(); 4],
174        })
175    }
176
177    pub fn display_primaries(&self) -> [VideoMasteringDisplayInfoCoordinate; 3] {
178        unsafe { mem::transmute(self.0.display_primaries) }
179    }
180
181    pub fn set_display_primaries(
182        &mut self,
183        display_primaries: [VideoMasteringDisplayInfoCoordinate; 3],
184    ) {
185        self.0.display_primaries = unsafe {
186            mem::transmute::<
187                [VideoMasteringDisplayInfoCoordinate; 3],
188                [ffi::GstVideoMasteringDisplayInfoCoordinates; 3],
189            >(display_primaries)
190        };
191    }
192
193    pub fn white_point(&self) -> VideoMasteringDisplayInfoCoordinate {
194        unsafe { mem::transmute(self.0.white_point) }
195    }
196
197    pub fn set_white_point(&mut self, white_point: VideoMasteringDisplayInfoCoordinate) {
198        self.0.white_point = unsafe {
199            mem::transmute::<
200                VideoMasteringDisplayInfoCoordinate,
201                ffi::GstVideoMasteringDisplayInfoCoordinates,
202            >(white_point)
203        };
204    }
205
206    pub fn max_display_mastering_luminance(&self) -> u32 {
207        self.0.max_display_mastering_luminance
208    }
209
210    pub fn set_max_display_mastering_luminance(&mut self, max_display_mastering_luminance: u32) {
211        self.0.max_display_mastering_luminance = max_display_mastering_luminance;
212    }
213
214    pub fn min_display_mastering_luminance(&self) -> u32 {
215        self.0.min_display_mastering_luminance
216    }
217
218    pub fn set_min_display_mastering_luminance(&mut self, min_display_mastering_luminance: u32) {
219        self.0.min_display_mastering_luminance = min_display_mastering_luminance;
220    }
221
222    #[doc(alias = "gst_video_mastering_display_info_add_to_caps")]
223    pub fn add_to_caps(&self, caps: &mut gst::CapsRef) {
224        unsafe {
225            ffi::gst_video_mastering_display_info_add_to_caps(&self.0, caps.as_mut_ptr());
226        }
227    }
228
229    #[doc(alias = "gst_video_mastering_display_info_from_caps")]
230    pub fn from_caps(caps: &gst::CapsRef) -> Result<Self, glib::BoolError> {
231        skip_assert_initialized!();
232
233        unsafe {
234            let mut info = mem::MaybeUninit::uninit();
235            let res: bool = from_glib(ffi::gst_video_mastering_display_info_from_caps(
236                info.as_mut_ptr(),
237                caps.as_ptr(),
238            ));
239
240            if res {
241                Ok(VideoMasteringDisplayInfo(info.assume_init()))
242            } else {
243                Err(glib::bool_error!(
244                    "Failed to parse VideoMasteringDisplayInfo from caps"
245                ))
246            }
247        }
248    }
249}
250
251impl<'a> TryFrom<&'a gst::CapsRef> for VideoMasteringDisplayInfo {
252    type Error = glib::BoolError;
253
254    fn try_from(value: &'a gst::CapsRef) -> Result<Self, Self::Error> {
255        skip_assert_initialized!();
256
257        Self::from_caps(value)
258    }
259}
260
261impl PartialEq for VideoMasteringDisplayInfo {
262    #[doc(alias = "gst_video_mastering_display_info_is_equal")]
263    fn eq(&self, other: &Self) -> bool {
264        unsafe {
265            from_glib(ffi::gst_video_mastering_display_info_is_equal(
266                &self.0, &other.0,
267            ))
268        }
269    }
270}
271
272impl Eq for VideoMasteringDisplayInfo {}
273
274impl str::FromStr for VideoMasteringDisplayInfo {
275    type Err = glib::error::BoolError;
276
277    #[doc(alias = "gst_video_mastering_display_info_from_string")]
278    fn from_str(s: &str) -> Result<Self, Self::Err> {
279        assert_initialized_main_thread!();
280
281        unsafe {
282            let mut colorimetry = mem::MaybeUninit::uninit();
283            let valid: bool = from_glib(ffi::gst_video_mastering_display_info_from_string(
284                colorimetry.as_mut_ptr(),
285                s.to_glib_none().0,
286            ));
287            if valid {
288                Ok(Self(colorimetry.assume_init()))
289            } else {
290                Err(glib::bool_error!("Invalid colorimetry info"))
291            }
292        }
293    }
294}
295
296impl fmt::Debug for VideoMasteringDisplayInfo {
297    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
298        f.debug_struct("VideoMasteringDisplayInfo")
299            .field("display_primaries", &self.display_primaries())
300            .field("white_point", &self.white_point())
301            .field(
302                "max_display_mastering_luminance",
303                &self.0.max_display_mastering_luminance,
304            )
305            .field(
306                "min_display_mastering_luminance",
307                &self.0.min_display_mastering_luminance,
308            )
309            .finish()
310    }
311}
312
313impl fmt::Display for VideoMasteringDisplayInfo {
314    #[doc(alias = "gst_video_mastering_display_info_to_string")]
315    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316        let s = unsafe {
317            glib::GString::from_glib_full(ffi::gst_video_mastering_display_info_to_string(&self.0))
318        };
319        f.write_str(&s)
320    }
321}
322
323#[repr(C)]
324#[derive(Copy, Clone, PartialEq, Eq)]
325#[doc(alias = "GstVideoMasteringDisplayInfoCoordinates")]
326pub struct VideoMasteringDisplayInfoCoordinate {
327    pub x: u16,
328    pub y: u16,
329}
330
331impl VideoMasteringDisplayInfoCoordinate {
332    pub fn new(x: f32, y: f32) -> Self {
333        skip_assert_initialized!();
334
335        Self {
336            x: (x * 50000.0) as u16,
337            y: (y * 50000.0) as u16,
338        }
339    }
340
341    pub fn x(&self) -> f32 {
342        self.x as f32 / 50000.0
343    }
344
345    pub fn y(&self) -> f32 {
346        self.y as f32 / 50000.0
347    }
348
349    pub fn set_x(&mut self, x: f32) {
350        self.x = (x * 50000.0) as u16;
351    }
352
353    pub fn set_y(&mut self, y: f32) {
354        self.y = (y * 50000.0) as u16;
355    }
356}
357
358impl fmt::Debug for VideoMasteringDisplayInfoCoordinate {
359    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
360        f.debug_struct("VideoMasteringDisplayInfoCoordinate")
361            .field("x", &self.x())
362            .field("y", &self.y())
363            .finish()
364    }
365}
366
367#[cfg(feature = "v1_30")]
368#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
369impl fmt::Display for VideoHDRFormat {
370    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
371        let s = unsafe {
372            glib::GString::from_glib_full(ffi::gst_video_hdr_format_to_string(self.into_glib()))
373        };
374        f.write_str(&s)
375    }
376}
377
378#[cfg(feature = "v1_30")]
379#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
380impl str::FromStr for VideoHDRFormat {
381    type Err = glib::BoolError;
382
383    #[doc(alias = "gst_video_hdr_format_from_string")]
384    fn from_str(s: &str) -> Result<Self, Self::Err> {
385        skip_assert_initialized!();
386
387        let format = unsafe { ffi::gst_video_hdr_format_from_string(s.to_glib_none().0) };
388
389        if format == ffi::GST_VIDEO_HDR_FORMAT_NONE && s != "none" {
390            Err(glib::bool_error!("Invalid HDR format: {}", s))
391        } else {
392            Ok(unsafe { from_glib(format) })
393        }
394    }
395}
396
397#[cfg(feature = "v1_30")]
398#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
399#[doc(alias = "GstVideoHDR10Plus")]
400#[derive(Copy, Clone)]
401pub struct VideoHDR10Plus(ffi::GstVideoHDR10Plus);
402
403#[cfg(feature = "v1_30")]
404#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
405impl VideoHDR10Plus {
406    #[doc(alias = "gst_video_hdr_parse_hdr10_plus")]
407    pub fn parse(data: &[u8]) -> Result<Self, glib::BoolError> {
408        skip_assert_initialized!();
409
410        let mut hdr10_plus = mem::MaybeUninit::uninit();
411        let ret: bool = unsafe {
412            from_glib(ffi::gst_video_hdr_parse_hdr10_plus(
413                data.as_ptr(),
414                data.len() as _,
415                hdr10_plus.as_mut_ptr(),
416            ))
417        };
418
419        if ret {
420            Ok(VideoHDR10Plus(unsafe { hdr10_plus.assume_init() }))
421        } else {
422            Err(glib::bool_error!("Failed to parse HDR10+ data"))
423        }
424    }
425
426    pub fn application_identifier(&self) -> u8 {
427        self.0.application_identifier
428    }
429
430    pub fn application_version(&self) -> u8 {
431        self.0.application_version
432    }
433
434    pub fn num_windows(&self) -> u8 {
435        self.0.num_windows
436    }
437}
438
439#[cfg(feature = "v1_30")]
440#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
441impl fmt::Debug for VideoHDR10Plus {
442    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
443        f.debug_struct("VideoHDR10Plus")
444            .field("application_identifier", &self.application_identifier())
445            .field("application_version", &self.application_version())
446            .field("num_windows", &self.num_windows())
447            .finish()
448    }
449}
450
451#[cfg(feature = "v1_30")]
452#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
453#[repr(transparent)]
454#[doc(alias = "GstVideoHDRMeta")]
455pub struct VideoHDRMeta(ffi::GstVideoHDRMeta);
456
457#[cfg(feature = "v1_30")]
458#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
459unsafe impl Send for VideoHDRMeta {}
460
461#[cfg(feature = "v1_30")]
462#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
463unsafe impl Sync for VideoHDRMeta {}
464
465#[cfg(feature = "v1_30")]
466#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
467impl VideoHDRMeta {
468    #[doc(alias = "gst_buffer_add_video_hdr_meta")]
469    pub fn add<'a>(
470        buffer: &'a mut gst::BufferRef,
471        format: VideoHDRFormat,
472        data: &[u8],
473    ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
474        skip_assert_initialized!();
475
476        unsafe {
477            let meta_ptr = ffi::gst_buffer_add_video_hdr_meta(
478                buffer.as_mut_ptr(),
479                format.into_glib(),
480                data.as_ptr(),
481                data.len(),
482            );
483            Self::from_mut_ptr(buffer, meta_ptr)
484        }
485    }
486
487    #[doc(alias = "get_format")]
488    pub fn format(&self) -> VideoHDRFormat {
489        unsafe { from_glib(self.0.format) }
490    }
491
492    #[doc(alias = "get_data")]
493    pub fn data(&self) -> &[u8] {
494        unsafe { std::slice::from_raw_parts(self.0.data, self.0.size) }
495    }
496}
497
498#[cfg(feature = "v1_30")]
499#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
500unsafe impl MetaAPI for VideoHDRMeta {
501    type GstType = ffi::GstVideoHDRMeta;
502
503    #[doc(alias = "gst_video_hdr_meta_api_get_type")]
504    #[inline]
505    fn meta_api() -> glib::Type {
506        unsafe { from_glib(ffi::gst_video_hdr_meta_api_get_type()) }
507    }
508}
509
510#[cfg(feature = "v1_30")]
511#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
512impl fmt::Debug for VideoHDRMeta {
513    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
514        f.debug_struct("VideoHDRMeta")
515            .field("format", &self.format())
516            .field("size", &self.0.size)
517            .finish()
518    }
519}
520
521#[cfg(feature = "v1_30")]
522#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
523#[doc(alias = "GstVideoColorVolumeTransformation")]
524#[derive(Copy, Clone)]
525pub struct VideoColorVolumeTransformation(ffi::GstVideoColorVolumeTransformation);
526
527#[cfg(feature = "v1_30")]
528#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
529impl VideoColorVolumeTransformation {
530    pub fn window_upper_left_corner_x(&self) -> u16 {
531        self.0.window_upper_left_corner_x
532    }
533
534    pub fn window_upper_left_corner_y(&self) -> u16 {
535        self.0.window_upper_left_corner_y
536    }
537
538    pub fn window_lower_right_corner_x(&self) -> u16 {
539        self.0.window_lower_right_corner_x
540    }
541
542    pub fn window_lower_right_corner_y(&self) -> u16 {
543        self.0.window_lower_right_corner_y
544    }
545
546    pub fn center_of_ellipse_x(&self) -> u16 {
547        self.0.center_of_ellipse_x
548    }
549
550    pub fn center_of_ellipse_y(&self) -> u16 {
551        self.0.center_of_ellipse_y
552    }
553
554    pub fn rotation_angle(&self) -> u8 {
555        self.0.rotation_angle
556    }
557
558    pub fn semimajor_axis_internal_ellipse(&self) -> u16 {
559        self.0.semimajor_axis_internal_ellipse
560    }
561
562    pub fn semimajor_axis_external_ellipse(&self) -> u16 {
563        self.0.semimajor_axis_external_ellipse
564    }
565
566    pub fn semiminor_axis_external_ellipse(&self) -> u16 {
567        self.0.semiminor_axis_external_ellipse
568    }
569
570    pub fn overlap_process_option(&self) -> u8 {
571        self.0.overlap_process_option
572    }
573
574    pub fn maxscl(&self) -> &[u32; 3] {
575        &self.0.maxscl
576    }
577
578    pub fn average_maxrgb(&self) -> u32 {
579        self.0.average_maxrgb
580    }
581
582    pub fn num_distributions(&self) -> u8 {
583        self.0.num_distributions
584    }
585
586    pub fn distribution_index(&self) -> &[u8; 16] {
587        &self.0.distribution_index
588    }
589
590    pub fn distribution_values(&self) -> &[u32; 16] {
591        &self.0.distribution_values
592    }
593
594    pub fn fraction_bright_pixels(&self) -> u16 {
595        self.0.fraction_bright_pixels
596    }
597
598    pub fn tone_mapping_flag(&self) -> u8 {
599        self.0.tone_mapping_flag
600    }
601
602    pub fn knee_point_x(&self) -> u16 {
603        self.0.knee_point_x
604    }
605
606    pub fn knee_point_y(&self) -> u16 {
607        self.0.knee_point_y
608    }
609
610    pub fn num_bezier_curve_anchors(&self) -> u8 {
611        self.0.num_bezier_curve_anchors
612    }
613
614    pub fn bezier_curve_anchors(&self) -> &[u16; 16] {
615        &self.0.bezier_curve_anchors
616    }
617
618    pub fn color_saturation_mapping_flag(&self) -> u8 {
619        self.0.color_saturation_mapping_flag
620    }
621
622    pub fn color_saturation_weight(&self) -> u8 {
623        self.0.color_saturation_weight
624    }
625}
626
627#[cfg(feature = "v1_30")]
628#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
629impl fmt::Debug for VideoColorVolumeTransformation {
630    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631        f.debug_struct("VideoColorVolumeTransformation")
632            .field(
633                "window_upper_left_corner_x",
634                &self.window_upper_left_corner_x(),
635            )
636            .field(
637                "window_upper_left_corner_y",
638                &self.window_upper_left_corner_y(),
639            )
640            .field(
641                "window_lower_right_corner_x",
642                &self.window_lower_right_corner_x(),
643            )
644            .field(
645                "window_lower_right_corner_y",
646                &self.window_lower_right_corner_y(),
647            )
648            .field("center_of_ellipse_x", &self.center_of_ellipse_x())
649            .field("center_of_ellipse_y", &self.center_of_ellipse_y())
650            .field("rotation_angle", &self.rotation_angle())
651            .field(
652                "semimajor_axis_internal_ellipse",
653                &self.semimajor_axis_internal_ellipse(),
654            )
655            .field(
656                "semimajor_axis_external_ellipse",
657                &self.semimajor_axis_external_ellipse(),
658            )
659            .field(
660                "semiminor_axis_external_ellipse",
661                &self.semiminor_axis_external_ellipse(),
662            )
663            .field("overlap_process_option", &self.overlap_process_option())
664            .field("maxscl", self.maxscl())
665            .field("average_maxrgb", &self.average_maxrgb())
666            .field("num_distributions", &self.num_distributions())
667            .field("distribution_index", self.distribution_index())
668            .field("distribution_values", self.distribution_values())
669            .field("fraction_bright_pixels", &self.fraction_bright_pixels())
670            .field("tone_mapping_flag", &self.tone_mapping_flag())
671            .field("knee_point_x", &self.knee_point_x())
672            .field("knee_point_y", &self.knee_point_y())
673            .field("num_bezier_curve_anchors", &self.num_bezier_curve_anchors())
674            .field("bezier_curve_anchors", self.bezier_curve_anchors())
675            .field(
676                "color_saturation_mapping_flag",
677                &self.color_saturation_mapping_flag(),
678            )
679            .field("color_saturation_weight", &self.color_saturation_weight())
680            .finish()
681    }
682}
683
684#[cfg(feature = "v1_30")]
685#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
686impl PartialEq for VideoColorVolumeTransformation {
687    fn eq(&self, other: &Self) -> bool {
688        self.0.window_upper_left_corner_x == other.0.window_upper_left_corner_x
689            && self.0.window_upper_left_corner_y == other.0.window_upper_left_corner_y
690            && self.0.window_lower_right_corner_x == other.0.window_lower_right_corner_x
691            && self.0.window_lower_right_corner_y == other.0.window_lower_right_corner_y
692            && self.0.center_of_ellipse_x == other.0.center_of_ellipse_x
693            && self.0.center_of_ellipse_y == other.0.center_of_ellipse_y
694            && self.0.rotation_angle == other.0.rotation_angle
695            && self.0.semimajor_axis_internal_ellipse == other.0.semimajor_axis_internal_ellipse
696            && self.0.semimajor_axis_external_ellipse == other.0.semimajor_axis_external_ellipse
697            && self.0.semiminor_axis_external_ellipse == other.0.semiminor_axis_external_ellipse
698            && self.0.overlap_process_option == other.0.overlap_process_option
699            && self.0.maxscl == other.0.maxscl
700            && self.0.average_maxrgb == other.0.average_maxrgb
701            && self.0.num_distributions == other.0.num_distributions
702            && self.0.distribution_index == other.0.distribution_index
703            && self.0.distribution_values == other.0.distribution_values
704            && self.0.fraction_bright_pixels == other.0.fraction_bright_pixels
705            && self.0.tone_mapping_flag == other.0.tone_mapping_flag
706            && self.0.knee_point_x == other.0.knee_point_x
707            && self.0.knee_point_y == other.0.knee_point_y
708            && self.0.num_bezier_curve_anchors == other.0.num_bezier_curve_anchors
709            && self.0.bezier_curve_anchors == other.0.bezier_curve_anchors
710            && self.0.color_saturation_mapping_flag == other.0.color_saturation_mapping_flag
711            && self.0.color_saturation_weight == other.0.color_saturation_weight
712    }
713}
714
715#[cfg(feature = "v1_30")]
716#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
717impl Eq for VideoColorVolumeTransformation {}