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}