1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/// Decoded VESA Display Device Data Block (extended tag `0x02`).
///
/// A fixed 30-byte payload describing the physical and electrical characteristics
/// of the display, per the VESA Display Device Data Block (DDDB) Standard, Version 1.
#[non_exhaustive]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VesaDisplayDeviceBlock {
/// Interface type code (bits 7:4). 0=Analog, 1=LVDS, 3=DVI-D, 6=HDMI-A, 9=DP, etc.
pub interface_type: u8,
/// Number of lanes/channels (bits 3:0). For analog interfaces this is a subtype code.
pub num_links: u8,
/// Interface standard version (bits 7:4 of byte 0x03).
pub interface_version: u8,
/// Interface standard release (bits 3:0 of byte 0x03).
pub interface_release: u8,
/// Content protection code (byte 0x04). 0=none, 1=HDCP, 2=DTCP, 3=DPCP.
pub content_protection: u8,
/// Minimum supported clock frequency per link in MHz (6-bit, range 0–63).
pub min_clock_mhz: u8,
/// Maximum supported clock frequency per link in MHz (10-bit, range 0–1023).
pub max_clock_mhz: u16,
/// Native horizontal pixel count, or `None` if the display has no fixed format.
pub native_width: Option<u16>,
/// Native vertical pixel count, or `None` if the display has no fixed format.
pub native_height: Option<u16>,
/// Aspect ratio raw byte. Physical AR = (raw / 100.0) + 1.0 (long-axis / short-axis).
pub aspect_ratio_raw: u8,
/// Default orientation: 0=landscape, 1=portrait, 2=not_fixed, 3=undefined.
pub default_orientation: u8,
/// Rotation capability: 0=none, 1=90°CW, 2=90°CCW, 3=both.
pub rotation_capability: u8,
/// Zero pixel (scan origin) location: 0=upper-left, 1=upper-right, 2=lower-left, 3=lower-right.
pub zero_pixel_location: u8,
/// Scan direction: 0=undefined, 1=long-axis-fast, 2=short-axis-fast, 3=reserved.
pub scan_direction: u8,
/// Subpixel layout code (byte 0x0D). 0=undefined, 1=RGB-V, 2=RGB-H, etc.
pub subpixel_layout: u8,
/// Horizontal pixel pitch in 0.01 mm increments (range 0.00–2.55 mm).
pub h_pitch_hundredths_mm: u8,
/// Vertical pixel pitch in 0.01 mm increments (range 0.00–2.55 mm).
pub v_pitch_hundredths_mm: u8,
/// Dithering type: 0=none, 1=spatial, 2=temporal, 3=spatial+temporal.
pub dithering: u8,
/// Display is direct-drive — no internal scaling/de-interlacing/FRC.
pub direct_drive: bool,
/// Video source should not apply overdrive for this display.
pub overdrive_not_recommended: bool,
/// Display can de-interlace interlaced input to progressive scan.
pub deinterlacing: bool,
/// Audio is supported on the video interface.
pub audio_on_video_interface: bool,
/// Separate audio inputs are provided independently of the video interface.
pub separate_audio_inputs: bool,
/// Audio received on the video interface automatically overrides other audio inputs.
pub audio_input_override: bool,
/// Signed audio delay in milliseconds (positive = audio after video, negative = before).
/// `None` means no delay information is provided (raw delay byte was 0x00).
pub audio_delay_ms: Option<i16>,
/// Frame-rate conversion capability: 0=none, 1=single-buffer, 2=double-buffer, 3=interpolation.
pub frame_rate_conversion: u8,
/// Maximum excursion (±FPS) from the nominal frame rate (6 bits, 0–63).
pub frame_rate_range: u8,
/// Native or nominal display frame rate in frames/second.
pub native_frame_rate: u8,
/// Color bit depth per primary on the video interface (1–16).
pub interface_color_depth: u8,
/// Color bit depth per primary at the display panel without temporal dithering (1–16).
pub display_color_depth: u8,
/// Raw bytes 0x16–0x1D: chromaticity data for up to three additional primaries.
pub additional_chromaticities: [u8; 8],
/// Response time in milliseconds (0 = < 1 ms, 127 = > 126 ms).
pub response_time_ms: u8,
/// `true` if the response time is white-to-black; `false` if black-to-white.
pub response_time_white_to_black: bool,
/// Percentage of active image outside the visible screen area, horizontally (0–15%).
pub h_overscan_pct: u8,
/// Percentage of active image outside the visible screen area, vertically (0–15%).
pub v_overscan_pct: u8,
}
impl VesaDisplayDeviceBlock {
/// Constructs a `VesaDisplayDeviceBlock`.
#[allow(clippy::too_many_arguments)]
pub fn new(
interface_type: u8,
num_links: u8,
interface_version: u8,
interface_release: u8,
content_protection: u8,
min_clock_mhz: u8,
max_clock_mhz: u16,
native_width: Option<u16>,
native_height: Option<u16>,
aspect_ratio_raw: u8,
default_orientation: u8,
rotation_capability: u8,
zero_pixel_location: u8,
scan_direction: u8,
subpixel_layout: u8,
h_pitch_hundredths_mm: u8,
v_pitch_hundredths_mm: u8,
dithering: u8,
direct_drive: bool,
overdrive_not_recommended: bool,
deinterlacing: bool,
audio_on_video_interface: bool,
separate_audio_inputs: bool,
audio_input_override: bool,
audio_delay_ms: Option<i16>,
frame_rate_conversion: u8,
frame_rate_range: u8,
native_frame_rate: u8,
interface_color_depth: u8,
display_color_depth: u8,
additional_chromaticities: [u8; 8],
response_time_ms: u8,
response_time_white_to_black: bool,
h_overscan_pct: u8,
v_overscan_pct: u8,
) -> Self {
Self {
interface_type,
num_links,
interface_version,
interface_release,
content_protection,
min_clock_mhz,
max_clock_mhz,
native_width,
native_height,
aspect_ratio_raw,
default_orientation,
rotation_capability,
zero_pixel_location,
scan_direction,
subpixel_layout,
h_pitch_hundredths_mm,
v_pitch_hundredths_mm,
dithering,
direct_drive,
overdrive_not_recommended,
deinterlacing,
audio_on_video_interface,
separate_audio_inputs,
audio_input_override,
audio_delay_ms,
frame_rate_conversion,
frame_rate_range,
native_frame_rate,
interface_color_depth,
display_color_depth,
additional_chromaticities,
response_time_ms,
response_time_white_to_black,
h_overscan_pct,
v_overscan_pct,
}
}
}