mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-11-16 19:48:30 +01:00
cta: add VIC table
Add a small Python tool to extract VIC information from the spec. Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
parent
5c2255047b
commit
b439985324
6 changed files with 2678 additions and 0 deletions
2472
cta-vic-table.c
Normal file
2472
cta-vic-table.c
Normal file
File diff suppressed because it is too large
Load diff
9
cta.c
9
cta.c
|
@ -23,6 +23,15 @@
|
||||||
*/
|
*/
|
||||||
#define CTA_SAD_SIZE 3
|
#define CTA_SAD_SIZE 3
|
||||||
|
|
||||||
|
const struct di_cta_video_format *
|
||||||
|
di_cta_video_format_from_vic(uint8_t vic)
|
||||||
|
{
|
||||||
|
if (vic > _di_cta_video_formats_len ||
|
||||||
|
_di_cta_video_formats[vic].vic == 0)
|
||||||
|
return NULL;
|
||||||
|
return &_di_cta_video_formats[vic];
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_failure(struct di_edid_cta *cta, const char fmt[], ...)
|
add_failure(struct di_edid_cta *cta, const char fmt[], ...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,6 +140,9 @@ struct di_cta_data_block {
|
||||||
struct di_cta_ycbcr420_cap_map ycbcr420_cap_map;
|
struct di_cta_ycbcr420_cap_map ycbcr420_cap_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct di_cta_video_format _di_cta_video_formats[];
|
||||||
|
extern const size_t _di_cta_video_formats_len;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
_di_edid_cta_parse(struct di_edid_cta *cta, const uint8_t *data, size_t size,
|
_di_edid_cta_parse(struct di_edid_cta *cta, const uint8_t *data, size_t size,
|
||||||
struct di_logger *logger);
|
struct di_logger *logger);
|
||||||
|
|
|
@ -13,6 +13,56 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTA video format picture aspect ratio.
|
||||||
|
*/
|
||||||
|
enum di_cta_video_format_picture_aspect_ratio {
|
||||||
|
DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_4_3, /* 4:3 */
|
||||||
|
DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_16_9, /* 16:9 */
|
||||||
|
DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_64_27, /* 64:27 */
|
||||||
|
DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_256_135, /* 256:135 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CTA video format sync pulse polarity.
|
||||||
|
*/
|
||||||
|
enum di_cta_video_format_sync_polarity {
|
||||||
|
DI_CTA_VIDEO_FORMAT_SYNC_NEGATIVE, /* Negative */
|
||||||
|
DI_CTA_VIDEO_FORMAT_SYNC_POSITIVE, /* Positive */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A CTA-861 video format, defined in section 4.
|
||||||
|
*/
|
||||||
|
struct di_cta_video_format {
|
||||||
|
/* Video Identification Code (VIC) */
|
||||||
|
uint8_t vic;
|
||||||
|
/* Horizontal/vertical active pixels/lines */
|
||||||
|
int32_t h_active, v_active;
|
||||||
|
/* Horizontal/vertical front porch */
|
||||||
|
int32_t h_front, v_front;
|
||||||
|
/* Horizontal/vertical sync pulse */
|
||||||
|
int32_t h_sync, v_sync;
|
||||||
|
/* Horizontal/vertical back porch */
|
||||||
|
int32_t h_back, v_back;
|
||||||
|
/* Horizontal/vertical sync pulse polarity */
|
||||||
|
enum di_cta_video_format_sync_polarity h_sync_polarity, v_sync_polarity;
|
||||||
|
/* Pixel clock in Hz */
|
||||||
|
int64_t pixel_clock_hz;
|
||||||
|
/* Whether this timing is interlaced */
|
||||||
|
bool interlaced;
|
||||||
|
/* Picture aspect ratio */
|
||||||
|
enum di_cta_video_format_picture_aspect_ratio picture_aspect_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a CTA-861 video format from a VIC.
|
||||||
|
*
|
||||||
|
* Returns NULL if the VIC is unknown.
|
||||||
|
*/
|
||||||
|
const struct di_cta_video_format *
|
||||||
|
di_cta_video_format_from_vic(uint8_t vic);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EDID CTA-861 extension block.
|
* EDID CTA-861 extension block.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -51,6 +51,7 @@ di_lib = library(
|
||||||
'display-info',
|
'display-info',
|
||||||
[
|
[
|
||||||
'cta.c',
|
'cta.c',
|
||||||
|
'cta-vic-table.c',
|
||||||
'cvt.c',
|
'cvt.c',
|
||||||
'displayid.c',
|
'displayid.c',
|
||||||
'dmt-table.c',
|
'dmt-table.c',
|
||||||
|
|
143
tool/gen-cta-vic.py
Executable file
143
tool/gen-cta-vic.py
Executable file
|
@ -0,0 +1,143 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("usage: gen-cta-vic.py <CTA-861-H PDF>", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
in_path = sys.argv[1]
|
||||||
|
in_basename = os.path.basename(in_path)
|
||||||
|
|
||||||
|
tool_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
out_path = tool_dir + "/../cta-vic-table.c"
|
||||||
|
|
||||||
|
# Page numbers for CTA-861-H
|
||||||
|
pages = {
|
||||||
|
"timing": (41, 43),
|
||||||
|
"sync": (44, 46),
|
||||||
|
"aspect_ratio": (55, 58),
|
||||||
|
}
|
||||||
|
|
||||||
|
def extract_pages(page_range):
|
||||||
|
pages = []
|
||||||
|
page = ""
|
||||||
|
cmd = ["pdftotext", "-f", str(page_range[0]), "-l", str(page_range[1]), "-layout", in_path, "-"]
|
||||||
|
for l in subprocess.check_output(cmd, text=True):
|
||||||
|
if l.startswith("\f"):
|
||||||
|
pages.append(page)
|
||||||
|
page = l[1:]
|
||||||
|
else:
|
||||||
|
page += l
|
||||||
|
return pages
|
||||||
|
|
||||||
|
def extract_table(page):
|
||||||
|
lines = [l.strip() for l in page.splitlines()]
|
||||||
|
rows = []
|
||||||
|
for l in lines:
|
||||||
|
fields = [field.strip() for field in l.split(" ") if field != ""]
|
||||||
|
rows.append(fields)
|
||||||
|
return rows
|
||||||
|
|
||||||
|
def parse_vic_list(s):
|
||||||
|
return [int(vic.strip()) for vic in s.split(",")]
|
||||||
|
|
||||||
|
def parse_hactive(s):
|
||||||
|
# Some hactive pixel values have a footnote marker
|
||||||
|
if s == "14402" or s == "28802":
|
||||||
|
s = s[:-1]
|
||||||
|
return int(s)
|
||||||
|
|
||||||
|
def parse_interlaced(s):
|
||||||
|
if s == "Prog":
|
||||||
|
return "false"
|
||||||
|
elif s == "Int":
|
||||||
|
return "true"
|
||||||
|
else:
|
||||||
|
assert(False)
|
||||||
|
|
||||||
|
def parse_timing_table(page, format_table):
|
||||||
|
assert("Table 1 - Video Format Timings — Detailed Timing Information" in page)
|
||||||
|
|
||||||
|
for fields in extract_table(page):
|
||||||
|
if len(fields) != 11 or fields[0] == "VIC":
|
||||||
|
continue
|
||||||
|
for vic in parse_vic_list(fields[0]):
|
||||||
|
format_table[vic] = {
|
||||||
|
"vic": vic,
|
||||||
|
"h_active": parse_hactive(fields[1]),
|
||||||
|
"v_active": int(fields[2]),
|
||||||
|
"interlaced": parse_interlaced(fields[3]),
|
||||||
|
"pixel_clock_hz": int(float(fields[10]) * 1000 * 1000),
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_polarity(pol):
|
||||||
|
if pol == "P":
|
||||||
|
return "POSITIVE"
|
||||||
|
elif pol == "N":
|
||||||
|
return "NEGATIVE"
|
||||||
|
else:
|
||||||
|
assert(False)
|
||||||
|
|
||||||
|
def parse_sync_table(page, format_table):
|
||||||
|
assert("Table 2 - Video Format Timings — Detailed Sync Information" in page)
|
||||||
|
|
||||||
|
for fields in extract_table(page):
|
||||||
|
if len(fields) < 12:
|
||||||
|
continue
|
||||||
|
for vic in parse_vic_list(fields[0]):
|
||||||
|
fmt = format_table[vic]
|
||||||
|
fmt["h_front"] = int(fields[2])
|
||||||
|
fmt["h_sync"] = int(fields[3])
|
||||||
|
fmt["h_back"] = int(fields[4])
|
||||||
|
fmt["h_sync_polarity"] = "DI_CTA_VIDEO_FORMAT_SYNC_" + parse_polarity(fields[5])
|
||||||
|
fmt["v_front"] = int(fields[6])
|
||||||
|
fmt["v_sync"] = int(fields[7])
|
||||||
|
fmt["v_back"] = int(fields[8])
|
||||||
|
fmt["v_sync_polarity"] = "DI_CTA_VIDEO_FORMAT_SYNC_" + parse_polarity(fields[9])
|
||||||
|
|
||||||
|
def parse_aspect_ratio_table(page, format_table):
|
||||||
|
assert("Table 3 - Video Formats — Video ID Code and Aspect Ratios" in page)
|
||||||
|
|
||||||
|
for fields in extract_table(page):
|
||||||
|
if len(fields) != 5:
|
||||||
|
continue
|
||||||
|
vic = int(fields[0])
|
||||||
|
fmt = format_table[vic]
|
||||||
|
pic_ar = fields[3]
|
||||||
|
if pic_ar == "64:276":
|
||||||
|
# 64:27 has a footnote
|
||||||
|
pic_ar = pic_ar[:-1]
|
||||||
|
fmt["picture_aspect_ratio"] = "DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_" + pic_ar.replace(":", "_")
|
||||||
|
|
||||||
|
format_table = {}
|
||||||
|
for page in extract_pages(pages["timing"]):
|
||||||
|
parse_timing_table(page, format_table)
|
||||||
|
for page in extract_pages(pages["sync"]):
|
||||||
|
parse_sync_table(page, format_table)
|
||||||
|
for page in extract_pages(pages["aspect_ratio"]):
|
||||||
|
parse_aspect_ratio_table(page, format_table)
|
||||||
|
|
||||||
|
max_vic = 0
|
||||||
|
for vic in format_table:
|
||||||
|
if vic > max_vic:
|
||||||
|
max_vic = vic
|
||||||
|
|
||||||
|
# Sanity check
|
||||||
|
for vic in format_table:
|
||||||
|
fmt = format_table[vic]
|
||||||
|
assert("h_sync" in fmt)
|
||||||
|
assert("picture_aspect_ratio" in fmt)
|
||||||
|
|
||||||
|
with open(out_path, "w+") as f:
|
||||||
|
f.write("/* DO NOT EDIT! This file has been generated by gen-cta-vic.py from {}. */\n\n".format(in_basename))
|
||||||
|
f.write('#include "cta.h"\n\n')
|
||||||
|
f.write("const struct di_cta_video_format _di_cta_video_formats[] = {\n")
|
||||||
|
for vic in format_table:
|
||||||
|
f.write("\t[{}] = {{\n".format(vic))
|
||||||
|
for k, v in format_table[vic].items():
|
||||||
|
f.write("\t\t.{} = {},\n".format(k, v))
|
||||||
|
f.write("\t},\n")
|
||||||
|
f.write("};\n\n")
|
||||||
|
f.write("const size_t _di_cta_video_formats_len = {};\n".format(max_vic + 1))
|
Loading…
Reference in a new issue