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: fix the DTD image size checks
Author:  Hans Verkuil <[email protected]>
Date:    Mon Jun 1 10:51:40 2026 +0200

If the DTD contains the image size, then that was checked against
the display size from the base block.

But if the display size > 255 cm in width and/or height, then the
base block can't handle that and the actual size is part of the
CTA Extension block (NVRDB) and/or the DisplayID Extension block.

So preparse the image size from the NVRDB and DisplayID so when
the DTD image size is checked it is using the actual size and not
the incorrect base block size.

Signed-off-by: Hans Verkuil <[email protected]>

 utils/edid-decode/edid-decode.cpp           | 13 +++++----
 utils/edid-decode/parse-base-block.cpp      |  7 +++--
 utils/edid-decode/parse-cta-block.cpp       | 33 ++++++++++++++++++++---
 utils/edid-decode/parse-displayid-block.cpp | 42 ++++++++++++++---------------
 4 files changed, 61 insertions(+), 34 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=be16d95dbb49f448b54310b1d4b08b9d7681837f
diff --git a/utils/edid-decode/edid-decode.cpp 
b/utils/edid-decode/edid-decode.cpp
index 668e265ddb24..132ee858dfb2 100644
--- a/utils/edid-decode/edid-decode.cpp
+++ b/utils/edid-decode/edid-decode.cpp
@@ -766,14 +766,14 @@ bool edid_state::print_timings(const char *prefix, const 
struct timings *t,
                /* 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) {
+       } else if (t->hsize_mm > image_width / 10.0 + 9 ||
+                  t->vsize_mm > image_height / 10.0 + 9) {
                fail("Mismatch of image size %ux%u mm vs display size %ux%u 
mm.\n",
-                    t->hsize_mm, t->vsize_mm, base.max_display_width_mm, 
base.max_display_height_mm);
-       } else if (t->hsize_mm < base.max_display_width_mm - 9 &&
-                  t->vsize_mm < base.max_display_height_mm - 9) {
+                    t->hsize_mm, t->vsize_mm, (image_width + 5) / 10, 
(image_height + 5) / 10);
+       } else if (t->hsize_mm < image_width / 10.0 - 9 &&
+                  t->vsize_mm < image_height / 10.0 - 9) {
                fail("Mismatch of image size %ux%u mm vs display size %ux%u 
mm.\n",
-                    t->hsize_mm, t->vsize_mm, base.max_display_width_mm, 
base.max_display_height_mm);
+                    t->hsize_mm, t->vsize_mm, (image_width + 5) / 10, 
(image_height + 5) / 10);
        }
        if (t->hsize_mm && t->vsize_mm) {
                if (t->hsize_mm < 100 || t->vsize_mm < 100) {
@@ -784,7 +784,6 @@ bool edid_state::print_timings(const char *prefix, const 
struct timings *t,
                        unsigned hsize = (t->vsize_mm * t->hratio) / t->vratio;
 
                        if (vsize > t->vsize_mm + 10 && hsize < t->hsize_mm + 
10) {
-
                                if (hsize < t->hsize_mm - 10 || hsize > 
t->hsize_mm + 10)
                                        warn("Image size is %dx%d mm, but based 
on the picture AR it should be %dx%d mm.\n",
                                             t->hsize_mm, t->vsize_mm, hsize, 
t->vsize_mm);
diff --git a/utils/edid-decode/parse-base-block.cpp 
b/utils/edid-decode/parse-base-block.cpp
index c850e251ef5b..f999f73eaae0 100644
--- a/utils/edid-decode/parse-base-block.cpp
+++ b/utils/edid-decode/parse-base-block.cpp
@@ -1652,8 +1652,11 @@ void edid_state::parse_base_block(const unsigned char *x)
                       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 (base.max_display_width_mm * 10 > image_width ||
+                   base.max_display_height_mm * 10 > image_height) {
+                       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 
%ux%u cm).\n",
                             x[0x15] * factor, x[0x16] * factor,
diff --git a/utils/edid-decode/parse-cta-block.cpp 
b/utils/edid-decode/parse-cta-block.cpp
index 3241d2dcbc2e..3015208c84bb 100644
--- a/utils/edid-decode/parse-cta-block.cpp
+++ b/utils/edid-decode/parse-cta-block.cpp
@@ -958,8 +958,6 @@ void edid_state::cta_nvrdb(const unsigned char *x, unsigned 
length)
                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");
        cta.nvrdb_has_size = true;
@@ -3059,9 +3057,29 @@ void edid_state::preparse_cta_block(unsigned char *x)
                                cta.has_vfpdb = true;
                        else if (x[i + 1] == 0x05)
                                cta.has_cdb = true;
-                       else if (x[i + 1] == 0x08)
+                       else if (x[i + 1] == 0x08) {
                                cta.has_nvrdb = true;
-                       else if (x[i + 1] == 0x21)
+                               if ((x[i] & 0x1f) < 7 || !(x[i + 3] & 1))
+                                       continue;
+
+                               unsigned w = (x[i + 5] << 8) | x[i + 4];
+                               unsigned h = (x[i + 7] << 8) | x[i + 6];
+
+                               if (!w || !h)
+                                       continue;
+
+                               if (x[i + 3] & 0x80) {
+                                       w *= 10;
+                                       h *= 10;
+                               }
+                               cta.image_width = w;
+                               cta.image_height = h;
+                               if (cta.image_width > image_width ||
+                                   cta.image_height > image_height) {
+                                       image_width = cta.image_width;
+                                       image_height = cta.image_height;
+                               }
+                       } else if (x[i + 1] == 0x21)
                                cta.has_pidb = true;
                        else if (x[i + 1] == 0x13 && (x[i + 2] & 0x40)) {
                                cta.preparsed_speaker_count = 1 + (x[i + 2] & 
0x1f);
@@ -3322,6 +3340,13 @@ void edid_state::check_cta_blocks()
 
        data_block = "CTA-861";
 
+       if (cta.image_width && cta.image_width < 25600 && cta.image_height < 
25600 &&
+           (abs((int)cta.image_width - (int)base.max_display_width_mm * 10) >= 
100 ||
+            abs((int)cta.image_height - (int)base.max_display_height_mm * 10) 
>= 100))
+               fail("Image size mismatch: NVRDB: %.1fx%.1fmm Base EDID: 
%u.0x%u.0mm.\n",
+                    cta.image_width / 10.0, cta.image_height / 10.0,
+                    base.max_display_width_mm, base.max_display_height_mm);
+
        // HDMI 1.4 goes up to 340 MHz. Dubious to have a DTD above that,
        // but no VICs. Displays often have a setting to turn off HDMI 2.x
        // support, dropping any HDMI 2.x VICs, but they sometimes forget
diff --git a/utils/edid-decode/parse-displayid-block.cpp 
b/utils/edid-decode/parse-displayid-block.cpp
index 1df812902200..dd2f0f283c1d 100644
--- a/utils/edid-decode/parse-displayid-block.cpp
+++ b/utils/edid-decode/parse-displayid-block.cpp
@@ -172,13 +172,6 @@ void edid_state::parse_displayid_parameters(const unsigned 
char *x)
        if (dispid.has_display_parameters)
                fail("Duplicate Display Parameters Data Block.\n");
        dispid.has_display_parameters = true;
-       dispid.image_width = (x[4] << 8) + x[3];
-       dispid.image_height = (x[6] << 8) + x[5];
-       if (dispid.image_width > image_width ||
-           dispid.image_height > image_height) {
-               image_width = dispid.image_width;
-               image_height = dispid.image_height;
-       }
        printf("    Image size: %.1f mm x %.1f mm\n",
               dispid.image_width / 10.0, dispid.image_height / 10.0);
        unsigned w = (x[8] << 8) + x[7];
@@ -1208,23 +1201,12 @@ void edid_state::parse_displayid_parameters_v2(const 
unsigned char *x,
                fail("Duplicate Display Parameters Data Block.\n");
        dispid.has_display_parameters = true;
 
-       unsigned hor_size = (x[4] << 8) + x[3];
-       unsigned vert_size = (x[6] << 8) + x[5];
-
-       dispid.image_width = hor_size;
-       dispid.image_height = vert_size;
        if (x[1] & 0x80) {
-               printf("    Image size: %u mm x %u mm\n", hor_size, vert_size);
-               dispid.image_width *= 10;
-               dispid.image_height *= 10;
+               printf("    Image size: %u mm x %u mm\n",
+                      dispid.image_width / 10, dispid.image_height / 10);
        } else {
                printf("    Image size: %.1f mm x %.1f mm\n",
-                      hor_size / 10.0, vert_size / 10.0);
-       }
-       if (dispid.image_width > image_width ||
-           dispid.image_height > image_height) {
-               image_width = dispid.image_width;
-               image_height = dispid.image_height;
+                      dispid.image_width / 10.0, dispid.image_height / 10.0);
        }
 
        unsigned w = (x[8] << 8) + x[7];
@@ -2394,6 +2376,24 @@ void edid_state::preparse_displayid_block(unsigned char 
*x)
                                update_checksum = true;
                        }
                        break;
+               case 0x01:
+               case 0x21: {
+                       unsigned hor_size = (x[offset + 4] << 8) + x[offset + 
3];
+                       unsigned vert_size = (x[offset + 6] << 8) + x[offset + 
5];
+
+                       if (tag == 0x21 && (x[offset + 1] & 0x80)) {
+                               hor_size *= 10;
+                               vert_size *= 10;
+                       }
+                       dispid.image_width = hor_size;
+                       dispid.image_height = vert_size;
+                       if (dispid.image_width > image_width ||
+                           dispid.image_height > image_height) {
+                               image_width = dispid.image_width;
+                               image_height = dispid.image_height;
+                       }
+                       break;
+               }
                case 0x12:
                case 0x28:
                        if (replace_unique_ids &&
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to