libdisplay_info/
cta.rs

1//! Low-level API for Consumer Technology Association standards.
2//!
3//! The library implements CTA-861-H, available at:
4//! <https://shop.cta.tech/collections/standards/products/a-dtv-profile-for-uncompressed-high-speed-digital-interfaces-cta-861-h>
5use std::marker::PhantomData;
6
7use libdisplay_info_derive::FFIFrom;
8
9use crate::{edid::ExtensionRef, ffi, FFIIter};
10
11/// EDID CTA-861 extension block.
12#[derive(Debug)]
13pub struct CTA<'ext> {
14    cta: *const ffi::cta::di_edid_cta,
15    phantom: PhantomData<&'ext ()>,
16}
17
18impl<'ext> CTA<'ext> {
19    /// Get a CTA-861 extension block.
20    ///
21    /// Returns `None` if the extension block tag is not [CEA](crate::edid::ExtensionTag::CEA).
22    pub fn from_extension(extensions: &'ext ExtensionRef) -> Option<CTA<'ext>> {
23        let cta = unsafe { ffi::edid::di_edid_ext_get_cta(extensions.as_ptr()) };
24
25        if cta.is_null() {
26            None
27        } else {
28            Some(Self {
29                cta: cta as *const ffi::cta::di_edid_cta,
30                phantom: PhantomData,
31            })
32        }
33    }
34
35    /// Get the CTA extension revision (also referred to as `version`` by the
36    /// specification).
37    pub fn revision(&self) -> i32 {
38        unsafe { ffi::cta::di_edid_cta_get_revision(self.cta) }
39    }
40
41    /// Get miscellaneous CTA flags.
42    pub fn flags(&self) -> Flags {
43        let flags = unsafe { ffi::cta::di_edid_cta_get_flags(self.cta) };
44        Flags::from(unsafe { *flags })
45    }
46
47    /// Get CTA data blocks.
48    pub fn data_blocks(&self) -> &[DataBlockRef] {
49        let data_blocks = unsafe { ffi::cta::di_edid_cta_get_data_blocks(self.cta) };
50
51        let mut len = 0;
52        while !unsafe { *data_blocks.offset(len) }.is_null() {
53            len += 1;
54        }
55
56        unsafe { std::slice::from_raw_parts(data_blocks as *const DataBlockRef, len as usize) }
57    }
58
59    /// Get a list of EDID detailed timing definitions.
60    pub fn detailed_timing_defs(&self) -> impl Iterator<Item = crate::edid::DetailedTimingDef> {
61        FFIIter::new(unsafe {
62            ffi::cta::di_edid_cta_get_detailed_timing_defs(self.cta)
63                as *const *const ffi::edid::di_edid_detailed_timing_def
64        })
65    }
66}
67
68/// CTA video format picture aspect ratio.
69#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
70#[ffi(ffi::cta::di_cta_video_format_picture_aspect_ratio)]
71#[repr(u32)]
72pub enum VideoFormatPictureAspectRatio {
73    _4_3 = ffi::cta::di_cta_video_format_picture_aspect_ratio_DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_4_3,
74    _16_9 = ffi::cta::di_cta_video_format_picture_aspect_ratio_DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_16_9,
75    _64_27 = ffi::cta::di_cta_video_format_picture_aspect_ratio_DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_64_27,
76    _256_135 = ffi::cta::di_cta_video_format_picture_aspect_ratio_DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_256_135,
77}
78
79/// CTA video format sync pulse polarity.
80#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
81#[ffi(ffi::cta::di_cta_video_format_sync_polarity)]
82#[repr(u32)]
83pub enum VideoFormatSyncPolarity {
84    Negative = ffi::cta::di_cta_video_format_sync_polarity_DI_CTA_VIDEO_FORMAT_SYNC_NEGATIVE,
85    Positive = ffi::cta::di_cta_video_format_sync_polarity_DI_CTA_VIDEO_FORMAT_SYNC_POSITIVE,
86}
87
88/// A CTA-861 video format, defined in section 4.
89#[derive(Debug, Copy, Clone, FFIFrom)]
90#[ffi(ffi::cta::di_cta_video_format)]
91pub struct VideoFormat {
92    pub vic: u8,
93    pub h_active: i32,
94    pub v_active: i32,
95    pub h_front: i32,
96    pub v_front: i32,
97    pub h_sync: i32,
98    pub v_sync: i32,
99    pub h_back: i32,
100    pub v_back: i32,
101    pub h_sync_polarity: VideoFormatSyncPolarity,
102    pub v_sync_polarity: VideoFormatSyncPolarity,
103    pub pixel_clock_hz: i64,
104    pub interlaced: bool,
105    pub picture_aspect_ratio: VideoFormatPictureAspectRatio,
106}
107
108impl VideoFormat {
109    /// Get a CTA-861 video format from a VIC.
110    ///
111    /// Returns `None` if the VIC is unknown.
112    pub fn from_vic(vic: u8) -> Option<VideoFormat> {
113        let video_format = unsafe { ffi::cta::di_cta_video_format_from_vic(vic) };
114
115        if video_format.is_null() {
116            None
117        } else {
118            Some(VideoFormat::from(unsafe { *video_format }))
119        }
120    }
121}
122
123/// Miscellaneous EDID CTA flags, defined in section 7.3.3.
124///
125/// For CTA revision 1, all of the fields are zero.
126#[derive(Debug, Copy, Clone, FFIFrom)]
127#[ffi(ffi::cta::di_edid_cta_flags)]
128pub struct Flags {
129    pub it_underscan: bool,
130    pub basic_audio: bool,
131    pub ycc444: bool,
132    pub ycc422: bool,
133    pub native_dtds: i32,
134}
135
136#[cfg_attr(docsrs, cfg(feature = "v0_2"))]
137#[cfg_attr(not(docsrs), cfg(all(feature = "v0_2", not(feature = "v0_3"))))]
138#[cfg_attr(
139    feature = "v0_3",
140    deprecated(since = "0.3.0", note = "use `VIITimingBlock` instead")
141)]
142pub type TypeIIIVIITiming = crate::displayid::TypeIIIVIITiming;
143
144/// CTA data block, defined in section 7.4.
145#[repr(transparent)]
146pub struct DataBlockRef(*const ffi::cta::di_cta_data_block);
147
148impl DataBlockRef {
149    /// Get the tag of the CTA data block.
150    pub fn tag(&self) -> DataBlockTag {
151        DataBlockTag::from(unsafe { ffi::cta::di_cta_data_block_get_tag(self.0) })
152    }
153
154    /// Get an array of short audio descriptors from a CTA data block.
155    ///
156    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_AUDIO.
157    #[cfg_attr(
158        feature = "v0_3",
159        deprecated(since = "0.3.0", note = "use `DataBlockRef::audio()` instead")
160    )]
161    pub fn sads(&self) -> impl Iterator<Item = Sad> {
162        FFIIter::new(unsafe { ffi::cta::di_cta_data_block_get_sads(self.0) })
163    }
164
165    /// Get the audio from a CTA data block.
166    ///
167    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_AUDIO.
168    #[cfg(feature = "v0_3")]
169    pub fn audio(&self) -> Option<AudioBlockRef> {
170        AudioBlockRef::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_audio(self.0) })
171    }
172
173    /// Get the speaker allocation from a CTA data block.
174    ///
175    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_SPEAKER_ALLOC.
176    pub fn speaker_alloc(&self) -> Option<SpeakerAllocBlock> {
177        SpeakerAllocBlock::from_ptr(unsafe {
178            ffi::cta::di_cta_data_block_get_speaker_alloc(self.0)
179        })
180    }
181
182    /// Get the video capabilities from a CTA data block.
183    ///
184    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO_CAP.
185    pub fn video_cap(&self) -> Option<VideoCapBlock> {
186        VideoCapBlock::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_video_cap(self.0) })
187    }
188
189    /// Get the VESA Display Device Data Block (DDDB) from a CTA data block.
190    ///
191    /// Returns `None` if the data block tag is not
192    /// DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE.
193    #[cfg_attr(
194        feature = "v0_3",
195        deprecated(
196            since = "0.3.0",
197            note = "use `DataBlockRef::vesa_display_device()` instead"
198        )
199    )]
200    #[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
201    pub fn vesa_dddb(&self) -> Option<VesaDddb> {
202        VesaDddb::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_vesa_dddb(self.0) })
203    }
204
205    /// Get the VESA Display Device Data Block (DDDB) from a CTA data block.
206    ///
207    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE.
208    #[cfg(feature = "v0_3")]
209    pub fn vesa_display_device(&self) -> Option<VesaDisplayDeviceBlock> {
210        VesaDisplayDeviceBlock::from_ptr(unsafe {
211            ffi::cta::di_cta_data_block_get_vesa_display_device(self.0)
212        })
213    }
214
215    /// Get the colorimetry data from a CTA data block.
216    ///
217    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_COLORIMETRY.
218    pub fn colorimetry(&self) -> Option<ColorimetryBlock> {
219        ColorimetryBlock::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_colorimetry(self.0) })
220    }
221
222    /// Get the HDR static metadata from a CTA data block.
223    ///
224    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA.
225    pub fn hdr_static_metadata(&self) -> Option<HdrStaticMetadataBlock> {
226        HdrStaticMetadataBlock::from_ptr(unsafe {
227            ffi::cta::di_cta_data_block_get_hdr_static_metadata(self.0)
228        })
229    }
230
231    /// Get the HDR dynamic metadata from a CTA data block.
232    ///
233    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA.
234    pub fn hdr_dynamic_metadata(&self) -> Option<HdrDynamicMetadataBlock> {
235        HdrDynamicMetadataBlock::from_ptr(unsafe {
236            ffi::cta::di_cta_data_block_get_hdr_dynamic_metadata(self.0)
237        })
238    }
239
240    /// Get an array of short video descriptors from a CTA data block.
241    ///
242    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO.
243    #[cfg_attr(
244        feature = "v0_3",
245        deprecated(since = "0.3.0", note = "use `DataBlockRef::video()` instead")
246    )]
247    pub fn svds(&self) -> impl Iterator<Item = Svd> {
248        FFIIter::new(unsafe { ffi::cta::di_cta_data_block_get_svds(self.0) })
249    }
250
251    /// Get the video from a CTA data block.
252    ///
253    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO.
254    #[cfg(feature = "v0_3")]
255    pub fn video(&self) -> Option<VideoBlockRef> {
256        VideoBlockRef::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_video(self.0) })
257    }
258
259    /// Get an array of short video descriptors which only allow YCbCr 4:2:0 sampling
260    /// mode from a CTA data block.
261    ///
262    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_YCBCR420.
263    #[cfg_attr(
264        feature = "v0_3",
265        deprecated(since = "0.3.0", note = "use `DataBlockRef::ycbcr420_video()` instead")
266    )]
267    pub fn ycbcr420_svds(&self) -> impl Iterator<Item = Svd> {
268        FFIIter::new(unsafe { ffi::cta::di_cta_data_block_get_ycbcr420_svds(self.0) })
269    }
270
271    /// Get the YCbCr video from a CTA data block.
272    ///
273    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_YCBCR420.
274    #[cfg(feature = "v0_3")]
275    pub fn ycbcr420_video(&self) -> Option<Ycbcr420VideoBlockRef> {
276        Ycbcr420VideoBlockRef::from_ptr(unsafe {
277            ffi::cta::di_cta_data_block_get_ycbcr420_video(self.0)
278        })
279    }
280
281    /// Get the Display Transfer Characteristic from a CTA data block.
282    ///
283    /// Returns `None` if the data block tag is not
284    /// DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC.
285    ///
286    /// Upstream is not aware of any EDID blob containing a Display Transfer
287    /// Characteristic data block.
288    /// If such a blob is found, please share it with upstream!
289    #[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
290    pub fn vesa_transfer_characteristics(&self) -> Option<VesaTransferCharacteristics> {
291        VesaTransferCharacteristics::from_ptr(unsafe {
292            ffi::cta::di_cta_data_block_get_vesa_transfer_characteristics(self.0)
293        })
294    }
295
296    /// Get the Display Transfer Characteristic from a CTA data block.
297    ///
298    /// Returns `None` if the data block tag is not
299    /// DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC.
300    ///
301    /// Upstream is not aware of any EDID blob containing a Display Transfer
302    /// Characteristic data block.
303    /// If such a blob is found, please share it with upstream!
304    #[cfg_attr(not(docsrs), cfg(feature = "v0_3"))]
305    #[cfg_attr(docsrs, cfg(not(feature = "v0_2")))]
306    pub fn vesa_transfer_characteristics(&self) -> Option<VesaTransferCharacteristicsBlock> {
307        VesaTransferCharacteristicsBlock::from_ptr(unsafe {
308            ffi::cta::di_cta_data_block_get_vesa_transfer_characteristics(self.0)
309        })
310    }
311
312    /// Get the YCbCr 4:2:0 Capability Map from a CTA data block.
313    ///
314    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP.
315    #[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
316    pub fn ycbcr420_cap_map(&self) -> Option<Ycbcr420CapMapRef> {
317        Ycbcr420CapMapRef::from_ptr(unsafe {
318            ffi::cta::di_cta_data_block_get_ycbcr420_cap_map(self.0)
319        })
320    }
321
322    /// Get the YCbCr 4:2:0 Capability Map from a CTA data block.
323    ///
324    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP.
325    #[cfg_attr(not(docsrs), cfg(feature = "v0_3"))]
326    #[cfg_attr(docsrs, cfg(not(feature = "v0_2")))]
327    pub fn ycbcr420_cap_map(&self) -> Option<Ycbcr420CapMapBlockRef> {
328        Ycbcr420CapMapBlockRef::from_ptr(unsafe {
329            ffi::cta::di_cta_data_block_get_ycbcr420_cap_map(self.0)
330        })
331    }
332
333    /// Get the InfoFrame information from a CTA data block.
334    ///
335    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_INFOFRAME.
336    pub fn infoframe(&self) -> Option<InfoframeBlockRef> {
337        InfoframeBlockRef::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_infoframe(self.0) })
338    }
339
340    /// Get the HDMI Audio information from a CTA data block.
341    ///
342    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_HDMI_AUDIO.
343    #[cfg(any(feature = "v0_2", feature = "v0_3"))]
344    pub fn hdmi_audio(&self) -> Option<HdmiAudioBlockRef> {
345        HdmiAudioBlockRef::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_hdmi_audio(self.0) })
346    }
347
348    /// Get the Room Configuration from a CTA data block.
349    ///
350    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_ROOM_CONFIG.
351    #[cfg_attr(not(docsrs), cfg(all(feature = "v0_2", not(feature = "v0_3"))))]
352    #[cfg_attr(docsrs, cfg(any(feature = "v0_2", feature = "v0_3")))]
353    pub fn room_configuration(&self) -> Option<RoomConfiguration> {
354        RoomConfiguration::from_ptr(unsafe {
355            ffi::cta::di_cta_data_block_get_room_configuration(self.0)
356        })
357    }
358
359    /// Get the Room Configuration from a CTA data block.
360    ///
361    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_ROOM_CONFIG.
362    #[cfg_attr(not(docsrs), cfg(feature = "v0_3"))]
363    #[cfg_attr(docsrs, cfg(not(feature = "v0_2")))]
364    pub fn room_configuration(&self) -> Option<RoomConfigurationBlock> {
365        RoomConfigurationBlock::from_ptr(unsafe {
366            ffi::cta::di_cta_data_block_get_room_configuration(self.0)
367        })
368    }
369
370    /// Get an array of Speaker Locations.
371    ///
372    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_SPEAKER_LOCATION.
373    #[cfg_attr(not(docsrs), cfg(all(feature = "v0_2", not(feature = "v0_3"))))]
374    #[cfg_attr(docsrs, cfg(any(feature = "v0_2", feature = "v0_3")))]
375    pub fn speaker_locations(&self) -> impl Iterator<Item = SpeakerLocations> {
376        // SAFETY: This is somewhat unfortunate, both v0.2 and v0.3 have this function,
377        // but v0.3 changed the return type.
378        // For now the polyfills in the -sys crate use a type alias to point to the new
379        // ffi type, which from C ABI point is safe to cast. Iteration should also be
380        // fine like this.
381        FFIIter::new(unsafe {
382            ffi::cta::di_cta_data_block_get_speaker_locations(self.0)
383                as *const *const ffi::cta::di_cta_speaker_locations
384        })
385    }
386
387    /// Get the Speaker Locations from a CTA data block.
388    ///
389    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_SPEAKER_LOCATION.
390    #[cfg_attr(not(docsrs), cfg(feature = "v0_3"))]
391    #[cfg_attr(docsrs, cfg(not(feature = "v0_2")))]
392    pub fn speaker_locations(&self) -> Option<SpeakerLocationBlockRef> {
393        SpeakerLocationBlockRef::from_ptr(unsafe {
394            ffi::cta::di_cta_data_block_get_speaker_locations(self.0)
395        })
396    }
397
398    /// Get the DisplayID Type VII Video Timing from a CTA data block.
399    ///
400    /// Returns `None` if the data block tag is not
401    /// DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII.
402    #[cfg_attr(docsrs, cfg(any(feature = "v0_2", feature = "v0_3")))]
403    #[cfg_attr(not(docsrs), cfg(all(feature = "v0_2", not(feature = "v0_3"))))]
404    pub fn did_type_vii_timing(&self) -> Option<TypeIIIVIITiming> {
405        TypeIIIVIITiming::from_ptr(unsafe {
406            ffi::cta::di_cta_data_block_get_did_type_vii_timing(self.0)
407                as *const ffi::displayid::di_displayid_type_i_ii_vii_timing
408        })
409    }
410
411    /// Get the DisplayID Type VII Video Timing from a CTA data block.
412    ///
413    /// Returns `None` if the data block tag is not
414    /// DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII.
415    #[cfg_attr(not(docsrs), cfg(feature = "v0_3"))]
416    #[cfg_attr(docsrs, cfg(not(feature = "v0_2")))]
417    pub fn did_type_vii_timing(&self) -> Option<VIITimingBlock> {
418        VIITimingBlock::from_ptr(unsafe {
419            ffi::cta::di_cta_data_block_get_did_type_vii_timing(self.0)
420                as *const ffi::cta::di_cta_type_vii_timing_block
421        })
422    }
423
424    /// Get an array of Short Video References (SVRs) from a CTA data block. The
425    /// first SVR refers to the most-preferred Video Format, while the next SVRs
426    /// are listed in order of decreasing preference.
427    ///
428    /// Returns `None` if the data block tag is not
429    /// DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF.
430    #[cfg(any(feature = "v0_2", feature = "v0_3"))]
431    #[cfg_attr(
432        feature = "v0_3",
433        deprecated(
434            since = "0.3.0",
435            note = "use `DataBlockRef::video_format_pref()` instead"
436        )
437    )]
438    pub fn svrs(&self) -> impl Iterator<Item = Svr> {
439        FFIIter::new(unsafe { ffi::cta::di_cta_data_block_get_svrs(self.0) })
440    }
441
442    /// Get the Video Format Preference information from a CTA data block.
443    ///
444    /// Returns `None` if the data block tag is not
445    /// DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF.
446    #[cfg(feature = "v0_3")]
447    pub fn video_format_pref(&self) -> Option<VideoFormatPrefBlockRef> {
448        VideoFormatPrefBlockRef::from_ptr(unsafe {
449            ffi::cta::di_cta_data_block_get_video_format_pref(self.0)
450        })
451    }
452
453    /// Get the HDR10+ information from a CTA data block.
454    ///
455    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_HDR10PLUS.
456    #[cfg(feature = "v0_3")]
457    pub fn hdr10plus(&self) -> Option<HDR10PlusBlock> {
458        HDR10PlusBlock::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_hdr10plus(self.0) })
459    }
460
461    /// Get the Dolby Vision information from a CTA data block.
462    ///
463    /// Returns `None` if the data block tag is not DI_CTA_DATA_BLOCK_DOLBY_VIDEO.
464    #[cfg(feature = "v0_3")]
465    pub fn dolby_video(&self) -> Option<DolbyVideoBlock> {
466        DolbyVideoBlock::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_dolby_video(self.0) })
467    }
468
469    /// Get the vendor-specific HDMI information from a CTA data block.
470    ///
471    /// Note, the HDMI and HDMI Forum vendor-specific data blocks are different.
472    ///
473    /// Returns `None` if the data block tag is not\n DI_CTA_DATA_BLOCK_VENDOR_HDMI.
474    #[cfg(feature = "v0_3")]
475    pub fn vendor_hdmi(&self) -> Option<VendorHdmiBlockRef> {
476        VendorHdmiBlockRef::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_vendor_hdmi(self.0) })
477    }
478
479    /// Get the vendor-specific HDMI Forum information from a CTA data block.
480    ///
481    /// Note, the HDMI and HDMI Forum vendor-specific data blocks are different.
482    ///
483    /// Returns `None` if the data block tag is not\n DI_CTA_DATA_BLOCK_VENDOR_HDMI_FORUM.
484    #[cfg(feature = "v0_3")]
485    pub fn vendor_hdmi_forum(&self) -> Option<VendorHdmiForumBlock> {
486        VendorHdmiForumBlock::from_ptr(unsafe {
487            ffi::cta::di_cta_data_block_get_vendor_hdmi_forum(self.0)
488        })
489    }
490
491    /// Get the HDMI Forum Sink Capability (HF-SCDB) from a CTA data block.
492    ///
493    /// Returns `None` if the data block tag is not
494    /// DI_CTA_DATA_BLOCK_HDMI_SINK_CAP.
495    #[cfg(feature = "v0_3")]
496    pub fn hdmi_sink_cap(&self) -> Option<HdmiForumSinkCap> {
497        HdmiForumSinkCap::from_ptr(unsafe { ffi::cta::di_cta_data_block_get_hdmi_sink_cap(self.0) })
498    }
499}
500
501/// CTA data block tag.
502///
503/// Note, the enum values don't match the specification.
504#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
505#[ffi(ffi::cta::di_cta_data_block_tag)]
506#[repr(u32)]
507pub enum DataBlockTag {
508    Audio = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_AUDIO,
509    Video = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VIDEO,
510    SpeakerAlloc = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_SPEAKER_ALLOC,
511    VesaDisplayTransferCharacteristic =
512        ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC,
513    VideoFormat = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VIDEO_FORMAT,
514    VideoCap = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VIDEO_CAP,
515    VesaDisplayDevice = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE,
516    Colorimetry = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_COLORIMETRY,
517    HdrStaticMetadata = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA,
518    HdrDynamicMetadata = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA,
519    NativeVideoResolution =
520        ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_NATIVE_VIDEO_RESOLUTION,
521    VideoFormatPref = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF,
522    Ycbcr420 = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_YCBCR420,
523    Ycbcr420CapMap = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP,
524    HdmiAudio = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDMI_AUDIO,
525    RoomConfig = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_ROOM_CONFIG,
526    SpeakerLocation = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_SPEAKER_LOCATION,
527    Infoframe = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_INFOFRAME,
528    DisplayidVideoTimingVii =
529        ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII,
530    DisplayidVideoTimingViii =
531        ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VIII,
532    DisplayidVideoTimingX =
533        ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_X,
534    HdmiEdidExtOverride = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE,
535    HdmiSinkCap = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDMI_SINK_CAP,
536    #[cfg(feature = "v0_3")]
537    VendorHdmi = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VENDOR_HDMI,
538    #[cfg(feature = "v0_3")]
539    DolbyVideo = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_DOLBY_VIDEO,
540    #[cfg(feature = "v0_3")]
541    HDR10Plus = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_HDR10PLUS,
542    #[cfg(feature = "v0_3")]
543    VendorHdmiForum = ffi::cta::di_cta_data_block_tag_DI_CTA_DATA_BLOCK_VENDOR_HDMI_FORUM,
544}
545
546/// Audio formats, defined in tables 37 and 39.
547///
548/// Note, the enum values don't match the specification.
549#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
550#[ffi(ffi::cta::di_cta_audio_format)]
551#[repr(u32)]
552#[allow(non_camel_case_types)]
553pub enum AudioFormat {
554    LPCM = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_LPCM,
555    AC3 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_AC3,
556    MPEG1 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG1,
557    MP3 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MP3,
558    MPEG2 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG2,
559    AAC_LC = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_AAC_LC,
560    DTS = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_DTS,
561    ATRAC = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_ATRAC,
562    ONE_BIT_AUDIO = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO,
563    ENHANCED_AC3 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_ENHANCED_AC3,
564    DTS_HD = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_DTS_HD,
565    MAT = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MAT,
566    DST = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_DST,
567    WMA_PRO = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_WMA_PRO,
568    MPEG4_HE_AAC = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC,
569    MPEG4_HE_AAC_V2 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2,
570    MPEG4_AAC_LC = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC,
571    DRA = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_DRA,
572    MPEG4_HE_AAC_MPEG_SURROUND =
573        ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND,
574    MPEG4_AAC_LC_MPEG_SURROUND =
575        ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND,
576    MPEGH_3D = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_MPEGH_3D,
577    AC4 = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_AC4,
578    LPCM_3D = ffi::cta::di_cta_audio_format_DI_CTA_AUDIO_FORMAT_LPCM_3D,
579}
580
581#[derive(Debug, Copy, Clone, FFIFrom)]
582#[ffi(ffi::cta::di_cta_sad_sample_rates)]
583pub struct SadSampleRates {
584    pub has_192_khz: bool,
585    pub has_176_4_khz: bool,
586    pub has_96_khz: bool,
587    pub has_88_2_khz: bool,
588    pub has_48_khz: bool,
589    pub has_44_1_khz: bool,
590    pub has_32_khz: bool,
591}
592
593#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
594#[ffi(ffi::cta::di_cta_sad_mpegh_3d_level)]
595#[repr(u32)]
596pub enum SadMpegh3dLevel {
597    Unspecified = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_UNSPECIFIED,
598    _1 = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_1,
599    _2 = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_2,
600    _3 = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_3,
601    _4 = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_4,
602    _5 = ffi::cta::di_cta_sad_mpegh_3d_level_DI_CTA_SAD_MPEGH_3D_LEVEL_5,
603}
604
605#[derive(Debug, Copy, Clone, FFIFrom)]
606#[ffi(ffi::cta::di_cta_sad_mpegh_3d)]
607pub struct SadMpegh3d {
608    pub level: SadMpegh3dLevel,
609    pub low_complexity_profile: bool,
610    pub baseline_profile: bool,
611}
612
613#[derive(Debug, Copy, Clone, FFIFrom)]
614#[ffi(ffi::cta::di_cta_sad_mpeg_aac)]
615pub struct SadMpegAac {
616    pub has_frame_length_960: bool,
617    pub has_frame_length_1024: bool,
618}
619
620#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
621#[ffi(ffi::cta::di_cta_sad_mpeg_surround_signaling)]
622#[repr(u32)]
623pub enum SadMpegSurroundSignaling {
624    Implicit =
625        ffi::cta::di_cta_sad_mpeg_surround_signaling_DI_CTA_SAD_MPEG_SURROUND_SIGNALING_IMPLICIT,
626    ImplicitAndExplicit = ffi::cta::di_cta_sad_mpeg_surround_signaling_DI_CTA_SAD_MPEG_SURROUND_SIGNALING_IMPLICIT_AND_EXPLICIT,
627}
628
629#[derive(Debug, Copy, Clone, FFIFrom)]
630#[ffi(ffi::cta::di_cta_sad_mpeg_surround)]
631pub struct SadMpegSurround {
632    pub signaling: SadMpegSurroundSignaling,
633}
634
635#[derive(Debug, Copy, Clone, FFIFrom)]
636#[ffi(ffi::cta::di_cta_sad_mpeg_aac_le)]
637pub struct SadMpegAacLe {
638    pub supports_multichannel_sound: bool,
639}
640
641#[derive(Debug, Copy, Clone, FFIFrom)]
642#[ffi(ffi::cta::di_cta_sad_lpcm)]
643pub struct SadLpcm {
644    pub has_sample_size_24_bits: bool,
645    pub has_sample_size_20_bits: bool,
646    pub has_sample_size_16_bits: bool,
647}
648
649#[derive(Debug, Copy, Clone, FFIFrom)]
650#[ffi(ffi::cta::di_cta_sad_enhanced_ac3)]
651#[allow(non_snake_case)]
652pub struct SadEnhancedAc3 {
653    pub supports_joint_object_coding: bool,
654    pub supports_joint_object_coding_ACMOD28: bool,
655}
656
657#[derive(Debug, Copy, Clone, FFIFrom)]
658#[ffi(ffi::cta::di_cta_sad_mat)]
659pub struct SadMat {
660    pub supports_object_audio_and_channel_based: bool,
661    pub requires_hash_calculation: bool,
662}
663
664#[derive(Debug, Copy, Clone, FFIFrom)]
665#[ffi(ffi::cta::di_cta_sad_wma_pro)]
666pub struct SadWmaPro {
667    pub profile: ::std::os::raw::c_int,
668}
669
670/// A CTA short audio descriptor (SAD), defined in section 7.5.2.
671#[derive(Debug, Copy, Clone, FFIFrom)]
672#[ffi(ffi::cta::di_cta_sad)]
673pub struct Sad {
674    pub format: AudioFormat,
675    #[optional(0i32)]
676    pub max_channels: Option<i32>,
677    #[ptr_deref]
678    pub supported_sample_rates: Option<SadSampleRates>,
679    #[optional(0i32)]
680    pub max_bitrate_kbs: Option<i32>,
681    #[ptr_deref]
682    pub lpcm: Option<SadLpcm>,
683    #[ptr_deref]
684    pub mpegh_3d: Option<SadMpegh3d>,
685    #[ptr_deref]
686    pub mpeg_aac: Option<SadMpegAac>,
687    #[ptr_deref]
688    pub mpeg_surround: Option<SadMpegSurround>,
689    #[ptr_deref]
690    pub mpeg_aac_le: Option<SadMpegAacLe>,
691    #[ptr_deref]
692    pub enhanced_ac3: Option<SadEnhancedAc3>,
693    #[ptr_deref]
694    pub mat: Option<SadMat>,
695    #[ptr_deref]
696    pub wma_pro: Option<SadWmaPro>,
697}
698
699#[derive(Debug, Copy, Clone, FFIFrom)]
700#[ffi(ffi::cta::di_cta_audio_block)]
701#[wrap]
702#[cfg(feature = "v0_3")]
703pub struct AudioBlock {}
704
705#[cfg(feature = "v0_3")]
706impl AudioBlockRef {
707    /// Get an array of short audio descriptors.
708    pub fn sads(&self) -> impl Iterator<Item = Sad> {
709        FFIIter::new(unsafe { (*self.0).sads })
710    }
711}
712
713/// Indicates which speakers are present.
714///
715/// See figure 6 for the meaning of the fields.
716#[derive(Debug, Copy, Clone, FFIFrom)]
717#[ffi(ffi::cta::di_cta_speaker_allocation)]
718pub struct SpeakerAllocation {
719    pub flw_frw: bool,
720    pub flc_frc: bool,
721    pub bc: bool,
722    pub bl_br: bool,
723    pub fc: bool,
724    pub lfe1: bool,
725    pub fl_fr: bool,
726    pub tpsil_tpsir: bool,
727    pub sil_sir: bool,
728    pub tpbc: bool,
729    pub lfe2: bool,
730    pub ls_rs: bool,
731    pub tpfc: bool,
732    pub tpc: bool,
733    pub tpfl_tpfr: bool,
734    pub btfl_btfr: bool,
735    pub btfc: bool,
736    pub tpbl_tpbr: bool,
737}
738
739/// Speaker allocation data block (SADB), defined in section 7.5.3.
740#[derive(Debug, Copy, Clone, FFIFrom)]
741#[ffi(ffi::cta::di_cta_speaker_alloc_block)]
742pub struct SpeakerAllocBlock {
743    pub speakers: SpeakerAllocation,
744}
745
746/// Over- and underscan capability.
747#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
748#[ffi(ffi::cta::di_cta_video_cap_over_underscan)]
749#[repr(u32)]
750pub enum VideoCapOverUnderscan {
751    UnknownOverUnderscan =
752        ffi::cta::di_cta_video_cap_over_underscan_DI_CTA_VIDEO_CAP_UNKNOWN_OVER_UNDERSCAN,
753    AlwaysOverscan = ffi::cta::di_cta_video_cap_over_underscan_DI_CTA_VIDEO_CAP_ALWAYS_OVERSCAN,
754    AlwaysUnderscan = ffi::cta::di_cta_video_cap_over_underscan_DI_CTA_VIDEO_CAP_ALWAYS_UNDERSCAN,
755    BothOverUnderscan =
756        ffi::cta::di_cta_video_cap_over_underscan_DI_CTA_VIDEO_CAP_BOTH_OVER_UNDERSCAN,
757}
758
759/// Video capability data block (VCDB), defined in section 7.5.6.
760#[derive(Debug, Copy, Clone, FFIFrom)]
761#[ffi(ffi::cta::di_cta_video_cap_block)]
762pub struct VideoCapBlock {
763    pub selectable_ycc_quantization_range: bool,
764    pub selectable_rgb_quantization_range: bool,
765    pub pt_over_underscan: VideoCapOverUnderscan,
766    pub it_over_underscan: VideoCapOverUnderscan,
767    pub ce_over_underscan: VideoCapOverUnderscan,
768}
769
770/// Interface types, defined in VESA DDDB section 2.3.1 and 2.3.2.
771///
772/// Note, the enum values don't match the specification.
773#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
774#[ffi(ffi::cta::di_cta_vesa_dddb_interface_type)]
775#[repr(u32)]
776#[allow(non_camel_case_types)]
777#[cfg_attr(
778    feature = "v0_3",
779    deprecated(since = "0.3.0", note = "use `VesaDisplayDeviceInterfaceType` instead")
780)]
781#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
782pub enum VesaDddbInterfaceType {
783    VGA = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_VGA,
784    NAVI_V = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_NAVI_V,
785    NAVI_D = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_NAVI_D,
786    LVDS = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_LVDS,
787    RSDS = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_RSDS,
788    DVI_D = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_DVI_D,
789    DVI_I_ANALOG =
790        ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_DVI_I_ANALOG,
791    DVI_I_DIGITAL =
792        ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_DVI_I_DIGITAL,
793    HDMI_A = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_HDMI_A,
794    HDMI_B = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_HDMI_B,
795    MDDI = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_MDDI,
796    DISPLAYPORT = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_DISPLAYPORT,
797    IEEE_1394 = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_IEEE_1394,
798    M1_ANALOG = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_M1_ANALOG,
799    M1_DIGITAL = ffi::cta::di_cta_vesa_dddb_interface_type_DI_CTA_VESA_DDDB_INTERFACE_M1_DIGITAL,
800}
801
802/// Interface types, defined in VESA DDDB section 2.3.1 and 2.3.2.
803///
804/// Note, the enum values don't match the specification.
805#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
806#[ffi(ffi::cta::di_cta_vesa_display_device_interface_type)]
807#[repr(u32)]
808#[allow(non_camel_case_types)]
809#[cfg(feature = "v0_3")]
810pub enum VesaDisplayDeviceInterfaceType {
811    VGA = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_VGA,
812    NAVI_V = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_NAVI_V,
813    NAVI_D = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_NAVI_D,
814    LVDS = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_LVDS,
815    RSDS = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_RSDS,
816    DVI_D = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_DVI_D,
817    DVI_I_ANALOG = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_DVI_I_ANALOG,
818    DVI_I_DIGITAL = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_DVI_I_DIGITAL,
819    HDMI_A = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_HDMI_A,
820    HDMI_B = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_HDMI_B,
821    MDDI = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_MDDI,
822    DISPLAYPORT = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_DISPLAYPORT,
823    IEEE_1394 = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_IEEE_1394,
824    M1_ANALOG = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_M1_ANALOG,
825    M1_DIGITAL = ffi::cta::di_cta_vesa_display_device_interface_type_DI_CTA_VESA_DISPLAY_DEVICE_INTERFACE_M1_DIGITAL,
826}
827
828#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
829#[ffi(ffi::cta::di_cta_vesa_dddb_content_protection)]
830#[repr(u32)]
831#[cfg_attr(
832    feature = "v0_3",
833    deprecated(
834        since = "0.3.0",
835        note = "use `VesaDisplayDeviceContentProtection` instead"
836    )
837)]
838#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
839pub enum VesaDddbContentProtection {
840    None = ffi::cta::di_cta_vesa_dddb_content_protection_DI_CTA_VESA_DDDB_CONTENT_PROTECTION_NONE,
841    HDCP = ffi::cta::di_cta_vesa_dddb_content_protection_DI_CTA_VESA_DDDB_CONTENT_PROTECTION_HDCP,
842    DTCP = ffi::cta::di_cta_vesa_dddb_content_protection_DI_CTA_VESA_DDDB_CONTENT_PROTECTION_DTCP,
843    DPCP = ffi::cta::di_cta_vesa_dddb_content_protection_DI_CTA_VESA_DDDB_CONTENT_PROTECTION_DPCP,
844}
845
846#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
847#[ffi(ffi::cta::di_cta_vesa_display_device_content_protection)]
848#[repr(u32)]
849#[cfg(feature = "v0_3")]
850pub enum VesaDisplayDeviceContentProtection {
851    None = ffi::cta::di_cta_vesa_display_device_content_protection_DI_CTA_VESA_DISPLAY_DEVICE_CONTENT_PROTECTION_NONE,
852    HDCP = ffi::cta::di_cta_vesa_display_device_content_protection_DI_CTA_VESA_DISPLAY_DEVICE_CONTENT_PROTECTION_HDCP,
853    DTCP = ffi::cta::di_cta_vesa_display_device_content_protection_DI_CTA_VESA_DISPLAY_DEVICE_CONTENT_PROTECTION_DTCP,
854    DPCP = ffi::cta::di_cta_vesa_display_device_content_protection_DI_CTA_VESA_DISPLAY_DEVICE_CONTENT_PROTECTION_DPCP,
855}
856
857#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
858#[ffi(ffi::cta::di_cta_vesa_dddb_default_orientation)]
859#[repr(u32)]
860#[cfg_attr(
861    feature = "v0_3",
862    deprecated(
863        since = "0.3.0",
864        note = "use `VesaDisplayDeviceDefaultOrientation` instead"
865    )
866)]
867#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
868pub enum VesaDddbDefaultOrientation {
869    Landscape = ffi::cta::di_cta_vesa_dddb_default_orientation_DI_CTA_VESA_DDDB_DEFAULT_ORIENTATION_LANDSCAPE,
870    Portrait =
871        ffi::cta::di_cta_vesa_dddb_default_orientation_DI_CTA_VESA_DDDB_DEFAULT_ORIENTATION_PORTAIT,
872    Unfixed =
873        ffi::cta::di_cta_vesa_dddb_default_orientation_DI_CTA_VESA_DDDB_DEFAULT_ORIENTATION_UNFIXED,
874    Undefined = ffi::cta::di_cta_vesa_dddb_default_orientation_DI_CTA_VESA_DDDB_DEFAULT_ORIENTATION_UNDEFINED,
875}
876
877#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
878#[ffi(ffi::cta::di_cta_vesa_display_device_default_orientation)]
879#[repr(u32)]
880#[cfg(feature = "v0_3")]
881pub enum VesaDisplayDeviceDefaultOrientation {
882    Landscape = ffi::cta::di_cta_vesa_display_device_default_orientation_DI_CTA_VESA_DISPLAY_DEVICE_DEFAULT_ORIENTATION_LANDSCAPE,
883    Portrait = ffi::cta::di_cta_vesa_display_device_default_orientation_DI_CTA_VESA_DISPLAY_DEVICE_DEFAULT_ORIENTATION_PORTAIT,
884    Unfixed = ffi::cta::di_cta_vesa_display_device_default_orientation_DI_CTA_VESA_DISPLAY_DEVICE_DEFAULT_ORIENTATION_UNFIXED,
885    Undefined = ffi::cta::di_cta_vesa_display_device_default_orientation_DI_CTA_VESA_DISPLAY_DEVICE_DEFAULT_ORIENTATION_UNDEFINED,
886}
887
888#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
889#[ffi(ffi::cta::di_cta_vesa_dddb_rotation_cap)]
890#[repr(u32)]
891#[allow(non_camel_case_types)]
892#[cfg_attr(
893    feature = "v0_3",
894    deprecated(since = "0.3.0", note = "use `VesaDisplayDeviceRotationCap` instead")
895)]
896#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
897pub enum VesaDddbRotationCap {
898    None = ffi::cta::di_cta_vesa_dddb_rotation_cap_DI_CTA_VESA_DDDB_ROTATION_CAP_NONE,
899    _90DEG_CLOCKWISE =
900        ffi::cta::di_cta_vesa_dddb_rotation_cap_DI_CTA_VESA_DDDB_ROTATION_CAP_90DEG_CLOCKWISE,
901    _90DEG_COUNTERCLOCKWISE = ffi::cta::di_cta_vesa_dddb_rotation_cap_DI_CTA_VESA_DDDB_ROTATION_CAP_90DEG_COUNTERCLOCKWISE,
902    _90DEG_EITHER =
903        ffi::cta::di_cta_vesa_dddb_rotation_cap_DI_CTA_VESA_DDDB_ROTATION_CAP_90DEG_EITHER,
904}
905
906#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
907#[ffi(ffi::cta::di_cta_vesa_display_device_rotation_cap)]
908#[repr(u32)]
909#[allow(non_camel_case_types)]
910#[cfg(feature = "v0_3")]
911pub enum VesaDisplayDeviceRotationCap {
912    None = ffi::cta::di_cta_vesa_display_device_rotation_cap_DI_CTA_VESA_DISPLAY_DEVICE_ROTATION_CAP_NONE,
913    _90DEG_CLOCKWISE = ffi::cta::di_cta_vesa_display_device_rotation_cap_DI_CTA_VESA_DISPLAY_DEVICE_ROTATION_CAP_90DEG_CLOCKWISE,
914    _90DEG_COUNTERCLOCKWISE = ffi::cta::di_cta_vesa_display_device_rotation_cap_DI_CTA_VESA_DISPLAY_DEVICE_ROTATION_CAP_90DEG_COUNTERCLOCKWISE,
915    _90DEG_EITHER = ffi::cta::di_cta_vesa_display_device_rotation_cap_DI_CTA_VESA_DISPLAY_DEVICE_ROTATION_CAP_90DEG_EITHER,
916}
917
918#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
919#[ffi(ffi::cta::di_cta_vesa_dddb_zero_pixel_location)]
920#[repr(u32)]
921#[cfg_attr(
922    feature = "v0_3",
923    deprecated(since = "0.3.0", note = "use `VesaDddbZeroPixelLocation` instead")
924)]
925#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
926pub enum VesaDddbZeroPixelLocation {
927    UpperLeft =
928        ffi::cta::di_cta_vesa_dddb_zero_pixel_location_DI_CTA_VESA_DDDB_ZERO_PIXEL_UPPER_LEFT,
929    UpperRight =
930        ffi::cta::di_cta_vesa_dddb_zero_pixel_location_DI_CTA_VESA_DDDB_ZERO_PIXEL_UPPER_RIGHT,
931    LowerLeft =
932        ffi::cta::di_cta_vesa_dddb_zero_pixel_location_DI_CTA_VESA_DDDB_ZERO_PIXEL_LOWER_LEFT,
933    LowerRight =
934        ffi::cta::di_cta_vesa_dddb_zero_pixel_location_DI_CTA_VESA_DDDB_ZERO_PIXEL_LOWER_RIGHT,
935}
936
937#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
938#[ffi(ffi::cta::di_cta_vesa_display_device_zero_pixel_location)]
939#[repr(u32)]
940#[cfg(feature = "v0_3")]
941pub enum VesaDisplayDeviceZeroPixelLocation {
942    UpperLeft = ffi::cta::di_cta_vesa_display_device_zero_pixel_location_DI_CTA_VESA_DISPLAY_DEVICE_ZERO_PIXEL_UPPER_LEFT,
943    UpperRight = ffi::cta::di_cta_vesa_display_device_zero_pixel_location_DI_CTA_VESA_DISPLAY_DEVICE_ZERO_PIXEL_UPPER_RIGHT,
944    LowerLeft = ffi::cta::di_cta_vesa_display_device_zero_pixel_location_DI_CTA_VESA_DISPLAY_DEVICE_ZERO_PIXEL_LOWER_LEFT,
945    LowerRight = ffi::cta::di_cta_vesa_display_device_zero_pixel_location_DI_CTA_VESA_DISPLAY_DEVICE_ZERO_PIXEL_LOWER_RIGHT,
946}
947
948#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
949#[ffi(ffi::cta::di_cta_vesa_dddb_scan_direction)]
950#[repr(u32)]
951#[cfg_attr(
952    feature = "v0_3",
953    deprecated(since = "0.3.0", note = "use `VesaDddbScanDirection` instead")
954)]
955#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
956pub enum VesaDddbScanDirection {
957    Undefined = ffi::cta::di_cta_vesa_dddb_scan_direction_DI_CTA_VESA_DDDB_SCAN_DIRECTION_UNDEFINED,
958    FastLongSlowShort = ffi::cta::di_cta_vesa_dddb_scan_direction_DI_CTA_VESA_DDDB_SCAN_DIRECTION_FAST_LONG_SLOW_SHORT,
959    FastShortSlowLong = ffi::cta::di_cta_vesa_dddb_scan_direction_DI_CTA_VESA_DDDB_SCAN_DIRECTION_FAST_SHORT_SLOW_LONG,
960}
961
962#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
963#[ffi(ffi::cta::di_cta_vesa_display_device_scan_direction)]
964#[repr(u32)]
965#[cfg(feature = "v0_3")]
966pub enum VesaDisplayDeviceScanDirection {
967    Undefined = ffi::cta::di_cta_vesa_display_device_scan_direction_DI_CTA_VESA_DISPLAY_DEVICE_SCAN_DIRECTION_UNDEFINED,
968    FastLongSlowShort = ffi::cta::di_cta_vesa_display_device_scan_direction_DI_CTA_VESA_DISPLAY_DEVICE_SCAN_DIRECTION_FAST_LONG_SLOW_SHORT,
969    FastShortSlowLong = ffi::cta::di_cta_vesa_display_device_scan_direction_DI_CTA_VESA_DISPLAY_DEVICE_SCAN_DIRECTION_FAST_SHORT_SLOW_LONG,
970}
971
972/// Subpixel layout, defined in VESA DDDB section 2.9.
973///
974/// For layouts with more than 3 subpixels, the color coordinates of the
975/// additional subpixels are defined in the additional primary chromaticities.
976#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
977#[ffi(ffi::cta::di_cta_vesa_dddb_subpixel_layout)]
978#[repr(u32)]
979#[allow(non_camel_case_types)]
980#[cfg_attr(
981    feature = "v0_3",
982    deprecated(
983        since = "0.3.0",
984        note = "use `VesaDisplayDeviceSubpixelLayout` instead"
985    )
986)]
987#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
988pub enum VesaDddbSubpixelLayout {
989    Undefined = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_UNDEFINED,
990    RGB_VERT = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_RGB_VERT,
991    RGB_HORIZ = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_RGB_HORIZ,
992    EDID_CHROM_VERT =
993        ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_EDID_CHROM_VERT,
994    EDID_CHROM_HORIZ =
995        ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_EDID_CHROM_HORIZ,
996    QUAD_RGGB = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_RGGB,
997    QUAD_GBRG = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_GBRG,
998    DELTA_RGB = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_DELTA_RGB,
999    MOSAIC = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_MOSAIC,
1000    QUAD_ANY = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_ANY,
1001    FIVE = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_FIVE,
1002    SIX = ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_SIX,
1003    CLAIRVOYANTE_PENTILE =
1004        ffi::cta::di_cta_vesa_dddb_subpixel_layout_DI_CTA_VESA_DDDB_SUBPIXEL_CLAIRVOYANTE_PENTILE,
1005}
1006
1007/// Subpixel layout, defined in VESA DDDB section 2.9.
1008///
1009/// For layouts with more than 3 subpixels, the color coordinates of the
1010/// additional subpixels are defined in the additional primary chromaticities.
1011#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1012#[ffi(ffi::cta::di_cta_vesa_display_device_subpixel_layout)]
1013#[repr(u32)]
1014#[allow(non_camel_case_types)]
1015#[cfg(feature = "v0_3")]
1016pub enum VesaDisplayDeviceSubpixelLayout {
1017    Undefined = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_UNDEFINED,
1018    RGB_VERT = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_RGB_VERT,
1019    RGB_HORIZ = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_RGB_HORIZ,
1020    EDID_CHROM_VERT = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_EDID_CHROM_VERT,
1021    EDID_CHROM_HORIZ = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_EDID_CHROM_HORIZ,
1022    QUAD_RGGB = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_QUAD_RGGB,
1023    QUAD_GBRG = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_QUAD_GBRG,
1024    DELTA_RGB = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_DELTA_RGB,
1025    MOSAIC = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_MOSAIC,
1026    QUAD_ANY = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_QUAD_ANY,
1027    FIVE = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_FIVE,
1028    SIX = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_SIX,
1029    CLAIRVOYANTE_PENTILE = ffi::cta::di_cta_vesa_display_device_subpixel_layout_DI_CTA_VESA_DISPLAY_DEVICE_SUBPIXEL_CLAIRVOYANTE_PENTILE,
1030}
1031
1032#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1033#[ffi(ffi::cta::di_cta_vesa_dddb_dithering_type)]
1034#[repr(u32)]
1035#[cfg_attr(
1036    feature = "v0_3",
1037    deprecated(since = "0.3.0", note = "use `VesaDisplayDeviceDitheringType` instead")
1038)]
1039#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1040pub enum VesaDddbDitheringType {
1041    None = ffi::cta::di_cta_vesa_dddb_dithering_type_DI_CTA_VESA_DDDB_DITHERING_NONE,
1042    Spacial = ffi::cta::di_cta_vesa_dddb_dithering_type_DI_CTA_VESA_DDDB_DITHERING_SPACIAL,
1043    Temporal = ffi::cta::di_cta_vesa_dddb_dithering_type_DI_CTA_VESA_DDDB_DITHERING_TEMPORAL,
1044    SpatialAndTemporal =
1045        ffi::cta::di_cta_vesa_dddb_dithering_type_DI_CTA_VESA_DDDB_DITHERING_SPATIAL_AND_TEMPORAL,
1046}
1047
1048#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1049#[ffi(ffi::cta::di_cta_vesa_display_device_dithering_type)]
1050#[repr(u32)]
1051#[cfg(feature = "v0_3")]
1052pub enum VesaDisplayDeviceDitheringType {
1053    None = ffi::cta::di_cta_vesa_display_device_dithering_type_DI_CTA_VESA_DISPLAY_DEVICE_DITHERING_NONE,
1054    Spacial = ffi::cta::di_cta_vesa_display_device_dithering_type_DI_CTA_VESA_DISPLAY_DEVICE_DITHERING_SPACIAL,
1055    Temporal = ffi::cta::di_cta_vesa_display_device_dithering_type_DI_CTA_VESA_DISPLAY_DEVICE_DITHERING_TEMPORAL,
1056    SpatialAndTemporal = ffi::cta::di_cta_vesa_display_device_dithering_type_DI_CTA_VESA_DISPLAY_DEVICE_DITHERING_SPATIAL_AND_TEMPORAL,
1057}
1058
1059#[derive(Debug, Copy, Clone, FFIFrom)]
1060#[ffi(ffi::cta::di_cta_vesa_dddb_additional_primary_chromaticity)]
1061#[cfg_attr(
1062    feature = "v0_3",
1063    deprecated(
1064        since = "0.3.0",
1065        note = "use `VesaDisplayDeviceAdditionalPrimaryChromaticity` instead"
1066    )
1067)]
1068#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1069pub struct VesaDddbAdditionalPrimaryChromaticity {
1070    pub x: f32,
1071    pub y: f32,
1072}
1073
1074#[derive(Debug, Copy, Clone, FFIFrom)]
1075#[ffi(ffi::cta::di_cta_vesa_display_device_additional_primary_chromaticity)]
1076#[cfg(feature = "v0_3")]
1077pub struct VesaDisplayDeviceAdditionalPrimaryChromaticity {
1078    pub x: f32,
1079    pub y: f32,
1080}
1081
1082#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1083#[ffi(ffi::cta::di_cta_vesa_dddb_frame_rate_conversion)]
1084#[repr(u32)]
1085#[cfg_attr(
1086    feature = "v0_3",
1087    deprecated(
1088        since = "0.3.0",
1089        note = "use `VesaDisplayDeviceFrameRateConversion` instead"
1090    )
1091)]
1092#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1093pub enum VesaDddbFrameRateConversion {
1094    None = ffi::cta::di_cta_vesa_dddb_frame_rate_conversion_DI_CTA_VESA_DDDB_FRAME_RATE_CONVERSION_NONE,
1095    SingleBuffering = ffi::cta::di_cta_vesa_dddb_frame_rate_conversion_DI_CTA_VESA_DDDB_FRAME_RATE_CONVERSION_SINGLE_BUFFERING,
1096    DoubleBuffering = ffi::cta::di_cta_vesa_dddb_frame_rate_conversion_DI_CTA_VESA_DDDB_FRAME_RATE_CONVERSION_DOUBLE_BUFFERING,
1097    Advanced = ffi::cta::di_cta_vesa_dddb_frame_rate_conversion_DI_CTA_VESA_DDDB_FRAME_RATE_CONVERSION_ADVANCED,
1098}
1099
1100#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1101#[ffi(ffi::cta::di_cta_vesa_display_device_frame_rate_conversion)]
1102#[repr(u32)]
1103#[cfg(feature = "v0_3")]
1104pub enum VesaDisplayDeviceFrameRateConversion {
1105    None = ffi::cta::di_cta_vesa_display_device_frame_rate_conversion_DI_CTA_VESA_DISPLAY_DEVICE_FRAME_RATE_CONVERSION_NONE,
1106    SingleBuffering = ffi::cta::di_cta_vesa_display_device_frame_rate_conversion_DI_CTA_VESA_DISPLAY_DEVICE_FRAME_RATE_CONVERSION_SINGLE_BUFFERING,
1107    DoubleBuffering = ffi::cta::di_cta_vesa_display_device_frame_rate_conversion_DI_CTA_VESA_DISPLAY_DEVICE_FRAME_RATE_CONVERSION_DOUBLE_BUFFERING,
1108    Advanced = ffi::cta::di_cta_vesa_display_device_frame_rate_conversion_DI_CTA_VESA_DISPLAY_DEVICE_FRAME_RATE_CONVERSION_ADVANCED,
1109}
1110
1111#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1112#[ffi(ffi::cta::di_cta_vesa_dddb_resp_time_transition)]
1113#[repr(u32)]
1114#[cfg_attr(
1115    feature = "v0_3",
1116    deprecated(
1117        since = "0.3.0",
1118        note = "use `VesaDisplayDeviceRespTimeTransition` instead"
1119    )
1120)]
1121#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1122pub enum VesaDddbRespTimeTransition {
1123    BlackToWhite =
1124        ffi::cta::di_cta_vesa_dddb_resp_time_transition_DI_CTA_VESA_DDDB_RESP_TIME_BLACK_TO_WHITE,
1125    WhiteToBlack =
1126        ffi::cta::di_cta_vesa_dddb_resp_time_transition_DI_CTA_VESA_DDDB_RESP_TIME_WHITE_TO_BLACK,
1127}
1128
1129#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1130#[ffi(ffi::cta::di_cta_vesa_display_device_resp_time_transition)]
1131#[repr(u32)]
1132#[cfg(feature = "v0_3")]
1133pub enum VesaDisplayDeviceRespTimeTransition {
1134    BlackToWhite = ffi::cta::di_cta_vesa_display_device_resp_time_transition_DI_CTA_VESA_DISPLAY_DEVICE_RESP_TIME_BLACK_TO_WHITE,
1135    WhiteToBlack = ffi::cta::di_cta_vesa_display_device_resp_time_transition_DI_CTA_VESA_DISPLAY_DEVICE_RESP_TIME_WHITE_TO_BLACK,
1136}
1137
1138/// VESA Display Device Data Block (DDDB), defined in VESA Display Device Data
1139/// Block (DDDB) Standard version 1.
1140#[derive(Debug, Copy, Clone, FFIFrom)]
1141#[ffi(ffi::cta::di_cta_vesa_dddb)]
1142#[cfg_attr(
1143    feature = "v0_3",
1144    deprecated(since = "0.3.0", note = "use `VesaDisplayDeviceBlock` instead")
1145)]
1146#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1147pub struct VesaDddb {
1148    pub interface_type: VesaDddbInterfaceType,
1149    #[optional(0i32)]
1150    pub num_channels: Option<i32>,
1151    pub interface_version: i32,
1152    pub interface_release: i32,
1153    pub content_protection: VesaDddbContentProtection,
1154    pub min_clock_freq_mhz: i32,
1155    pub max_clock_freq_mhz: i32,
1156    pub native_horiz_pixels: i32,
1157    pub native_vert_pixels: i32,
1158    pub aspect_ratio: f32,
1159    pub default_orientation: VesaDddbDefaultOrientation,
1160    pub rotation_cap: VesaDddbRotationCap,
1161    pub zero_pixel_location: VesaDddbZeroPixelLocation,
1162    pub scan_direction: VesaDddbScanDirection,
1163    pub subpixel_layout: VesaDddbSubpixelLayout,
1164    pub horiz_pitch_mm: f32,
1165    pub vert_pitch_mm: f32,
1166    pub dithering_type: VesaDddbDitheringType,
1167    pub direct_drive: bool,
1168    pub overdrive_not_recommended: bool,
1169    pub deinterlacing: bool,
1170    pub audio_support: bool,
1171    pub separate_audio_inputs: bool,
1172    pub audio_input_override: bool,
1173    pub audio_delay_provided: bool,
1174    pub audio_delay_ms: i32,
1175    pub frame_rate_conversion: VesaDddbFrameRateConversion,
1176    #[optional(0i32)]
1177    pub frame_rate_range_hz: Option<i32>,
1178    pub frame_rate_native_hz: i32,
1179    pub bit_depth_interface: i32,
1180    pub bit_depth_display: i32,
1181    pub additional_primary_chromaticities_len: usize,
1182    pub additional_primary_chromaticities: [VesaDddbAdditionalPrimaryChromaticity; 3usize],
1183    pub resp_time_transition: VesaDddbRespTimeTransition,
1184    pub resp_time_ms: i32,
1185    pub overscan_horiz_pct: i32,
1186    pub overscan_vert_pct: i32,
1187}
1188
1189/// VESA Display Device Data Block (DDDB), defined in VESA Display Device Data
1190/// Block (DDDB) Standard version 1.
1191#[derive(Debug, Copy, Clone, FFIFrom)]
1192#[ffi(ffi::cta::di_cta_vesa_display_device_block)]
1193#[cfg(feature = "v0_3")]
1194pub struct VesaDisplayDeviceBlock {
1195    pub interface_type: VesaDisplayDeviceInterfaceType,
1196    #[optional(0i32)]
1197    pub num_channels: Option<i32>,
1198    pub interface_version: i32,
1199    pub interface_release: i32,
1200    pub content_protection: VesaDisplayDeviceContentProtection,
1201    pub min_clock_freq_mhz: i32,
1202    pub max_clock_freq_mhz: i32,
1203    pub native_horiz_pixels: i32,
1204    pub native_vert_pixels: i32,
1205    pub aspect_ratio: f32,
1206    pub default_orientation: VesaDisplayDeviceDefaultOrientation,
1207    pub rotation_cap: VesaDisplayDeviceRotationCap,
1208    pub zero_pixel_location: VesaDisplayDeviceZeroPixelLocation,
1209    pub scan_direction: VesaDisplayDeviceScanDirection,
1210    pub subpixel_layout: VesaDisplayDeviceSubpixelLayout,
1211    pub horiz_pitch_mm: f32,
1212    pub vert_pitch_mm: f32,
1213    pub dithering_type: VesaDisplayDeviceDitheringType,
1214    pub direct_drive: bool,
1215    pub overdrive_not_recommended: bool,
1216    pub deinterlacing: bool,
1217    pub audio_support: bool,
1218    pub separate_audio_inputs: bool,
1219    pub audio_input_override: bool,
1220    pub audio_delay_provided: bool,
1221    pub audio_delay_ms: i32,
1222    pub frame_rate_conversion: VesaDisplayDeviceFrameRateConversion,
1223    #[optional(0i32)]
1224    pub frame_rate_range_hz: Option<i32>,
1225    pub frame_rate_native_hz: i32,
1226    pub bit_depth_interface: i32,
1227    pub bit_depth_display: i32,
1228    pub additional_primary_chromaticities_len: usize,
1229    pub additional_primary_chromaticities: [VesaDisplayDeviceAdditionalPrimaryChromaticity; 3usize],
1230    pub resp_time_transition: VesaDisplayDeviceRespTimeTransition,
1231    pub resp_time_ms: i32,
1232    pub overscan_horiz_pct: i32,
1233    pub overscan_vert_pct: i32,
1234}
1235
1236/// CTA colorimetry data block, defined in section 7.5.5.
1237#[derive(Debug, Copy, Clone, FFIFrom)]
1238#[ffi(ffi::cta::di_cta_colorimetry_block)]
1239pub struct ColorimetryBlock {
1240    pub xvycc_601: bool,
1241    pub xvycc_709: bool,
1242    pub sycc_601: bool,
1243    pub opycc_601: bool,
1244    pub oprgb: bool,
1245    pub bt2020_cycc: bool,
1246    pub bt2020_ycc: bool,
1247    pub bt2020_rgb: bool,
1248    pub st2113_rgb: bool,
1249    pub ictcp: bool,
1250}
1251
1252/// Supported Electro-Optical Transfer Functions for a CTA HDR static metadata
1253/// block.
1254#[derive(Debug, Copy, Clone, FFIFrom)]
1255#[ffi(ffi::cta::di_cta_hdr_static_metadata_block_eotfs)]
1256#[cfg_attr(
1257    feature = "v0_3",
1258    deprecated(since = "0.3.0", note = "use `HdrStaticMetadataEotfs` instead")
1259)]
1260#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1261pub struct HdrStaticMetadataBlockEotfs {
1262    pub traditional_sdr: bool,
1263    pub traditional_hdr: bool,
1264    pub pq: bool,
1265    pub hlg: bool,
1266}
1267
1268/// Supported Electro-Optical Transfer Functions for a CTA HDR static metadata
1269/// block.
1270#[derive(Debug, Copy, Clone, FFIFrom)]
1271#[ffi(ffi::cta::di_cta_hdr_static_metadata_eotfs)]
1272#[cfg(feature = "v0_3")]
1273pub struct HdrStaticMetadataEotfs {
1274    pub traditional_sdr: bool,
1275    pub traditional_hdr: bool,
1276    pub pq: bool,
1277    pub hlg: bool,
1278}
1279
1280/// Supported static metadata descriptors for a CTA HDR static metadata block.
1281#[derive(Debug, Copy, Clone, FFIFrom)]
1282#[ffi(ffi::cta::di_cta_hdr_static_metadata_block_descriptors)]
1283#[cfg_attr(
1284    feature = "v0_3",
1285    deprecated(since = "0.3.0", note = "use `HdrStaticMetadataDescriptors` instead")
1286)]
1287#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1288pub struct HdrStaticMetadataBlockDescriptors {
1289    pub type1: bool,
1290}
1291
1292/// Supported static metadata descriptors for a CTA HDR static metadata block.
1293#[derive(Debug, Copy, Clone, FFIFrom)]
1294#[ffi(ffi::cta::di_cta_hdr_static_metadata_descriptors)]
1295#[cfg(feature = "v0_3")]
1296pub struct HdrStaticMetadataDescriptors {
1297    pub type1: bool,
1298}
1299
1300#[cfg(not(feature = "v0_3"))]
1301pub type HdrStaticMetadataBlockFieldEotfs = HdrStaticMetadataBlockEotfs;
1302#[cfg(feature = "v0_3")]
1303pub type HdrStaticMetadataBlockFieldEotfs = HdrStaticMetadataEotfs;
1304
1305#[cfg(not(feature = "v0_3"))]
1306pub type HdrStaticMetadataBlockFieldDescriptors = HdrStaticMetadataBlockDescriptors;
1307#[cfg(feature = "v0_3")]
1308pub type HdrStaticMetadataBlockFieldDescriptors = HdrStaticMetadataDescriptors;
1309
1310/// CTA HDR static metadata block, defined in section 7.5.13.
1311#[derive(Debug, Copy, Clone, FFIFrom)]
1312#[ffi(ffi::cta::di_cta_hdr_static_metadata_block)]
1313pub struct HdrStaticMetadataBlock {
1314    #[optional(0f32)]
1315    pub desired_content_max_luminance: Option<f32>,
1316    #[optional(0f32)]
1317    pub desired_content_max_frame_avg_luminance: Option<f32>,
1318    #[optional(0f32)]
1319    pub desired_content_min_luminance: Option<f32>,
1320    #[ptr_deref]
1321    pub eotfs: Option<HdrStaticMetadataBlockFieldEotfs>,
1322    #[ptr_deref]
1323    pub descriptors: Option<HdrStaticMetadataBlockFieldDescriptors>,
1324}
1325
1326#[derive(Debug, Copy, Clone, FFIFrom)]
1327#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block_type1)]
1328#[cfg_attr(
1329    feature = "v0_3",
1330    deprecated(since = "0.3.0", note = "use `HdrDynamicMetadataType1` instead")
1331)]
1332#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1333pub struct HdrDynamicMetadataBlockType1 {
1334    pub type_1_hdr_metadata_version: u8,
1335}
1336
1337#[derive(Debug, Copy, Clone, FFIFrom)]
1338#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_type1)]
1339#[cfg(feature = "v0_3")]
1340pub struct HdrDynamicMetadataType1 {
1341    pub type_1_hdr_metadata_version: u8,
1342}
1343
1344#[derive(Debug, Copy, Clone, FFIFrom)]
1345#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block_type2)]
1346#[cfg_attr(
1347    feature = "v0_3",
1348    deprecated(since = "0.3.0", note = "use `HdrDynamicMetadataBlockType2` instead")
1349)]
1350#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1351pub struct HdrDynamicMetadataBlockType2 {
1352    pub ts_103_433_spec_version: u8,
1353    pub ts_103_433_1_capable: bool,
1354    pub ts_103_433_2_capable: bool,
1355    pub ts_103_433_3_capable: bool,
1356}
1357
1358#[derive(Debug, Copy, Clone, FFIFrom)]
1359#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_type2)]
1360#[cfg(feature = "v0_3")]
1361pub struct HdrDynamicMetadataType2 {
1362    pub ts_103_433_spec_version: u8,
1363    pub ts_103_433_1_capable: bool,
1364    pub ts_103_433_2_capable: bool,
1365    pub ts_103_433_3_capable: bool,
1366}
1367
1368#[derive(Debug, Copy, Clone, FFIFrom)]
1369#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block_type3)]
1370#[cfg_attr(
1371    feature = "v0_3",
1372    deprecated(since = "0.3.0", note = "use `HdrDynamicMetadataType3` instead")
1373)]
1374#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1375pub struct HdrDynamicMetadataBlockType3 {}
1376
1377#[derive(Debug, Copy, Clone, FFIFrom)]
1378#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_type3)]
1379#[cfg(feature = "v0_3")]
1380pub struct HdrDynamicMetadataType3 {}
1381
1382#[derive(Debug, Copy, Clone, FFIFrom)]
1383#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block_type4)]
1384#[cfg_attr(
1385    feature = "v0_3",
1386    deprecated(since = "0.3.0", note = "use `HdrDynamicMetadataType4` instead")
1387)]
1388#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1389pub struct HdrDynamicMetadataBlockType4 {
1390    pub type_4_hdr_metadata_version: u8,
1391}
1392
1393#[derive(Debug, Copy, Clone, FFIFrom)]
1394#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_type4)]
1395#[cfg(feature = "v0_3")]
1396pub struct HdrDynamicMetadataType4 {
1397    pub type_4_hdr_metadata_version: u8,
1398}
1399
1400#[derive(Debug, Copy, Clone, FFIFrom)]
1401#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block_type256)]
1402#[cfg_attr(
1403    feature = "v0_3",
1404    deprecated(since = "0.3.0", note = "use `HdrDynamicMetadataType256` instead")
1405)]
1406#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1407pub struct HdrDynamicMetadataBlockType256 {
1408    pub graphics_overlay_flag_version: u8,
1409}
1410
1411#[derive(Debug, Copy, Clone, FFIFrom)]
1412#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_type256)]
1413#[cfg(feature = "v0_3")]
1414pub struct HdrDynamicMetadataType256 {
1415    pub graphics_overlay_flag_version: u8,
1416}
1417
1418#[cfg(not(feature = "v0_3"))]
1419pub type HdrDynamicMetadataBlockFieldType1 = HdrDynamicMetadataBlockType1;
1420#[cfg(feature = "v0_3")]
1421pub type HdrDynamicMetadataBlockFieldType1 = HdrDynamicMetadataType1;
1422#[cfg(not(feature = "v0_3"))]
1423pub type HdrDynamicMetadataBlockFieldType2 = HdrDynamicMetadataBlockType2;
1424#[cfg(feature = "v0_3")]
1425pub type HdrDynamicMetadataBlockFieldType2 = HdrDynamicMetadataType2;
1426#[cfg(not(feature = "v0_3"))]
1427pub type HdrDynamicMetadataBlockFieldType3 = HdrDynamicMetadataBlockType3;
1428#[cfg(feature = "v0_3")]
1429pub type HdrDynamicMetadataBlockFieldType3 = HdrDynamicMetadataType3;
1430#[cfg(not(feature = "v0_3"))]
1431pub type HdrDynamicMetadataBlockFieldType4 = HdrDynamicMetadataBlockType4;
1432#[cfg(feature = "v0_3")]
1433pub type HdrDynamicMetadataBlockFieldType4 = HdrDynamicMetadataType4;
1434#[cfg(not(feature = "v0_3"))]
1435pub type HdrDynamicMetadataBlockFieldType256 = HdrDynamicMetadataBlockType256;
1436#[cfg(feature = "v0_3")]
1437pub type HdrDynamicMetadataBlockFieldType256 = HdrDynamicMetadataType256;
1438
1439#[doc = " CTA HDR dynamic metadata block, defined in section 7.5.14."]
1440#[derive(Debug, Copy, Clone, FFIFrom)]
1441#[ffi(ffi::cta::di_cta_hdr_dynamic_metadata_block)]
1442pub struct HdrDynamicMetadataBlock {
1443    #[ptr_deref]
1444    pub type1: Option<HdrDynamicMetadataBlockFieldType1>,
1445    #[ptr_deref]
1446    pub type2: Option<HdrDynamicMetadataBlockFieldType2>,
1447    #[ptr_deref]
1448    pub type3: Option<HdrDynamicMetadataBlockFieldType3>,
1449    #[ptr_deref]
1450    pub type4: Option<HdrDynamicMetadataBlockFieldType4>,
1451    #[ptr_deref]
1452    pub type256: Option<HdrDynamicMetadataBlockFieldType256>,
1453}
1454
1455/// A Short Video Descriptor (SVD).
1456#[derive(Debug, Copy, Clone, FFIFrom)]
1457#[ffi(ffi::cta::di_cta_svd)]
1458pub struct Svd {
1459    pub vic: u8,
1460    #[cfg(feature = "v0_3")]
1461    pub original_index: u8,
1462    pub native: bool,
1463}
1464
1465#[derive(Debug, Copy, Clone, FFIFrom)]
1466#[ffi(ffi::cta::di_cta_video_block)]
1467#[wrap]
1468#[cfg(feature = "v0_3")]
1469pub struct VideoBlock {}
1470
1471#[cfg(feature = "v0_3")]
1472impl VideoBlockRef {
1473    /// Get an array of short video descriptors.
1474    pub fn svds(&self) -> impl Iterator<Item = Svd> {
1475        FFIIter::new(unsafe { (*self.0).svds })
1476    }
1477}
1478
1479#[derive(Debug, Copy, Clone, FFIFrom)]
1480#[ffi(ffi::cta::di_cta_ycbcr420_video_block)]
1481#[wrap]
1482#[cfg(feature = "v0_3")]
1483pub struct Ycbcr420VideoBlock {}
1484
1485#[cfg(feature = "v0_3")]
1486impl Ycbcr420VideoBlockRef {
1487    /// Get an array of short video descriptors.
1488    pub fn svds(&self) -> impl Iterator<Item = Svd> {
1489        FFIIter::new(unsafe { (*self.0).svds })
1490    }
1491}
1492
1493#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1494#[ffi(ffi::cta::di_cta_vesa_transfer_characteristics_usage)]
1495#[repr(u32)]
1496pub enum VesaTransferCharacteristicsUsage {
1497    White = ffi::cta::di_cta_vesa_transfer_characteristics_usage_DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_WHITE,
1498    Red = ffi::cta::di_cta_vesa_transfer_characteristics_usage_DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_RED,
1499    Green = ffi::cta::di_cta_vesa_transfer_characteristics_usage_DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_GREEN,
1500    Blue = ffi::cta::di_cta_vesa_transfer_characteristics_usage_DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_BLUE,
1501}
1502
1503/// VESA Display Transfer Characteristic Data Block, defined in VESA Display
1504/// Transfer Characteristics Data Block Standard Version 1.0
1505///
1506/// Contains 8, 16 or 32 evenly distributed points on the input axis describing
1507/// the normalized relative luminance at that input. The first value includes the
1508/// relative black level luminance.
1509#[derive(Debug, Copy, Clone, FFIFrom)]
1510#[ffi(ffi::cta::di_cta_vesa_transfer_characteristics)]
1511#[cfg_attr(
1512    feature = "v0_3",
1513    deprecated(
1514        since = "0.3.0",
1515        note = "use `VesaTransferCharacteristicsBlock` instead"
1516    )
1517)]
1518#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1519pub struct VesaTransferCharacteristics {
1520    pub usage: VesaTransferCharacteristicsUsage,
1521    pub points_len: u8,
1522    pub points: [f32; 32usize],
1523}
1524
1525/// VESA Display Transfer Characteristic Data Block, defined in VESA Display
1526/// Transfer Characteristics Data Block Standard Version 1.0
1527///
1528/// Contains 8, 16 or 32 evenly distributed points on the input axis describing
1529/// the normalized relative luminance at that input. The first value includes the
1530/// relative black level luminance.
1531#[derive(Debug, Copy, Clone, FFIFrom)]
1532#[ffi(ffi::cta::di_cta_vesa_transfer_characteristics_block)]
1533#[cfg(feature = "v0_3")]
1534pub struct VesaTransferCharacteristicsBlock {
1535    pub usage: VesaTransferCharacteristicsUsage,
1536    pub points_len: u8,
1537    pub points: [f32; 32usize],
1538}
1539
1540/// CTA YCbCr 4:2:0 Capability Map block, defined in section 7.5.11.
1541#[derive(Debug, Copy, Clone, FFIFrom)]
1542#[ffi(ffi::cta::di_cta_ycbcr420_cap_map)]
1543#[wrap]
1544#[cfg_attr(
1545    feature = "v0_3",
1546    deprecated(
1547        since = "0.3.0",
1548        note = "use `VesaTransferCharacteristicsBlock` instead"
1549    )
1550)]
1551#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1552pub struct Ycbcr420CapMap {}
1553
1554#[cfg_attr(not(docsrs), cfg(not(feature = "v0_3")))]
1555impl Ycbcr420CapMapRef {
1556    /// Returns true if the SVD in regular Video Data Blocks at index `svd_index`
1557    /// supports YCbCr 4:2:0 subsampling.
1558    pub fn di_cta_ycbcr420_cap_map_supported(&self, svd_index: usize) -> bool {
1559        unsafe { ffi::cta::di_cta_ycbcr420_cap_map_supported(self.0, svd_index) }
1560    }
1561}
1562
1563/// CTA YCbCr 4:2:0 Capability Map block, defined in section 7.5.11.
1564#[derive(Debug, Copy, Clone, FFIFrom)]
1565#[ffi(ffi::cta::di_cta_ycbcr420_cap_map_block)]
1566#[wrap]
1567#[cfg(feature = "v0_3")]
1568pub struct Ycbcr420CapMapBlock {}
1569
1570#[cfg(feature = "v0_3")]
1571impl Ycbcr420CapMapBlockRef {
1572    /// Returns true if the SVD in regular Video Data Blocks at index `svd_index`
1573    /// supports YCbCr 4:2:0 subsampling.
1574    pub fn di_cta_ycbcr420_cap_map_supported(&self, svd_index: usize) -> bool {
1575        unsafe { ffi::cta::di_cta_ycbcr420_cap_map_supported(self.0, svd_index) }
1576    }
1577}
1578
1579/// InfoFrame types, defined in table 7.
1580///
1581/// Note, the enum values don't match the specification.
1582#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1583#[ffi(ffi::cta::di_cta_infoframe_type)]
1584#[repr(u32)]
1585pub enum InfoframeType {
1586    AuxiliaryVideoInformation =
1587        ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_AUXILIARY_VIDEO_INFORMATION,
1588    SourceProductDescription =
1589        ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_SOURCE_PRODUCT_DESCRIPTION,
1590    Audio = ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_AUDIO,
1591    MpegSource = ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_MPEG_SOURCE,
1592    NtscVbi = ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_NTSC_VBI,
1593    DynamicRangeAndMastering =
1594        ffi::cta::di_cta_infoframe_type_DI_CTA_INFOFRAME_TYPE_DYNAMIC_RANGE_AND_MASTERING,
1595}
1596
1597/// CTA InfoFrame descriptor, defined in section 7.5.9.
1598#[derive(Debug, Copy, Clone, FFIFrom)]
1599#[ffi(ffi::cta::di_cta_infoframe_descriptor)]
1600pub struct InfoframeDescriptor {
1601    pub type_: InfoframeType,
1602}
1603
1604/// CTA InfoFrame processing, defined in section 7.5.9.
1605#[derive(Debug, Copy, Clone, FFIFrom)]
1606#[ffi(ffi::cta::di_cta_infoframe_block)]
1607#[wrap]
1608pub struct InfoframeBlock {
1609    pub num_simultaneous_vsifs: i32,
1610}
1611
1612impl InfoframeBlockRef {
1613    pub fn infoframes(&self) -> impl Iterator<Item = InfoframeDescriptor> {
1614        FFIIter::new(unsafe { (*self.0).infoframes })
1615    }
1616}
1617
1618/// InfoFrame types, defined in table 7.
1619///
1620/// Note, the enum values don't match the specification.
1621#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1622#[ffi(ffi::cta::di_cta_hdmi_audio_3d_channels)]
1623#[repr(u32)]
1624#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1625pub enum HdmiAudio3DChannels {
1626    Unknown = ffi::cta::di_cta_hdmi_audio_3d_channels_DI_CTA_HDMI_AUDIO_3D_CHANNELS_UNKNOWN,
1627    _10_2 = ffi::cta::di_cta_hdmi_audio_3d_channels_DI_CTA_HDMI_AUDIO_3D_CHANNELS_10_2,
1628    _22_2 = ffi::cta::di_cta_hdmi_audio_3d_channels_DI_CTA_HDMI_AUDIO_3D_CHANNELS_22_2,
1629    _30_2 = ffi::cta::di_cta_hdmi_audio_3d_channels_DI_CTA_HDMI_AUDIO_3D_CHANNELS_30_2,
1630}
1631
1632/// HDMI 3D Audio
1633#[derive(Debug, Copy, Clone, FFIFrom)]
1634#[ffi(ffi::cta::di_cta_hdmi_audio_3d)]
1635#[wrap]
1636#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1637pub struct HdmiAudio3d {
1638    pub channels: HdmiAudio3DChannels,
1639    pub speakers: SpeakerAllocation,
1640}
1641
1642#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1643impl HdmiAudio3dRef {
1644    pub fn sads(&self) -> impl Iterator<Item = Sad> {
1645        FFIIter::new(unsafe { (*self.0).sads })
1646    }
1647}
1648
1649/// HDMI Multi-Stream Audio
1650#[derive(Debug, Copy, Clone, FFIFrom)]
1651#[ffi(ffi::cta::di_cta_hdmi_audio_multi_stream)]
1652#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1653pub struct HdmiAudioMultiStream {
1654    pub max_streams: ::std::os::raw::c_int,
1655    pub supports_non_mixed: bool,
1656}
1657
1658/// HDMI Audio
1659#[derive(Debug, FFIFrom)]
1660#[ffi(ffi::cta::di_cta_hdmi_audio_block)]
1661#[wrap]
1662#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1663pub struct HdmiAudioBlock {
1664    #[ptr_deref]
1665    pub multi_stream: Option<HdmiAudioMultiStream>,
1666}
1667
1668#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1669impl HdmiAudioBlockRef {
1670    pub fn audio_3d(&self) -> Option<HdmiAudio3dRef> {
1671        HdmiAudio3dRef::from_ptr(unsafe { (*self.0).audio_3d })
1672    }
1673}
1674
1675/// Room Configuration Data Block, defined in section 7.5.15.
1676#[derive(Debug, Copy, Clone, FFIFrom)]
1677#[ffi(ffi::cta::di_cta_room_configuration)]
1678#[cfg(feature = "v0_2")]
1679#[cfg_attr(
1680    feature = "v0_3",
1681    deprecated(since = "0.3.0", note = "use `RoomConfigurationBlock` instead")
1682)]
1683pub struct RoomConfiguration {
1684    pub speakers: SpeakerAllocation,
1685    pub speaker_count: ::std::os::raw::c_int,
1686    pub has_speaker_location_descriptors: bool,
1687    pub max_x: ::std::os::raw::c_int,
1688    pub max_y: ::std::os::raw::c_int,
1689    pub max_z: ::std::os::raw::c_int,
1690    pub display_x: f64,
1691    pub display_y: f64,
1692    pub display_z: f64,
1693}
1694
1695/// Room Configuration Data Block, defined in section 7.5.15.
1696#[derive(Debug, Copy, Clone, FFIFrom)]
1697#[ffi(ffi::cta::di_cta_room_configuration_block)]
1698#[cfg(feature = "v0_3")]
1699pub struct RoomConfigurationBlock {
1700    pub speakers: SpeakerAllocation,
1701    pub speaker_count: ::std::os::raw::c_int,
1702    pub has_speaker_location_descriptors: bool,
1703    pub max_x: ::std::os::raw::c_int,
1704    pub max_y: ::std::os::raw::c_int,
1705    pub max_z: ::std::os::raw::c_int,
1706    pub display_x: f64,
1707    pub display_y: f64,
1708    pub display_z: f64,
1709}
1710
1711#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1712#[ffi(ffi::cta::di_cta_speaker_placement)]
1713#[repr(u32)]
1714#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1715pub enum SpeakerPlacement {
1716    FL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FL,
1717    FR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FR,
1718    FC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FC,
1719    LFE1 = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_LFE1,
1720    BL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BL,
1721    BR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BR,
1722    FLC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FLC,
1723    FRC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FRC,
1724    BC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BC,
1725    LFE2 = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_LFE2,
1726    SIL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_SIL,
1727    SIR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_SIR,
1728    TPFL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPFL,
1729    TPFR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPFR,
1730    TPFC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPFC,
1731    TPC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPC,
1732    TPBL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPBL,
1733    TPBR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPBR,
1734    TPSIL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPSIL,
1735    TPSIR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPSIR,
1736    TPBC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_TPBC,
1737    BTFC = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BTFC,
1738    BTFL = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BTFL,
1739    BRFR = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_BRFR,
1740    FLW = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FLW,
1741    FRW = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_FRW,
1742    LS = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_LS,
1743    RS = ffi::cta::di_cta_speaker_placement_DI_CTA_SPEAKER_PLACEMENT_RS,
1744}
1745
1746/// Speaker Location Data Block, defined in section 7.5.16.
1747#[derive(Debug, Copy, Clone, FFIFrom)]
1748#[ffi(ffi::cta::di_cta_speaker_locations)]
1749#[cfg(feature = "v0_2")]
1750#[cfg_attr(
1751    feature = "v0_3",
1752    deprecated(since = "0.3.0", note = "use `SpeakerLocationBlock` instead")
1753)]
1754pub struct SpeakerLocations {
1755    pub channel_index: ::std::os::raw::c_int,
1756    pub is_active: bool,
1757    pub has_coords: bool,
1758    pub x: f64,
1759    pub y: f64,
1760    pub z: f64,
1761    pub speaker_id: SpeakerPlacement,
1762}
1763
1764/// Speaker Location Descriptor, defined in section 7.5.16.
1765#[derive(Debug, Copy, Clone, FFIFrom)]
1766#[ffi(ffi::cta::di_cta_speaker_location_descriptor)]
1767#[cfg(feature = "v0_3")]
1768pub struct SpeakerLocationDescriptor {
1769    pub channel_index: ::std::os::raw::c_int,
1770    pub is_active: bool,
1771    pub has_coords: bool,
1772    pub x: f64,
1773    pub y: f64,
1774    pub z: f64,
1775    pub speaker_id: SpeakerPlacement,
1776}
1777
1778/// Speaker Location Data Block, defined in section 7.5.16.
1779#[derive(Debug, Copy, Clone, FFIFrom)]
1780#[ffi(ffi::cta::di_cta_speaker_location_block)]
1781#[wrap]
1782#[cfg(feature = "v0_3")]
1783pub struct SpeakerLocationBlock {}
1784
1785#[cfg(feature = "v0_3")]
1786impl SpeakerLocationBlockRef {
1787    /// Get an array of speaker location descriptors.
1788    pub fn locations(&self) -> impl Iterator<Item = SpeakerLocationDescriptor> {
1789        FFIIter::new(unsafe { (*self.0).locations })
1790    }
1791}
1792
1793#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1794#[ffi(ffi::cta::di_cta_svr_type)]
1795#[repr(u32)]
1796#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1797pub enum SvrType {
1798    VIC = ffi::cta::di_cta_svr_type_DI_CTA_SVR_TYPE_VIC,
1799    DtdIndex = ffi::cta::di_cta_svr_type_DI_CTA_SVR_TYPE_DTD_INDEX,
1800    T7T10VTDB = ffi::cta::di_cta_svr_type_DI_CTA_SVR_TYPE_T7T10VTDB,
1801    FirstT8vtdb = ffi::cta::di_cta_svr_type_DI_CTA_SVR_TYPE_FIRST_T8VTDB,
1802}
1803
1804/// Short Video Reference, defined in section 7.5.12.
1805#[derive(Debug, Copy, Clone, FFIFrom)]
1806#[ffi(ffi::cta::di_cta_svr)]
1807#[cfg(any(feature = "v0_2", feature = "v0_3"))]
1808pub struct Svr {
1809    pub type_: SvrType,
1810    pub vic: u8,
1811    pub dtd_index: u8,
1812    pub t7_t10_vtdb_index: u8,
1813}
1814/// A HDMI video format, not to be confused with a CTA-861 video format.
1815#[derive(Debug, Copy, Clone, FFIFrom)]
1816#[ffi(ffi::cta::di_cta_hdmi_video_format)]
1817#[cfg(feature = "v0_3")]
1818pub struct HdmiVideoFormat {
1819    pub vic: u8,
1820    pub h_active: i32,
1821    pub v_active: i32,
1822    pub h_front: i32,
1823    pub v_front: i32,
1824    pub h_sync: i32,
1825    pub v_sync: i32,
1826    pub h_back: i32,
1827    pub v_back: i32,
1828    pub pixel_clock_hz: i64,
1829}
1830
1831#[cfg(feature = "v0_3")]
1832impl HdmiVideoFormat {
1833    /// Get a HDMI video format from a HDMI VIC.
1834    ///
1835    /// Returns `None` if the HDMI VIC is unknown.
1836    pub fn from_vic(hdmi_vic: u8) -> Option<Self> {
1837        HdmiVideoFormat::from_ptr(unsafe {
1838            ffi::cta::di_cta_hdmi_video_format_from_hdmi_vic(hdmi_vic)
1839        })
1840    }
1841}
1842
1843/// HDR10+ Vendor-Specific Video Data Block
1844#[derive(Debug, Copy, Clone, FFIFrom)]
1845#[ffi(ffi::cta::di_cta_hdr10plus_block)]
1846#[cfg(feature = "v0_3")]
1847pub struct HDR10PlusBlock {
1848    pub version: ::std::os::raw::c_int,
1849    pub peak_lum: ::std::os::raw::c_int,
1850    pub ff_peak_lum: ::std::os::raw::c_int,
1851}
1852
1853/// Dolby Video Colorimetry
1854#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1855#[ffi(ffi::cta::di_cta_dolby_video_colorimetry)]
1856#[repr(u32)]
1857#[cfg(feature = "v0_3")]
1858pub enum DolbyVideoColorimetry {
1859    BT709 = ffi::cta::di_cta_dolby_video_colorimetry_DI_CTA_DOLBY_VIDEO_COLORIMETRY_BT_709,
1860    P3D65 = ffi::cta::di_cta_dolby_video_colorimetry_DI_CTA_DOLBY_VIDEO_COLORIMETRY_P3_D65,
1861}
1862
1863/// Dolby Video YUV 4:4:4 support
1864#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1865#[ffi(ffi::cta::di_cta_dolby_video_yuv444)]
1866#[repr(u32)]
1867#[cfg(feature = "v0_3")]
1868pub enum DolbyVideoYuv444 {
1869    None = ffi::cta::di_cta_dolby_video_yuv444_DI_CTA_DOLBY_VIDEO_YUV444_NONE,
1870    _10Bits = ffi::cta::di_cta_dolby_video_yuv444_DI_CTA_DOLBY_VIDEO_YUV444_10_BITS,
1871    _12Bits = ffi::cta::di_cta_dolby_video_yuv444_DI_CTA_DOLBY_VIDEO_YUV444_12_BITS,
1872}
1873
1874/// Dolby Video Version 0 Data
1875#[derive(Debug, Copy, Clone, FFIFrom)]
1876#[ffi(ffi::cta::di_cta_dolby_video_block_v0)]
1877#[cfg(feature = "v0_3")]
1878pub struct DolbyVideoBlockV0 {
1879    pub yuv422_12bit: bool,
1880    pub global_dimming: bool,
1881    pub supports_2160p60: bool,
1882    pub dynamic_metadata_version_major: i32,
1883    pub dynamic_metadata_version_minor: i32,
1884    pub target_pq_12b_level_min: i32,
1885    pub target_pq_12b_level_max: i32,
1886    pub red_x: f64,
1887    pub red_y: f64,
1888    pub green_x: f64,
1889    pub green_y: f64,
1890    pub blue_x: f64,
1891    pub blue_y: f64,
1892    pub white_x: f64,
1893    pub white_y: f64,
1894}
1895
1896/// Dolby Video Version 1 Data
1897#[derive(Debug, Copy, Clone, FFIFrom)]
1898#[ffi(ffi::cta::di_cta_dolby_video_block_v1)]
1899#[cfg(feature = "v0_3")]
1900pub struct DolbyVideoBlockV1 {
1901    pub yuv422_12bit: bool,
1902    pub global_dimming: bool,
1903    pub supports_2160p60: bool,
1904    pub dynamic_metadata_version: i32,
1905    pub colorimetry: DolbyVideoColorimetry,
1906    pub target_luminance_min: f64,
1907    pub target_luminance_max: f64,
1908    pub mode_low_latency: bool,
1909    pub unique_primaries: bool,
1910    pub red_x: f64,
1911    pub red_y: f64,
1912    pub green_x: f64,
1913    pub green_y: f64,
1914    pub blue_x: f64,
1915    pub blue_y: f64,
1916}
1917
1918/// Dolby Video Version 2 Data
1919#[derive(Debug, Copy, Clone, FFIFrom)]
1920#[ffi(ffi::cta::di_cta_dolby_video_block_v2)]
1921#[cfg(feature = "v0_3")]
1922pub struct DolbyVideoBlockV2 {
1923    pub yuv422_12bit: bool,
1924    pub global_dimming: bool,
1925    pub dynamic_metadata_version: i32,
1926    pub backlight_control: bool,
1927    pub backlight_luminance_min: f64,
1928    pub mode_standard: bool,
1929    pub mode_low_latency_hdmi: bool,
1930    pub yuv444: DolbyVideoYuv444,
1931    pub target_pq_12b_level_min: i32,
1932    pub target_pq_12b_level_max: i32,
1933    pub red_x: f64,
1934    pub red_y: f64,
1935    pub green_x: f64,
1936    pub green_y: f64,
1937    pub blue_x: f64,
1938    pub blue_y: f64,
1939}
1940
1941/// Dolby Video Data Block version
1942#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
1943#[ffi(ffi::cta::di_cta_dolby_video_version)]
1944#[repr(u32)]
1945#[cfg(feature = "v0_3")]
1946pub enum DolbyVideoVersion {
1947    Version0 = ffi::cta::di_cta_dolby_video_version_DI_CTA_DOLBY_VIDEO_VERSION0,
1948    Version1 = ffi::cta::di_cta_dolby_video_version_DI_CTA_DOLBY_VIDEO_VERSION1,
1949    Version2 = ffi::cta::di_cta_dolby_video_version_DI_CTA_DOLBY_VIDEO_VERSION2,
1950}
1951
1952/// Dolby Video Data Block
1953#[derive(Debug, Copy, Clone, FFIFrom)]
1954#[ffi(ffi::cta::di_cta_dolby_video_block)]
1955#[cfg(feature = "v0_3")]
1956pub struct DolbyVideoBlock {
1957    pub version: DolbyVideoVersion,
1958    #[ptr_deref]
1959    pub v0: Option<DolbyVideoBlockV0>,
1960    #[ptr_deref]
1961    pub v1: Option<DolbyVideoBlockV1>,
1962    #[ptr_deref]
1963    pub v2: Option<DolbyVideoBlockV2>,
1964}
1965
1966/// Type VII Video Timing Data Block, defined in section 7.5.17.1
1967#[derive(Debug, Copy, Clone, FFIFrom)]
1968#[ffi(ffi::cta::di_cta_type_vii_timing_block)]
1969#[cfg(feature = "v0_3")]
1970pub struct VIITimingBlock {
1971    #[cast_as(*const ffi::displayid::di_displayid_type_i_ii_vii_timing)]
1972    #[ptr_deref]
1973    pub timing: Option<crate::displayid::TypeIIIVIITiming>,
1974}
1975
1976/// HDMI vendor-specific data block.
1977///
1978/// This block is defined in HDMI 1.4b section 8.3.2.
1979#[derive(Debug, Copy, Clone, FFIFrom)]
1980#[ffi(ffi::cta::di_cta_vendor_hdmi_block)]
1981#[cfg(feature = "v0_3")]
1982#[wrap]
1983pub struct VendorHdmiBlock {
1984    pub source_phys_addr: u16,
1985    pub supports_ai: bool,
1986    pub supports_dc_48bit: bool,
1987    pub supports_dc_36bit: bool,
1988    pub supports_dc_30bit: bool,
1989    pub supports_dc_y444: bool,
1990    pub supports_dvi_dual: bool,
1991    pub max_tmds_clock: ::std::os::raw::c_int,
1992    pub supports_content_graphics: bool,
1993    pub supports_content_photo: bool,
1994    pub supports_content_cinema: bool,
1995    pub supports_content_game: bool,
1996    /// If !has_latency and !has_interlaced_latency, we have no latency
1997    /// information at all.
1998    ///
1999    /// If only has_latency, video/audio latency fields are valid and
2000    /// should be used for both progressive and interlaced video/audio
2001    /// formats.
2002    ///
2003    /// If both are valid, it means that video_latency and audio_latency
2004    /// should be used for progressive video/audio formats, and their
2005    /// interlaced counterpart for interlaced formats.
2006    pub has_latency: bool,
2007    pub has_interlaced_latency: bool,
2008    pub supports_progressive_video: bool,
2009    pub supports_progressive_audio: bool,
2010    pub supports_interlaced_video: bool,
2011    pub supports_interlaced_audio: bool,
2012    pub progressive_video_latency: ::std::os::raw::c_int,
2013    pub progressive_audio_latency: ::std::os::raw::c_int,
2014    pub interlaced_video_latency: ::std::os::raw::c_int,
2015    pub interlaced_audio_latency: ::std::os::raw::c_int,
2016}
2017
2018#[cfg(feature = "v0_3")]
2019impl VendorHdmiBlockRef {
2020    /// Get the vics from the hdmi block.
2021    pub fn vics(&self) -> &[u8] {
2022        unsafe { std::slice::from_raw_parts((*self.0).vics, (*self.0).vics_len) }
2023    }
2024}
2025
2026/// Fixed Rate Link (FRL) support.
2027#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
2028#[ffi(ffi::cta::di_cta_hdmi_frl)]
2029#[repr(u32)]
2030#[cfg(feature = "v0_3")]
2031pub enum HdmiFrl {
2032    Unsupported = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_UNSUPPORTED,
2033    _3GBps3Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_3GBPS_3LANES,
2034    _6GBps3Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_6GBPS_3LANES,
2035    _6GBps4Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_6GBPS_4LANES,
2036    _8GBps4Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_8GBPS_4LANES,
2037    _10GBps4Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_10GBPS_4LANES,
2038    _12GBps4Lanes = ffi::cta::di_cta_hdmi_frl_DI_CTA_HDMI_FRL_12GBPS_4LANES,
2039}
2040
2041#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
2042#[ffi(ffi::cta::di_cta_hdmi_dsc_max_slices)]
2043#[repr(u32)]
2044#[cfg(feature = "v0_3")]
2045pub enum HdmiDscMaxSlices {
2046    Unsupported = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_UNSUPPORTED,
2047    _1_340MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_1_340MHZ,
2048    _2_340MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_2_340MHZ,
2049    _4_340MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_4_340MHZ,
2050    _8_340MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_8_340MHZ,
2051    _8_400MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_8_400MHZ,
2052    _12_400MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_12_400MHZ,
2053    _16_400MHZ = ffi::cta::di_cta_hdmi_dsc_max_slices_DI_CTA_HDMI_DSC_MAX_SLICES_16_400MHZ,
2054}
2055
2056/// Display Stream Compression (DSC) support.
2057#[derive(Debug, Copy, Clone, FFIFrom)]
2058#[ffi(ffi::cta::di_cta_hdmi_dsc)]
2059#[cfg(feature = "v0_3")]
2060pub struct HdmiDsc {
2061    pub supports_10bpc: bool,
2062    pub supports_12bpc: bool,
2063    pub supports_all_bpc: bool,
2064    pub supports_native_420: bool,
2065    pub max_slices: HdmiDscMaxSlices,
2066    pub max_frl_rate: HdmiFrl,
2067    pub max_total_chunk_bytes: i32,
2068}
2069
2070/// HDMI Sink Capability Data Structure (SCDS).
2071///
2072/// This data is exposed via HDMI Forum Vendor-Specific Data Block (HF-VSDB) or
2073/// the HDMI Forum Sink Capability Data Block (HF-SCDB).
2074#[derive(Debug, Copy, Clone, FFIFrom)]
2075#[ffi(ffi::cta::di_cta_hdmi_scds)]
2076#[cfg(feature = "v0_3")]
2077pub struct HdmiScds {
2078    pub version: ::std::os::raw::c_int,
2079    pub max_tmds_char_rate_mhz: ::std::os::raw::c_int,
2080    pub supports_3d_osd_disparity: bool,
2081    pub supports_3d_dual_view: bool,
2082    pub supports_3d_independent_view: bool,
2083    pub supports_lte_340mcsc_scramble: bool,
2084    pub supports_ccbpci: bool,
2085    pub supports_cable_status: bool,
2086    pub supports_scdc_read_request: bool,
2087    pub supports_scdc: bool,
2088    pub supports_dc_30bit_420: bool,
2089    pub supports_dc_36bit_420: bool,
2090    pub supports_dc_48bit_420: bool,
2091    pub supports_uhd_vic: bool,
2092    pub max_frl_rate: HdmiFrl,
2093    pub supports_fapa_start_location: bool,
2094    pub supports_allm: bool,
2095    pub supports_fva: bool,
2096    pub supports_neg_mvrr: bool,
2097    pub supports_cinema_vrr: bool,
2098    pub m_delta: bool,
2099    pub supports_qms: bool,
2100    pub supports_fapa_end_extended: bool,
2101    pub vrr_min_hz: ::std::os::raw::c_int,
2102    pub vrr_max_hz: ::std::os::raw::c_int,
2103    pub qms_tfr_min: bool,
2104    pub qms_tfr_max: bool,
2105    #[ptr_deref]
2106    pub dsc: Option<HdmiDsc>,
2107}
2108
2109/// HDMI Forum vendor-specific data block (HF-VSDB).
2110///
2111/// This block is defined in HDMI 2.1 section 10.3.2.
2112#[derive(Debug, Copy, Clone, FFIFrom)]
2113#[ffi(ffi::cta::di_cta_vendor_hdmi_forum_block)]
2114#[cfg(feature = "v0_3")]
2115pub struct VendorHdmiForumBlock {
2116    pub scds: HdmiScds,
2117}
2118
2119/// HDMI Forum Sink Capability Data Block (HF-SCDB).
2120///
2121/// This block is defined in HDMI 2.1a
2122#[derive(Debug, Copy, Clone, FFIFrom)]
2123#[ffi(ffi::cta::di_cta_hdmi_forum_sink_cap)]
2124#[cfg(feature = "v0_3")]
2125pub struct HdmiForumSinkCap {
2126    pub scds: HdmiScds,
2127}
2128
2129/// Video Format Preference Data Block, defined in section 7.5.12.
2130#[derive(Debug, Copy, Clone, FFIFrom)]
2131#[ffi(ffi::cta::di_cta_video_format_pref_block)]
2132#[wrap]
2133#[cfg(feature = "v0_3")]
2134pub struct VideoFormatPrefBlock {}
2135
2136#[cfg(feature = "v0_3")]
2137impl VideoFormatPrefBlockRef {
2138    /// Get the svrs of the pref block
2139    pub fn svrs(&self) -> impl Iterator<Item = Svr> {
2140        FFIIter::new(unsafe { (*self.0).svrs })
2141    }
2142}