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;
|
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
|
static void
|
||||||
destroy_data_block(struct di_cta_data_block *data_block)
|
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;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC;
|
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;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
/* Use Extended Tag */
|
/* 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;
|
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 {
|
static struct {
|
||||||
bool color_point_descriptor;
|
bool color_point_descriptor;
|
||||||
bool color_management_data;
|
bool color_management_data;
|
||||||
|
bool cta_transfer_characteristics;
|
||||||
} contains_uncommon_feature;
|
} contains_uncommon_feature;
|
||||||
|
|
||||||
static size_t num_detailed_timing_defs = 0;
|
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);
|
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 *
|
static const char *
|
||||||
cta_data_block_tag_name(enum di_cta_data_block_tag tag)
|
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_video_cap_block *video_cap;
|
||||||
const struct di_cta_colorimetry_block *colorimetry;
|
const struct di_cta_colorimetry_block *colorimetry;
|
||||||
const struct di_cta_hdr_static_metadata_block *hdr_static_metadata;
|
const struct di_cta_hdr_static_metadata_block *hdr_static_metadata;
|
||||||
|
const struct di_cta_vesa_transfer_characteristics *transfer_characteristics;
|
||||||
size_t i;
|
size_t i;
|
||||||
const struct di_edid_detailed_timing_def *const *detailed_timing_defs;
|
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);
|
hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(data_block);
|
||||||
print_cta_hdr_static_metadata(hdr_static_metadata);
|
print_cta_hdr_static_metadata(hdr_static_metadata);
|
||||||
break;
|
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:
|
default:
|
||||||
break; /* Ignore */
|
break; /* Ignore */
|
||||||
}
|
}
|
||||||
|
@ -1312,6 +1346,11 @@ main(int argc, char *argv[])
|
||||||
"Management Data Descriptor. Please share the "
|
"Management Data Descriptor. Please share the "
|
||||||
"EDID blob with upstream!\n");
|
"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);
|
di_info_destroy(info);
|
||||||
return failure_msg ? 254 : 0;
|
return failure_msg ? 254 : 0;
|
||||||
|
|
|
@ -72,6 +72,8 @@ struct di_cta_data_block {
|
||||||
struct di_cta_colorimetry_block colorimetry;
|
struct di_cta_colorimetry_block colorimetry;
|
||||||
/* Used for DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA */
|
/* Used for DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA */
|
||||||
struct di_cta_hdr_static_metadata_block_priv 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
|
bool
|
||||||
|
|
|
@ -259,6 +259,44 @@ struct di_cta_svd {
|
||||||
const struct di_cta_svd *const *
|
const struct di_cta_svd *const *
|
||||||
di_cta_data_block_get_svds(const struct di_cta_data_block *block);
|
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.
|
* Get a list of EDID detailed timing definitions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue