cta: add support for VESA Display Transfer Characteristic data block

Signed-off-by: Sebastian Wick <sebastian.wick@redhat.com>
This commit is contained in:
Sebastian Wick 2022-09-27 02:26:22 +02:00 committed by Sebastian Wick
parent 78b4f0eb68
commit 11f48480d8
4 changed files with 115 additions and 0 deletions

36
cta.c
View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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.
*