Skip to main content

display_types/cea861/
capabilities.rs

1#[cfg(any(feature = "alloc", feature = "std"))]
2use crate::prelude::Vec;
3
4#[cfg(any(feature = "alloc", feature = "std"))]
5use super::{
6    ColorimetryBlock, HdmiForumSinkCap, HdmiVsdb, HdrDynamicMetadataDescriptor, HdrStaticMetadata,
7    InfoFrameDescriptor, RoomConfigurationBlock, ShortAudioDescriptor, SpeakerAllocation,
8    SpeakerLocationEntry, T7VtdbBlock, T8VtdbBlock, T10VtdbBlock, VendorSpecificBlock,
9    VesaDisplayDeviceBlock, VesaTransferCharacteristic, VideoCapability, VtbExtBlock,
10};
11
12bitflags::bitflags! {
13    /// Capability flags from byte 3 of a CEA-861 extension block.
14    ///
15    /// | Bit | Mask   | Meaning                  |
16    /// |-----|--------|--------------------------|
17    /// | 7   | `0x80` | Underscan support        |
18    /// | 6   | `0x40` | Basic audio support      |
19    /// | 5   | `0x20` | YCbCr 4:4:4 support      |
20    /// | 4   | `0x10` | YCbCr 4:2:2 support      |
21    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
23    pub struct Cea861Flags: u8 {
24        /// The display supports underscan.
25        const UNDERSCAN   = 0x80;
26        /// The display supports basic audio.
27        const BASIC_AUDIO = 0x40;
28        /// The display supports YCbCr 4:4:4 color encoding.
29        const YCBCR_444   = 0x20;
30        /// The display supports YCbCr 4:2:2 color encoding.
31        const YCBCR_422   = 0x10;
32    }
33}
34
35/// Decoded HDMI Audio Data Block (extended tag `0x12`).
36///
37/// Advertises HDMI-specific audio capabilities, including Multi-Stream Audio (MSA)
38/// support and a set of Short Audio Descriptors for the HDMI audio path.
39#[non_exhaustive]
40#[cfg(any(feature = "alloc", feature = "std"))]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct HdmiAudioBlock {
44    /// If `true`, the sink supports HDMI Multi-Stream Audio (MSA).
45    pub multi_stream_audio: bool,
46    /// Short Audio Descriptors for the HDMI audio path (eARC-capable formats, etc.).
47    pub audio_descriptors: Vec<ShortAudioDescriptor>,
48}
49
50#[cfg(any(feature = "alloc", feature = "std"))]
51impl HdmiAudioBlock {
52    /// Constructs an `HdmiAudioBlock`.
53    pub fn new(multi_stream_audio: bool, audio_descriptors: Vec<ShortAudioDescriptor>) -> Self {
54        Self {
55            multi_stream_audio,
56            audio_descriptors,
57        }
58    }
59}
60
61/// Decoded capabilities from a CEA-861 extension block.
62///
63/// Stored in `DisplayCapabilities::extension_data` under tag `0x02` by the CEA-861
64/// extension handler. Retrieve it with `caps.get_extension_data::<Cea861Capabilities>(0x02)`.
65#[non_exhaustive]
66#[cfg(any(feature = "alloc", feature = "std"))]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68#[derive(Debug, Clone, PartialEq)] // no Eq: HdrStaticMetadata contains f32
69pub struct Cea861Capabilities {
70    /// Capability flags from byte 3 of the CEA-861 header.
71    pub flags: Cea861Flags,
72    /// Short Video Descriptors from the CEA Video Data Block (tag `0x02`).
73    ///
74    /// Each entry is `(vic_number, is_native)`. VICs beyond the range of the
75    /// built-in lookup table are included here but do not produce an entry in
76    /// `DisplayCapabilities::supported_modes`.
77    pub vics: Vec<(u8, bool)>,
78    /// Short Audio Descriptors from the CEA Audio Data Block (tag `0x01`).
79    pub audio_descriptors: Vec<ShortAudioDescriptor>,
80    /// Decoded HDMI 1.x Vendor-Specific Data Block (OUI `0x000C03`), if present.
81    pub hdmi_vsdb: Option<HdmiVsdb>,
82    /// Decoded HDMI Forum Vendor-Specific Data Block (OUI `0xC45DD8`), if present.
83    ///
84    /// Carries the same HDMI Forum Sink Capability Data Structure (SCDS) as
85    /// `hf_scdb`. Typically found on HDMI 2.0 sinks; HDMI 2.1 sinks
86    /// more commonly use the HF-SCDB (extended tag `0x79`) instead.
87    pub hf_vsdb: Option<HdmiForumSinkCap>,
88    /// Decoded Video Capability Data Block (extended tag `0x00`), if present.
89    pub video_capability: Option<VideoCapability>,
90    /// Decoded Colorimetry Data Block (extended tag `0x05`), if present.
91    pub colorimetry: Option<ColorimetryBlock>,
92    /// Decoded HDR Static Metadata Data Block (extended tag `0x06`), if present.
93    pub hdr_static_metadata: Option<HdrStaticMetadata>,
94    /// Decoded HDMI Audio Data Block (extended tag `0x12`), if present.
95    pub hdmi_audio: Option<HdmiAudioBlock>,
96    /// InfoFrame descriptors from the InfoFrame Data Block (extended tag `0x20`).
97    pub infoframe_descriptors: Vec<InfoFrameDescriptor>,
98    /// Decoded Room Configuration Data Block (extended tag `0x13`), if present.
99    pub room_configuration: Option<RoomConfigurationBlock>,
100    /// Speaker location entries from the Speaker Location Data Block (extended tag `0x14`).
101    pub speaker_locations: Vec<SpeakerLocationEntry>,
102    /// Decoded VESA Display Transfer Characteristic Data Block (standard tag `0x05`), if present.
103    pub vesa_transfer_characteristic: Option<VesaTransferCharacteristic>,
104    /// Decoded Speaker Allocation Data Block (standard tag `0x04`), if present.
105    pub speaker_allocation: Option<SpeakerAllocation>,
106    /// HDR Dynamic Metadata application descriptors (extended tag `0x07`).
107    pub hdr_dynamic_metadata: Vec<HdrDynamicMetadataDescriptor>,
108    /// Raw Short Video References from the Video Format Preference Data Block
109    /// (extended tag `0x0D`), if present.
110    pub video_format_preferences: Vec<u8>,
111    /// VICs from the YCbCr 4:2:0 Video Data Block (extended tag `0x0E`).
112    pub y420_vics: Vec<u8>,
113    /// Raw capability bitmap from the YCbCr 4:2:0 Capability Map Data Block
114    /// (extended tag `0x0F`).
115    pub y420_capability_map: Vec<u8>,
116    /// Decoded VESA Display Device Data Block (extended tag `0x02`), if present.
117    pub vesa_display_device: Option<VesaDisplayDeviceBlock>,
118    /// Additional timing modes from VESA Video Timing Block Extension blocks
119    /// (extended tag `0x03`).
120    pub vtb_ext: Vec<VtbExtBlock>,
121    /// Vendor-Specific Video Data Blocks (extended tag `0x01`).
122    pub vendor_specific_video: Vec<VendorSpecificBlock>,
123    /// Vendor-Specific Audio Data Blocks (extended tag `0x11`).
124    pub vendor_specific_audio: Vec<VendorSpecificBlock>,
125    /// DisplayID Type VII Video Timing Data Blocks (extended tag `0x22`).
126    pub t7_vtdb: Vec<T7VtdbBlock>,
127    /// DisplayID Type VIII Video Timing Data Blocks (extended tag `0x23`).
128    pub t8_vtdb: Vec<T8VtdbBlock>,
129    /// DisplayID Type X Video Timing Data Blocks (extended tag `0x2A`).
130    pub t10_vtdb: Vec<T10VtdbBlock>,
131    /// Extension block count from the HDMI Forum EDID Extension Override Data Block
132    /// (extended tag `0x78`), if present.
133    pub hf_eeodb_extension_count: Option<u8>,
134    /// HDMI Forum Sink Capability Data Block (extended tag `0x79`), if present.
135    pub hf_scdb: Option<HdmiForumSinkCap>,
136}
137
138#[cfg(any(feature = "alloc", feature = "std"))]
139impl Cea861Capabilities {
140    /// Constructs a zeroed `Cea861Capabilities` with the given header flags.
141    ///
142    /// All `Vec` fields are initialized empty and all `Option` fields are `None`.
143    /// Callers populate the fields after construction.
144    pub fn new(flags: Cea861Flags) -> Self {
145        Self {
146            flags,
147            vics: Vec::new(),
148            audio_descriptors: Vec::new(),
149            hdmi_vsdb: None,
150            hf_vsdb: None,
151            video_capability: None,
152            colorimetry: None,
153            hdr_static_metadata: None,
154            hdmi_audio: None,
155            infoframe_descriptors: Vec::new(),
156            room_configuration: None,
157            speaker_locations: Vec::new(),
158            vesa_transfer_characteristic: None,
159            speaker_allocation: None,
160            hdr_dynamic_metadata: Vec::new(),
161            video_format_preferences: Vec::new(),
162            y420_vics: Vec::new(),
163            y420_capability_map: Vec::new(),
164            vesa_display_device: None,
165            vtb_ext: Vec::new(),
166            vendor_specific_video: Vec::new(),
167            vendor_specific_audio: Vec::new(),
168            t7_vtdb: Vec::new(),
169            t8_vtdb: Vec::new(),
170            t10_vtdb: Vec::new(),
171            hf_eeodb_extension_count: None,
172            hf_scdb: None,
173        }
174    }
175}