mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-12-25 21:59:08 +01:00
cta: add support for VESA Display Transfer Characteristic data block
Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
This commit is contained in:
parent
78b4f0eb68
commit
11f48480d8
4 changed files with 115 additions and 0 deletions
36
cta.c
36
cta.c
|
@ -214,6 +214,29 @@ parse_hdr_static_metadata_block(struct di_edid_cta *cta,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_vesa_transfer_characteristics_block(struct di_edid_cta *cta,
|
||||
struct di_cta_vesa_transfer_characteristics *tf,
|
||||
const uint8_t *data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (size != 7 && size != 15 && size != 31) {
|
||||
add_failure(cta, "Invalid length %u.", size);
|
||||
return false;
|
||||
}
|
||||
|
||||
tf->points_len = (uint8_t) size + 1;
|
||||
tf->usage = get_bit_range(data[0], 7, 6);
|
||||
|
||||
tf->points[0] = get_bit_range(data[0], 5, 0) / 1023.0f;
|
||||
for (i = 1; i < size; i++)
|
||||
tf->points[i] = tf->points[i - 1] + data[i] / 1023.0f;
|
||||
tf->points[i] = 1.0f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_data_block(struct di_cta_data_block *data_block)
|
||||
{
|
||||
|
@ -262,6 +285,10 @@ parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data,
|
|||
break;
|
||||
case 5:
|
||||
tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC;
|
||||
if (!parse_vesa_transfer_characteristics_block(cta,
|
||||
&data_block->vesa_transfer_characteristics,
|
||||
data, size))
|
||||
goto error;
|
||||
break;
|
||||
case 7:
|
||||
/* Use Extended Tag */
|
||||
|
@ -536,3 +563,12 @@ di_edid_cta_get_detailed_timing_defs(const struct di_edid_cta *cta)
|
|||
{
|
||||
return (const struct di_edid_detailed_timing_def *const *) cta->detailed_timing_defs;
|
||||
}
|
||||
|
||||
const struct di_cta_vesa_transfer_characteristics *
|
||||
di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block *block)
|
||||
{
|
||||
if (block->tag != DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC) {
|
||||
return NULL;
|
||||
}
|
||||
return &block->vesa_transfer_characteristics;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
static struct {
|
||||
bool color_point_descriptor;
|
||||
bool color_management_data;
|
||||
bool cta_transfer_characteristics;
|
||||
} contains_uncommon_feature;
|
||||
|
||||
static size_t num_detailed_timing_defs = 0;
|
||||
|
@ -703,6 +704,34 @@ print_cta_hdr_static_metadata(const struct di_cta_hdr_static_metadata_block *met
|
|||
metadata->desired_content_min_luminance);
|
||||
}
|
||||
|
||||
static void
|
||||
print_cta_vesa_transfer_characteristics(const struct di_cta_vesa_transfer_characteristics *tf)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
switch (tf->usage) {
|
||||
case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_WHITE:
|
||||
printf(" White");
|
||||
break;
|
||||
case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_RED:
|
||||
printf(" Red");
|
||||
break;
|
||||
case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_GREEN:
|
||||
printf(" Green");
|
||||
break;
|
||||
case DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_BLUE:
|
||||
printf(" Blue");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" transfer characteristics:");
|
||||
for (i = 0; i < tf->points_len; i++)
|
||||
printf(" %u", (uint16_t) (tf->points[i] * 1023.0f));
|
||||
printf("\n");
|
||||
|
||||
contains_uncommon_feature.cta_transfer_characteristics = true;
|
||||
}
|
||||
|
||||
static const char *
|
||||
cta_data_block_tag_name(enum di_cta_data_block_tag tag)
|
||||
{
|
||||
|
@ -781,6 +810,7 @@ print_cta(const struct di_edid_cta *cta)
|
|||
const struct di_cta_video_cap_block *video_cap;
|
||||
const struct di_cta_colorimetry_block *colorimetry;
|
||||
const struct di_cta_hdr_static_metadata_block *hdr_static_metadata;
|
||||
const struct di_cta_vesa_transfer_characteristics *transfer_characteristics;
|
||||
size_t i;
|
||||
const struct di_edid_detailed_timing_def *const *detailed_timing_defs;
|
||||
|
||||
|
@ -858,6 +888,10 @@ print_cta(const struct di_edid_cta *cta)
|
|||
hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(data_block);
|
||||
print_cta_hdr_static_metadata(hdr_static_metadata);
|
||||
break;
|
||||
case DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC:
|
||||
transfer_characteristics = di_cta_data_block_get_vesa_transfer_characteristics(data_block);
|
||||
print_cta_vesa_transfer_characteristics(transfer_characteristics);
|
||||
break;
|
||||
default:
|
||||
break; /* Ignore */
|
||||
}
|
||||
|
@ -1312,6 +1346,11 @@ main(int argc, char *argv[])
|
|||
"Management Data Descriptor. Please share the "
|
||||
"EDID blob with upstream!\n");
|
||||
}
|
||||
if (contains_uncommon_feature.cta_transfer_characteristics) {
|
||||
fprintf(stderr, "The EDID blob contains an uncommon CTA VESA "
|
||||
"Display Transfer Characteristic data block. "
|
||||
"Please share the EDID blob with upstream!\n");
|
||||
}
|
||||
|
||||
di_info_destroy(info);
|
||||
return failure_msg ? 254 : 0;
|
||||
|
|
|
@ -72,6 +72,8 @@ struct di_cta_data_block {
|
|||
struct di_cta_colorimetry_block colorimetry;
|
||||
/* Used for DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA */
|
||||
struct di_cta_hdr_static_metadata_block_priv hdr_static_metadata;
|
||||
/* Used for DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC */
|
||||
struct di_cta_vesa_transfer_characteristics vesa_transfer_characteristics;
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
@ -259,6 +259,44 @@ struct di_cta_svd {
|
|||
const struct di_cta_svd *const *
|
||||
di_cta_data_block_get_svds(const struct di_cta_data_block *block);
|
||||
|
||||
enum di_cta_vesa_transfer_characteristics_usage {
|
||||
/* White transfer characteristic */
|
||||
DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_WHITE = 0,
|
||||
/* Red transfer characteristic */
|
||||
DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_RED = 1,
|
||||
/* Green transfer characteristic */
|
||||
DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_GREEN = 2,
|
||||
/* Blue transfer characteristic */
|
||||
DI_CTA_VESA_TRANSFER_CHARACTERISTIC_USAGE_BLUE = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* VESA Display Transfer Characteristic Data Block, defined in VESA Display
|
||||
* Transfer Characteristics Data Block Standard Version 1.0
|
||||
*
|
||||
* Contains 8, 16 or 32 evenly distributed points on the input axis describing
|
||||
* the normalized relative luminance at that input. The first value includes the
|
||||
* relative black level luminance.
|
||||
*/
|
||||
struct di_cta_vesa_transfer_characteristics {
|
||||
enum di_cta_vesa_transfer_characteristics_usage usage;
|
||||
uint8_t points_len;
|
||||
float points[32];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the Display Transfer Characteristic from a CTA data block.
|
||||
*
|
||||
* Returns NULL if the data block tag is not
|
||||
* DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC.
|
||||
*
|
||||
* Upstream is not aware of any EDID blob containing a Display Transfer
|
||||
* Characteristic data block.
|
||||
* If such a blob is found, please share it with upstream!
|
||||
*/
|
||||
const struct di_cta_vesa_transfer_characteristics *
|
||||
di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block *block);
|
||||
|
||||
/**
|
||||
* Get a list of EDID detailed timing definitions.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue