mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-11-16 19:48:30 +01:00
info: add di_info_get_hdr_static_metadata()
The low-level struct di_cta_hdr_static_metadata_block is essentially duplicated in struct di_hdr_static_metadata to make the high-level API independent of low-level API headers. It's also simpler in form, while new fields can still be added in the end while maintaining ABI backward compatibility. If new sources for HDR static metadata appear, they can be parsed into this same structure in the future when compatible. Wayland compositors will be interested in this. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
ef69f6276c
commit
f2c1b01bd2
3 changed files with 131 additions and 0 deletions
|
@ -12,6 +12,7 @@
|
|||
* struct di_info. These are exposed by the high-level API only.
|
||||
*/
|
||||
struct di_derived_info {
|
||||
struct di_hdr_static_metadata hdr_static_metadata;
|
||||
struct di_color_primaries color_primaries;
|
||||
};
|
||||
|
||||
|
|
|
@ -103,6 +103,49 @@ di_info_get_model(const struct di_info *info);
|
|||
char *
|
||||
di_info_get_serial(const struct di_info *info);
|
||||
|
||||
/**
|
||||
* Display HDR static metadata
|
||||
*/
|
||||
struct di_hdr_static_metadata {
|
||||
/* Desired content max luminance (cd/m²), zero if unset */
|
||||
float desired_content_max_luminance;
|
||||
/* Desired content max frame-average luminance (cd/m²), zero if unset */
|
||||
float desired_content_max_frame_avg_luminance;
|
||||
/* Desired content min luminance (cd/m²), zero if unset */
|
||||
float desired_content_min_luminance;
|
||||
|
||||
/* Supported metadata types: */
|
||||
|
||||
/* Static Metadata Type 1 */
|
||||
bool type1;
|
||||
|
||||
/* Supported EOFTs: */
|
||||
|
||||
/* Traditional gamma - SDR luminance range */
|
||||
bool traditional_sdr;
|
||||
/* Traditional gamma - HDR luminance range */
|
||||
bool traditional_hdr;
|
||||
/* Perceptual Quantization (PQ) based on SMPTE ST 2084 */
|
||||
bool pq;
|
||||
/* Hybrid Log-Gamma (HLG) based on Rec. ITU-R BT.2100 */
|
||||
bool hlg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get HDR static metadata support information as defined in ANSI/CTA-861-H
|
||||
* as HDR Static Metadata Data Block.
|
||||
*
|
||||
* The returned pointer is owned by the struct di_info passed in. It remains
|
||||
* valid only as long as the di_info exists, and must not be freed by the
|
||||
* caller.
|
||||
*
|
||||
* This function does not return NULL. When HDR static metadata does not exist,
|
||||
* all luminance fields are zero and only traditional_sdr is flagged as
|
||||
* supported.
|
||||
*/
|
||||
const struct di_hdr_static_metadata *
|
||||
di_info_get_hdr_static_metadata(const struct di_info *info);
|
||||
|
||||
/** CIE 1931 2-degree observer chromaticity coordinates */
|
||||
struct di_chromaticity_cie1931 {
|
||||
float x;
|
||||
|
|
87
info.c
87
info.c
|
@ -2,6 +2,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "edid.h"
|
||||
#include "info.h"
|
||||
|
@ -11,6 +12,85 @@
|
|||
const char *
|
||||
pnp_id_table(const char *key);
|
||||
|
||||
static bool
|
||||
di_cta_data_block_allowed_multiple(enum di_cta_data_block_tag tag)
|
||||
{
|
||||
/* See CTA-861-H, 7.6 Multiple Instances of Data Blocks. */
|
||||
switch (tag) {
|
||||
case DI_CTA_DATA_BLOCK_SPEAKER_ALLOC:
|
||||
case DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC:
|
||||
case DI_CTA_DATA_BLOCK_VIDEO_CAP:
|
||||
case DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE:
|
||||
case DI_CTA_DATA_BLOCK_COLORIMETRY:
|
||||
case DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA:
|
||||
case DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF:
|
||||
case DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP:
|
||||
case DI_CTA_DATA_BLOCK_HDMI_AUDIO:
|
||||
case DI_CTA_DATA_BLOCK_ROOM_CONFIG:
|
||||
case DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE:
|
||||
case DI_CTA_DATA_BLOCK_HDMI_SINK_CAP:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct di_cta_data_block *
|
||||
di_edid_get_cta_data_block(const struct di_edid *edid,
|
||||
enum di_cta_data_block_tag tag)
|
||||
{
|
||||
const struct di_edid_ext *const *ext;
|
||||
|
||||
/*
|
||||
* Here we do not handle blocks that are allowed to occur in
|
||||
* multiple instances.
|
||||
*/
|
||||
assert(!di_cta_data_block_allowed_multiple(tag));
|
||||
|
||||
for (ext = di_edid_get_extensions(edid); *ext; ext++) {
|
||||
const struct di_edid_cta *cta;
|
||||
const struct di_cta_data_block *const *block;
|
||||
|
||||
if (di_edid_ext_get_tag(*ext) != DI_EDID_EXT_CEA)
|
||||
continue;
|
||||
|
||||
cta = di_edid_ext_get_cta(*ext);
|
||||
for (block = di_edid_cta_get_data_blocks(cta); *block; block++) {
|
||||
if (di_cta_data_block_get_tag(*block) == tag)
|
||||
return *block;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
derive_edid_hdr_static_metadata(const struct di_edid *edid,
|
||||
struct di_hdr_static_metadata *hsm)
|
||||
{
|
||||
const struct di_cta_data_block *block;
|
||||
const struct di_cta_hdr_static_metadata_block *cta_hsm;
|
||||
|
||||
/* By default, everything unset and only traditional gamma supported. */
|
||||
hsm->traditional_sdr = true;
|
||||
|
||||
block = di_edid_get_cta_data_block(edid, DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA);
|
||||
if (!block)
|
||||
return;
|
||||
|
||||
cta_hsm = di_cta_data_block_get_hdr_static_metadata(block);
|
||||
assert(cta_hsm);
|
||||
|
||||
hsm->desired_content_max_luminance = cta_hsm->desired_content_max_luminance;
|
||||
hsm->desired_content_max_frame_avg_luminance = cta_hsm->desired_content_max_frame_avg_luminance;
|
||||
hsm->desired_content_min_luminance = cta_hsm->desired_content_min_luminance;
|
||||
hsm->type1 = cta_hsm->descriptors->type1;
|
||||
hsm->traditional_sdr = cta_hsm->eotfs->traditional_sdr;
|
||||
hsm->traditional_hdr = cta_hsm->eotfs->traditional_hdr;
|
||||
hsm->pq = cta_hsm->eotfs->pq;
|
||||
hsm->hlg = cta_hsm->eotfs->hlg;
|
||||
}
|
||||
|
||||
static void
|
||||
derive_edid_color_primaries(const struct di_edid *edid,
|
||||
struct di_color_primaries *cc)
|
||||
|
@ -93,6 +173,7 @@ di_info_parse_edid(const void *data, size_t size)
|
|||
else
|
||||
free(failure_msg_str);
|
||||
|
||||
derive_edid_hdr_static_metadata(info->edid, &info->derived.hdr_static_metadata);
|
||||
derive_edid_color_primaries(info->edid, &info->derived.color_primaries);
|
||||
|
||||
return info;
|
||||
|
@ -252,6 +333,12 @@ di_info_get_serial(const struct di_info *info)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_hdr_static_metadata *
|
||||
di_info_get_hdr_static_metadata(const struct di_info *info)
|
||||
{
|
||||
return &info->derived.hdr_static_metadata;
|
||||
}
|
||||
|
||||
const struct di_color_primaries *
|
||||
di_info_get_default_color_primaries(const struct di_info *info)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue