mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-11-16 19:48:30 +01:00
cta: add support for video data blocks
Report the SVDs inside the video data block. We'll need to add additional APIs to get detailed SVD mode info in the future (with a SVD table). Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
parent
9806eb214e
commit
0c8673af02
5 changed files with 145 additions and 3 deletions
77
cta.c
77
cta.c
|
@ -43,6 +43,47 @@ add_failure_until(struct di_edid_cta *cta, int revision, const char fmt[], ...)
|
|||
va_end(args);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_video_block(struct di_edid_cta *cta, struct di_cta_video_block *video,
|
||||
const uint8_t *data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t raw;
|
||||
struct di_cta_svd svd, *svd_ptr;
|
||||
|
||||
if (size == 0)
|
||||
add_failure(cta, "Video Data Block: Empty Data Block");
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
raw = data[i];
|
||||
|
||||
if (raw == 0 || raw == 128 || raw >= 254) {
|
||||
/* Reserved */
|
||||
add_failure_until(cta, 3,
|
||||
"Video Data Block: Unknown VIC %" PRIu8 ".",
|
||||
raw);
|
||||
continue;
|
||||
} else if (raw <= 127 || raw >= 193) {
|
||||
svd = (struct di_cta_svd) {
|
||||
.vic = raw,
|
||||
};
|
||||
} else {
|
||||
svd = (struct di_cta_svd) {
|
||||
.vic = get_bit_range(raw, 6, 0),
|
||||
.native = true,
|
||||
};
|
||||
}
|
||||
|
||||
svd_ptr = calloc(1, sizeof(*svd_ptr));
|
||||
if (!svd_ptr)
|
||||
return false;
|
||||
*svd_ptr = svd;
|
||||
video->svds[video->svds_len++] = svd_ptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_colorimetry_block(struct di_edid_cta *cta,
|
||||
struct di_cta_colorimetry_block *colorimetry,
|
||||
|
@ -133,6 +174,25 @@ parse_hdr_static_metadata_block(struct di_edid_cta *cta,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_data_block(struct di_cta_data_block *data_block)
|
||||
{
|
||||
size_t i;
|
||||
struct di_cta_video_block *video;
|
||||
|
||||
switch (data_block->tag) {
|
||||
case DI_CTA_DATA_BLOCK_VIDEO:
|
||||
video = &data_block->video;
|
||||
for (i = 0; i < video->svds_len; i++)
|
||||
free(video->svds[i]);
|
||||
break;
|
||||
default:
|
||||
break; /* Nothing to do */
|
||||
}
|
||||
|
||||
free(data_block);
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data, size_t size)
|
||||
{
|
||||
|
@ -151,6 +211,8 @@ parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data,
|
|||
break;
|
||||
case 2:
|
||||
tag = DI_CTA_DATA_BLOCK_VIDEO;
|
||||
if (!parse_video_block(cta, &data_block->video, data, size))
|
||||
goto error;
|
||||
break;
|
||||
case 3:
|
||||
/* Vendor-Specific Data Block */
|
||||
|
@ -257,6 +319,10 @@ parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data,
|
|||
skip:
|
||||
free(data_block);
|
||||
return true;
|
||||
|
||||
error:
|
||||
destroy_data_block(data_block);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -352,7 +418,7 @@ _di_edid_cta_finish(struct di_edid_cta *cta)
|
|||
size_t i;
|
||||
|
||||
for (i = 0; i < cta->data_blocks_len; i++) {
|
||||
free(cta->data_blocks[i]);
|
||||
destroy_data_block(cta->data_blocks[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < cta->detailed_timing_defs_len; i++) {
|
||||
|
@ -384,6 +450,15 @@ di_cta_data_block_get_tag(const struct di_cta_data_block *block)
|
|||
return block->tag;
|
||||
}
|
||||
|
||||
const struct di_cta_svd *const *
|
||||
di_cta_data_block_get_svds(const struct di_cta_data_block *block)
|
||||
{
|
||||
if (block->tag != DI_CTA_DATA_BLOCK_VIDEO) {
|
||||
return NULL;
|
||||
}
|
||||
return (const struct di_cta_svd *const *) block->video.svds;
|
||||
}
|
||||
|
||||
const struct di_cta_colorimetry_block *
|
||||
di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block)
|
||||
{
|
||||
|
|
|
@ -474,6 +474,24 @@ display_color_type_name(enum di_edid_display_color_type type)
|
|||
abort();
|
||||
}
|
||||
|
||||
static void
|
||||
printf_cta_svds(const struct di_cta_svd *const *svds)
|
||||
{
|
||||
size_t i;
|
||||
const struct di_cta_svd *svd;
|
||||
|
||||
for (i = 0; svds[i] != NULL; i++) {
|
||||
svd = svds[i];
|
||||
|
||||
printf(" VIC %3" PRIu8, svd->vic);
|
||||
if (svd->native)
|
||||
printf(" (native)");
|
||||
printf("\n");
|
||||
|
||||
// TODO: print detailed mode info
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
encode_max_luminance(float max)
|
||||
{
|
||||
|
@ -580,6 +598,7 @@ print_cta(const struct di_edid_cta *cta)
|
|||
const struct di_cta_data_block *const *data_blocks;
|
||||
const struct di_cta_data_block *data_block;
|
||||
enum di_cta_data_block_tag data_block_tag;
|
||||
const struct di_cta_svd *const *svds;
|
||||
const struct di_cta_colorimetry_block *colorimetry;
|
||||
const struct di_cta_hdr_static_metadata_block *hdr_static_metadata;
|
||||
size_t i;
|
||||
|
@ -610,6 +629,10 @@ print_cta(const struct di_edid_cta *cta)
|
|||
printf(" %s:\n", cta_data_block_tag_name(data_block_tag));
|
||||
|
||||
switch (data_block_tag) {
|
||||
case DI_CTA_DATA_BLOCK_VIDEO:
|
||||
svds = di_cta_data_block_get_svds(data_block);
|
||||
printf_cta_svds(svds);
|
||||
break;
|
||||
case DI_CTA_DATA_BLOCK_COLORIMETRY:
|
||||
colorimetry = di_cta_data_block_get_colorimetry(data_block);
|
||||
if (colorimetry->xvycc_601)
|
||||
|
|
|
@ -19,6 +19,13 @@
|
|||
* 18 bytes.
|
||||
*/
|
||||
#define EDID_CTA_MAX_DETAILED_TIMING_DEFS 6
|
||||
/**
|
||||
* The maximum number of SVD entries in a video data block.
|
||||
*
|
||||
* Each data block has its size described in a 5-bit field, so its maximum size
|
||||
* is 63 bytes, and each SVD uses 1 byte.
|
||||
*/
|
||||
#define EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES 63
|
||||
|
||||
struct di_edid_cta {
|
||||
int revision;
|
||||
|
@ -41,9 +48,17 @@ struct di_cta_hdr_static_metadata_block_priv {
|
|||
struct di_cta_hdr_static_metadata_block_descriptors descriptors;
|
||||
};
|
||||
|
||||
struct di_cta_video_block {
|
||||
/* NULL-terminated */
|
||||
struct di_cta_svd *svds[EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES + 1];
|
||||
size_t svds_len;
|
||||
};
|
||||
|
||||
struct di_cta_data_block {
|
||||
enum di_cta_data_block_tag tag;
|
||||
|
||||
/* Used for DI_CTA_DATA_BLOCK_VIDEO */
|
||||
struct di_cta_video_block video;
|
||||
/* Used for DI_CTA_DATA_BLOCK_COLORIMETRY */
|
||||
struct di_cta_colorimetry_block colorimetry;
|
||||
/* Used for DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA */
|
||||
|
|
|
@ -199,6 +199,26 @@ struct di_cta_hdr_static_metadata_block {
|
|||
const struct di_cta_hdr_static_metadata_block *
|
||||
di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block);
|
||||
|
||||
/**
|
||||
* A Short Video Descriptor (SVD).
|
||||
*/
|
||||
struct di_cta_svd {
|
||||
/* Video Identification Code (VIC) */
|
||||
uint8_t vic;
|
||||
/* Whether this is a native video format */
|
||||
bool native;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an array of short video descriptors from a CTA data block.
|
||||
*
|
||||
* Returns NULL if the data block tag is not DI_CTA_DATA_BLOCK_VIDEO.
|
||||
*
|
||||
* The returned array is NULL-terminated.
|
||||
*/
|
||||
const struct di_cta_svd *const *
|
||||
di_cta_data_block_get_svds(const struct di_cta_data_block *block);
|
||||
|
||||
/**
|
||||
* Get a list of EDID detailed timing definitions.
|
||||
*
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
Detailed Timing Descriptors:
|
||||
DTD 1: 2560x1440 59.950550 Hz 16:9 88.787 kHz 241.500000 MHz (597 mm x 339 mm)
|
||||
Hfront 48 Hsync 32 Hback 80 Hpol P
|
||||
@@ -51,32 +51,7 @@
|
||||
@@ -51,32 +51,16 @@
|
||||
Supports YCbCr 4:2:2
|
||||
Native detailed modes: 1
|
||||
Video Data Block:
|
||||
|
@ -42,6 +42,15 @@
|
|||
- DC_30bit
|
||||
- DC_Y444
|
||||
- Maximum TMDS clock: 310 MHz
|
||||
+ VIC 16
|
||||
+ VIC 4
|
||||
+ VIC 3
|
||||
+ VIC 2
|
||||
+ VIC 31
|
||||
+ VIC 19
|
||||
+ VIC 18
|
||||
+ VIC 17
|
||||
+ VIC 1
|
||||
Video Capability Data Block:
|
||||
- YCbCr quantization: No Data
|
||||
- RGB quantization: No Data
|
||||
|
@ -56,7 +65,7 @@
|
|||
Colorimetry Data Block:
|
||||
BT2020cYCC
|
||||
BT2020YCC
|
||||
@@ -104,20 +79,8 @@
|
||||
@@ -104,20 +88,8 @@
|
||||
DTD 5: 1920x1080 74.972503 Hz 16:9 83.894 kHz 174.500000 MHz (597 mm x 339 mm)
|
||||
Hfront 48 Hsync 32 Hback 80 Hpol P
|
||||
Vfront 3 Vsync 5 Vback 31 Vpol N
|
||||
|
|
Loading…
Reference in a new issue