This is an automatic generated email to let you know that the following patch were queued at the http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:
Subject: edid-decode: preparse the HDMI VSDB Image_Size Author: Hans Verkuil <hverk...@xs4all.nl> Date: Tue Apr 8 14:47:18 2025 +0200 Preparse the HDMI VSDB Image_Size value, and use that to fix the base block display size (if it indicates 5 cm units) or to suppress width/height checks (if it indicates that only the ratio is valid, not the actual size itself). Signed-off-by: Hans Verkuil <hverk...@xs4all.nl> utils/edid-decode/edid-decode.cpp | 2 ++ utils/edid-decode/edid-decode.h | 13 +++++++++-- utils/edid-decode/parse-base-block.cpp | 15 ++++++++---- utils/edid-decode/parse-cta-block.cpp | 42 ++++++++++++++++++++++++++-------- 4 files changed, 56 insertions(+), 16 deletions(-) --- http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=4f4815bd2f4c97ef6b293d1b7b306f14caebf2ef diff --git a/utils/edid-decode/edid-decode.cpp b/utils/edid-decode/edid-decode.cpp index 98be06ea8ddd..9dee00a9507c 100644 --- a/utils/edid-decode/edid-decode.cpp +++ b/utils/edid-decode/edid-decode.cpp @@ -750,6 +750,8 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t, /* this is valid */ } else if (!t->hsize_mm && !t->vsize_mm) { /* this is valid */ + } else if (cta.preparsed_image_size == hdmi_image_size_ratio) { + /* this is valid */ } else if (t->hsize_mm > base.max_display_width_mm + 9 || t->vsize_mm > base.max_display_height_mm + 9) { fail("Mismatch of image size %ux%u mm vs display size %ux%u mm.\n", diff --git a/utils/edid-decode/edid-decode.h b/utils/edid-decode/edid-decode.h index 7e39d8348e8a..7270400d4459 100644 --- a/utils/edid-decode/edid-decode.h +++ b/utils/edid-decode/edid-decode.h @@ -116,6 +116,13 @@ enum gtf_ip_parm { gtf_ip_clk_freq, }; +enum hdmi_image_size { + hdmi_image_size_none, + hdmi_image_size_ratio, + hdmi_image_size_rounded, + hdmi_image_size_5cm, +}; + typedef std::vector<timings_ext> vec_timings_ext; struct cta_rid { @@ -202,6 +209,7 @@ struct edid_state { cta.preparsed_has_t8vtdb = false; cta.preparsed_t8vtdb_dmt = 0; cta.preparsed_max_vic_pixclk_khz = 0; + cta.preparsed_image_size = hdmi_image_size_none; cta.warn_about_hdmi_2x_dtd = false; cta.avi_version = 2; cta.avi_v4_length = 14; @@ -338,6 +346,7 @@ struct edid_state { bool preparsed_has_vic[2][256]; std::vector<unsigned char> preparsed_svds[2]; unsigned preparsed_max_vic_pixclk_khz; + enum hdmi_image_size preparsed_image_size; bool warn_about_hdmi_2x_dtd; unsigned avi_version; unsigned avi_v4_length; @@ -627,14 +636,14 @@ char *extract_string(const unsigned char *x, unsigned len, bool is_cp437); int request_i2c_adapter(const char *device); int read_edid(int adapter_fd, unsigned char *edid, bool silent = false); -int test_reliability(int adapter_fd, unsigned cnt, unsigned msleep); +int test_reliability(int adapter_fd, unsigned secs, unsigned msleep); int read_hdcp(int adapter_fd); int read_hdcp_ri(int adapter_fd, double ri_time); #else static inline int read_edid(int adapter_fd, unsigned char *edid) { return -ENODEV; } -static inline int test_reliability(int adapter_fd, unsigned cnt, unsigned msleep) { return -ENODEV; } +static inline int test_reliability(int adapter_fd, unsigned secs, unsigned msleep) { return -ENODEV; } static inline int read_hdcp(int adapter_fd) { return -ENODEV; } static inline int read_hdcp_ri(int adapter_fd, double ri_time) { return -ENODEV; } diff --git a/utils/edid-decode/parse-base-block.cpp b/utils/edid-decode/parse-base-block.cpp index 0d7f7c212f65..f6bc064d79b7 100644 --- a/utils/edid-decode/parse-base-block.cpp +++ b/utils/edid-decode/parse-base-block.cpp @@ -1625,14 +1625,19 @@ void edid_state::parse_base_block(const unsigned char *x) } if (x[0x15] && x[0x16]) { - printf(" Maximum image size: %u cm x %u cm\n", x[0x15], x[0x16]); - base.max_display_width_mm = x[0x15] * 10; - base.max_display_height_mm = x[0x16] * 10; + unsigned factor = cta.preparsed_image_size == hdmi_image_size_5cm ? 5 : 1; + + printf(" Maximum image size: %u cm x %u cm%s\n", + x[0x15] * factor, x[0x16] * factor, + factor == 5 ? " (HDMI VSDB indicates 5 cm units)" : ""); + base.max_display_width_mm = x[0x15] * 10 * factor; + base.max_display_height_mm = x[0x16] * 10 * factor; image_width = base.max_display_width_mm * 10; image_height = base.max_display_height_mm * 10; if (x[0x15] < 10 || x[0x16] < 10) - warn("Dubious maximum image size (%ux%u is smaller than 10x10 cm).\n", - x[0x15], x[0x16]); + warn("Dubious maximum image size (%ux%u is smaller than %ux%u cm).\n", + x[0x15] * factor, x[0x16] * factor, + 10 * factor, 10 * factor); } else if (base.edid_minor >= 4 && (x[0x15] || x[0x16])) { if (x[0x15]) diff --git a/utils/edid-decode/parse-cta-block.cpp b/utils/edid-decode/parse-cta-block.cpp index 4c2824c9a7a4..847bb1fcba80 100644 --- a/utils/edid-decode/parse-cta-block.cpp +++ b/utils/edid-decode/parse-cta-block.cpp @@ -942,13 +942,20 @@ void edid_state::cta_nvrdb(const unsigned char *x, unsigned length) unsigned w = (x[3] << 8) | x[2]; unsigned h = (x[5] << 8) | x[4]; - if (!w || !h) + if (!w || !h) { fail("Image Size has a zero width and/or height.\n"); + return; + } - if (flags & 0x80) - printf(" Image Size: %ux%u mm\n", w, h); - else - printf(" Image Size: %.1fx%.1f mm\n", w / 10.0, h / 10.0); + if (flags & 0x80) { + w *= 10; + h *= 10; + } + printf(" Image Size: %.1fx%.1f mm\n", w / 10.0, h / 10.0); + image_width = w; + image_height = h; + if (w < 25500 && h < 25500) + warn("Image Size should only be used for large displays with width and/or height > 255 cm\n"); } static std::string hdmi_latency2s(unsigned char l, bool is_video) @@ -1088,10 +1095,9 @@ void edid_state::cta_hdmi_block(const unsigned char *x, unsigned length) break; case 0x18: printf(" Base EDID image size is in units of 5 cm\n"); - base.max_display_width_mm *= 5; - base.max_display_height_mm *= 5; - printf(" Recalculated image size: %u cm x %u cm\n", - base.max_display_width_mm / 10, base.max_display_height_mm / 10); + if (base.max_display_width_mm < 2550 && + base.max_display_height_mm < 2550) + fail("5 cm units should not be used for displays smaller than 255x255 cm\n"); break; } b++; @@ -2848,10 +2854,28 @@ void edid_state::preparse_cta_block(unsigned char *x) switch ((x[i] & 0xe0) >> 5) { case 0x03: + if ((x[i] & 0x1f) < 5) + continue; oui = (x[i + 3] << 16) + (x[i + 2] << 8) + x[i + 1]; if (oui == 0x000c03) { + unsigned length = x[i] & 0x1f; + unsigned b = i + 8; + cta.has_hdmi = true; cta.preparsed_phys_addr = (x[i + 4] << 8) | x[i + 5]; + if (length < 9 || !(x[b] & 0x20)) + continue; + if (x[b] & 0x80) { + if (length < 11) + continue; + if (x[b] & 0x40) { + if (length < 13) + continue; + b += 2; + } + b += 2; + } + cta.preparsed_image_size = (enum hdmi_image_size)((x[b + 1] & 0x18) >> 3); } else if ((oui == 0xca125c || oui == 0x5c12ca) && (x[i] & 0x1f) == 0x15 && replace_unique_ids) { memset(x + i + 6, 0, 16);