displayid: add support for display parameters data block

Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
Simon Ser 2022-09-29 17:06:24 +02:00
parent d7144ad9b9
commit cad7de92c7
5 changed files with 167 additions and 15 deletions

View file

@ -932,6 +932,39 @@ print_cta(const struct di_edid_cta *cta)
}
}
static void
print_displayid_display_params(const struct di_displayid_display_params *params)
{
printf(" Image size: %.1f mm x %.1f mm\n",
params->horiz_image_mm, params->vert_image_mm);
printf(" Display native pixel format: %dx%d\n",
params->horiz_pixels, params->vert_pixels);
printf(" Feature support flags:\n");
if (params->features->audio)
printf(" Audio support on video interface\n");
if (params->features->separate_audio_inputs)
printf(" Separate audio inputs provided\n");
if (params->features->audio_input_override)
printf(" Audio input override\n");
if (params->features->power_management)
printf(" Power management (DPM)\n");
if (params->features->fixed_timing)
printf(" Fixed timing\n");
if (params->features->fixed_pixel_format)
printf(" Fixed pixel format\n");
if (params->features->ai)
printf(" Support ACP, ISRC1, or ISRC2packets\n");
if (params->features->deinterlacing)
printf(" De-interlacing\n");
if (params->gamma != 0)
printf(" Gamma: %.2f\n", params->gamma);
printf(" Aspect ratio: %.2f\n", params->aspect_ratio);
printf(" Dynamic bpc native: %d\n", params->bits_per_color_native);
printf(" Dynamic bpc overall: %d\n", params->bits_per_color_overall);
}
static void
get_displayid_type_i_timing_aspect_ratio(enum di_displayid_type_i_timing_aspect_ratio ratio,
int *horiz, int *vert)
@ -1135,6 +1168,7 @@ print_displayid(const struct di_displayid *displayid)
const struct di_displayid_data_block *data_block;
enum di_displayid_data_block_tag tag;
size_t i;
const struct di_displayid_display_params *display_params;
printf(" Version: %d.%d\n", di_displayid_get_version(displayid),
di_displayid_get_revision(displayid));
@ -1150,6 +1184,10 @@ print_displayid(const struct di_displayid *displayid)
tag = di_displayid_data_block_get_tag(data_block);
printf(" %s:\n", displayid_data_block_tag_name(tag));
switch (tag) {
case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS:
display_params = di_displayid_data_block_get_display_params(data_block);
print_displayid_display_params(display_params);
break;
case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING:
print_displayid_type_i_timing_block(data_block);
break;

View file

@ -53,6 +53,49 @@ check_data_block_revision(struct di_displayid *displayid,
}
}
static bool
parse_display_params_block(struct di_displayid *displayid,
struct di_displayid_display_params_priv *priv,
const uint8_t *data, size_t size)
{
struct di_displayid_display_params *params = &priv->base;
uint8_t raw_features;
check_data_block_revision(displayid, data,
"Display Parameters Data Block",
0);
if (size != 0x0F) {
add_failure(displayid, "Display Parameters Data Block: DisplayID payload length is different than expected (%zu != %zu)", size, 0x0F);
return false;
}
params->horiz_image_mm = 0.1f * (float)(data[0x03] | (data[0x04] << 8));
params->vert_image_mm = 0.1f * (float)(data[0x05] | (data[0x06] << 8));
params->horiz_pixels = data[0x07] | (data[0x08] << 8);
params->vert_pixels = data[0x09] | (data[0x0A] << 8);
raw_features = data[0x0B];
params->features = &priv->features;
priv->features.audio = has_bit(raw_features, 7);
priv->features.separate_audio_inputs = has_bit(raw_features, 6);
priv->features.audio_input_override = has_bit(raw_features, 5);
priv->features.power_management = has_bit(raw_features, 4);
priv->features.fixed_timing = has_bit(raw_features, 3);
priv->features.fixed_pixel_format = has_bit(raw_features, 2);
priv->features.ai = has_bit(raw_features, 1);
priv->features.deinterlacing = has_bit(raw_features, 0);
if (data[0x0C] != 0xFF)
params->gamma = (float)data[0x0C] / 100 + 1;
params->aspect_ratio = (float)data[0x0D] / 100 + 1;
params->bits_per_color_overall = get_bit_range(data[0x0E], 7, 4) + 1;
params->bits_per_color_native = get_bit_range(data[0x0E], 3, 0) + 1;
return true;
}
static bool
parse_type_i_timing(struct di_displayid *displayid,
struct di_displayid_data_block *data_block,
@ -174,12 +217,17 @@ parse_data_block(struct di_displayid *displayid, const uint8_t *data,
goto error;
switch (tag) {
case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS:
if (!parse_display_params_block(displayid,
&data_block->display_params,
data, data_block_size))
goto error;
break;
case DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING:
if (!parse_type_i_timing_block(displayid, data_block, data, data_block_size))
goto error;
break;
case DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID:
case DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS:
case DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT:
case DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING:
case DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING:
@ -381,6 +429,15 @@ di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block
return data_block->tag;
}
const struct di_displayid_display_params *
di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block)
{
if (data_block->tag != DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS) {
return NULL;
}
return &data_block->display_params.base;
}
const struct di_displayid_type_i_timing *const *
di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *data_block)
{

View file

@ -38,12 +38,20 @@ struct di_displayid {
struct di_logger *logger;
};
struct di_displayid_display_params_priv {
struct di_displayid_display_params base;
struct di_displayid_display_params_features features;
};
struct di_displayid_data_block {
enum di_displayid_data_block_tag tag;
/* Used for TYPE_I_TIMING, NULL-terminated */
struct di_displayid_type_i_timing *type_i_timings[DISPLAYID_MAX_TYPE_I_TIMINGS + 1];
size_t type_i_timings_len;
/* Used for DISPLAY_PARAMS */
struct di_displayid_display_params_priv display_params;
};
bool

View file

@ -109,6 +109,57 @@ struct di_displayid_data_block;
enum di_displayid_data_block_tag
di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block);
/**
* Display parameters feature support flags, defined in section 4.2.3.
*/
struct di_displayid_display_params_features {
/* Audio support on video interface */
bool audio;
/* Audio inputs are provided separately from the video interface */
bool separate_audio_inputs;
/* Audio information received via the video interface will automatically
* override any other audio input channels provided */
bool audio_input_override;
/* Display supports the VESA Display Power Management (DPM) standard */
bool power_management;
/* Display is capable of only a single fixed timing */
bool fixed_timing;
/* Display is capable of supporting timings at only a single fixed pixel
* format */
bool fixed_pixel_format;
/* Display supports ACP, ISRC1 or ISRC2 packets */
bool ai;
/* Display by default will de-interlace any interlaced video input */
bool deinterlacing;
};
/**
* Display parameters data block, defined in section 4.2.
*/
struct di_displayid_display_params {
/* Image size in millimeters accurate to the thenths place, zero if unset */
float horiz_image_mm, vert_image_mm;
/* Native format size in pixels, zero if unset */
int32_t horiz_pixels, vert_pixels;
/* Feature flags */
const struct di_displayid_display_params_features *features;
/* Transfer characteristic gamma, zero if unset */
float gamma;
/* Aspect ratio (long axis divided by short axis) */
float aspect_ratio;
/* Color bit depth (dynamic range) */
int32_t bits_per_color_overall, bits_per_color_native;
};
/**
* Get display parameters from a DisplayID data block.
*
* Returns NULL if the data block tag isn't
* DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS.
*/
const struct di_displayid_display_params *
di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block);
enum di_displayid_type_i_timing_stereo_3d {
/* This timing is always displayed monoscopic (no stereo) */
DI_DISPLAYID_TYPE_I_TIMING_STEREO_3D_NEVER = 0x00,

View file

@ -1,6 +1,6 @@
--- ref
+++ di
@@ -62,44 +62,15 @@
@@ -62,16 +62,13 @@
DTD 6: 3840x2160 47.951737 Hz 16:9 134.696 kHz 528.010000 MHz (699 mm x 393 mm)
Hfront 8 Hsync 32 Hback 40 Hpol P
Vfront 59 Vsync 8 Vback 582 Vpol N
@ -16,14 +16,12 @@
- ContainerID Data Block:
- Container ID: dfde542f-1339-444b-ad7d-7071d131bff8
Display Parameters Data Block (0x01):
- Image size: 699.4 mm x 393.4 mm
- Display native pixel format: 6016x3384
- Feature support flags:
- Power management (DPM)
- Gamma: 2.20
- Aspect ratio: 1.78
- Dynamic bpc native: 12
- Dynamic bpc overall: 12
Image size: 699.4 mm x 393.4 mm
Display native pixel format: 6016x3384
@@ -81,25 +78,7 @@
Aspect ratio: 1.78
Dynamic bpc native: 12
Dynamic bpc overall: 12
- Vendor-Specific Data Block (0x7f) (Apple), OUI 00-10-FA:
- Type: 4, Version: 1
- 00 00 '..'
@ -46,7 +44,7 @@
Video Timing Modes Type 1 - Detailed Timings Data Block:
DTD: 3840x2160 59.999545 Hz 16:9 134.699 kHz 528.020000 MHz (aspect 16:9, no 3D stereo)
Hfront 8 Hsync 32 Hback 40 Hpol P
@@ -107,14 +78,12 @@
@@ -107,14 +86,12 @@
DTD: 3008x3384 59.999726 Hz 0:0 210.959 kHz 648.910000 MHz (aspect undefined, no 3D stereo)
Hfront 8 Hsync 32 Hback 28 Hpol P
Vfront 118 Vsync 8 Vback 6 Vpol N
@ -61,7 +59,7 @@
Video Timing Modes Type 1 - Detailed Timings Data Block:
DTD: 2560x2880 59.999451 Hz 0:0 179.578 kHz 481.270000 MHz (aspect undefined, no 3D stereo)
Hfront 8 Hsync 32 Hback 80 Hpol P
@@ -131,14 +100,12 @@
@@ -131,14 +108,12 @@
DTD: 2560x2880 47.951349 Hz 0:0 179.530 kHz 481.140000 MHz (aspect undefined, no 3D stereo)
Hfront 8 Hsync 32 Hback 80 Hpol P
Vfront 850 Vsync 8 Vback 6 Vpol N
@ -76,7 +74,7 @@
Video Timing Modes Type 1 - Detailed Timings Data Block:
DTD: 3008x3384 59.999726 Hz 0:0 210.959 kHz 648.910000 MHz (aspect undefined, no 3D stereo)
Hfront 8 Hsync 32 Hback 28 Hpol P
@@ -155,14 +122,12 @@
@@ -155,14 +130,12 @@
DTD: 3008x3384 47.951701 Hz 0:0 210.940 kHz 648.850000 MHz (aspect undefined, no 3D stereo)
Hfront 8 Hsync 32 Hback 28 Hpol P
Vfront 1001 Vsync 8 Vback 6 Vpol N
@ -91,7 +89,7 @@
Video Timing Modes Type 1 - Detailed Timings Data Block:
DTD: 5120x2880 59.999614 Hz 16:9 179.579 kHz 933.810000 MHz (aspect 16:9, no 3D stereo)
Hfront 8 Hsync 32 Hback 40 Hpol P
@@ -179,16 +144,14 @@
@@ -179,16 +152,14 @@
DTD: 5120x2880 47.951594 Hz 16:9 179.531 kHz 933.560000 MHz (aspect 16:9, no 3D stereo)
Hfront 8 Hsync 32 Hback 40 Hpol P
Vfront 850 Vsync 8 Vback 6 Vpol N
@ -109,7 +107,7 @@
Hfront 8 Hsync 32 Hback 40 Hpol P
Vfront 118 Vsync 8 Vback 6 Vpol N
DTD: 6016x3384 59.939891 Hz 16:9 210.928 kHz 1285.820000 MHz (aspect 16:9, no 3D stereo)
@@ -203,30 +166,13 @@
@@ -203,30 +174,13 @@
DTD: 6016x3384 47.951798 Hz 16:9 210.940 kHz 1285.890000 MHz (aspect 16:9, no 3D stereo)
Hfront 8 Hsync 32 Hback 40 Hpol P
Vfront 1001 Vsync 8 Vback 6 Vpol N