This is an automatic generated email to let you know that the following patch 
were queued:

Subject: edid-decode: add support for CTA Product Information Data Block
Author:  Hans Verkuil <hverkuil-ci...@xs4all.nl>
Date:    Thu Apr 25 12:09:01 2024 +0200

Add support for this new CTA-861.7 data block.

Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 edid-decode.h        |  4 +++-
 parse-base-block.cpp |  6 +++++-
 parse-cta-block.cpp  | 29 +++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

---

diff --git a/edid-decode.h b/edid-decode.h
index d982f90b72a4..d2623910c9fe 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -174,7 +174,7 @@ struct edid_state {
                // CTA-861 block state
                cta.has_vic_1 = cta.first_svd_might_be_preferred = cta.has_sldb 
=
                        cta.has_hdmi = cta.has_vcdb = cta.has_vfpdb = 
cta.has_cdb =
-                       cta.has_nvrdb = false;
+                       cta.has_nvrdb = cta.has_pidb = false;
                cta.previous_cta_tag = 0xfff;
                cta.have_hf_vsdb = cta.have_hf_scdb = false;
                cta.hdmi_max_rate = 0;
@@ -309,6 +309,7 @@ struct edid_state {
                bool preparsed_sld_has_coord;
                bool preparsed_sld;
                bool has_sldb;
+               bool has_pidb;
                unsigned short preparsed_phys_addr;
                unsigned previous_cta_tag;
                bool have_hf_vsdb, have_hf_scdb;
@@ -410,6 +411,7 @@ struct edid_state {
        cta_vfd cta_parse_vfd(const unsigned char *x, unsigned lvfd);
        void cta_rcdb(const unsigned char *x, unsigned length);
        void cta_sldb(const unsigned char *x, unsigned length);
+       void cta_pidb(const unsigned char *x, unsigned length);
        void cta_preparse_sldb(const unsigned char *x, unsigned length);
        void cta_colorimetry_block(const unsigned char *x, unsigned length);
        void cta_hdmi_block(const unsigned char *x, unsigned length);
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index 2f2b4f6148fa..26cebb3c2344 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -1412,6 +1412,7 @@ void edid_state::parse_base_block(const unsigned char *x)
        int analog;
        unsigned col_x, col_y;
        bool has_preferred_timing = false;
+       char *manufacturer;
 
        data_block = "EDID Structure Version & Revision";
        printf("  %s: %hhu.%hhu\n", data_block.c_str(), x[0x12], x[0x13]);
@@ -1426,10 +1427,13 @@ void edid_state::parse_base_block(const unsigned char 
*x)
        }
 
        data_block = "Vendor & Product Identification";
+       manufacturer = manufacturer_name(x + 0x08);
        printf("  %s:\n", data_block.c_str());
        printf("    Manufacturer: %s\n    Model: %u\n",
-              manufacturer_name(x + 0x08),
+              manufacturer,
               (unsigned short)(x[0x0a] + (x[0x0b] << 8)));
+       if (!strcmp(manufacturer, "CID") && !cta.has_pidb)
+               fail("Manufacturer name is set to CID, but there is no CTA-861 
Product Information Data Block.\n");
        if (base.serial_number) {
                unsigned sn = base.serial_number;
 
diff --git a/parse-cta-block.cpp b/parse-cta-block.cpp
index e976de554e83..6bb7ea201a75 100644
--- a/parse-cta-block.cpp
+++ b/parse-cta-block.cpp
@@ -2434,6 +2434,30 @@ static void cta_ifdb(const unsigned char *x, unsigned 
length)
        }
 }
 
+void edid_state::cta_pidb(const unsigned char *x, unsigned length)
+{
+       if (length < 4) {
+               fail("Empty Data Block with length %u.\n", length);
+               return;
+       }
+       unsigned oui = (x[0] << 16) | (x[1] << 8) | x[2];
+       printf("    IEEE CID/OUI: %s\n", ouitohex(oui).c_str());
+       if (length == 4)
+               return;
+       printf("    Version: %u\n", x[3]);
+       if (x[3])
+               fail("Unsupported version %u.\n", x[3]);
+       if (length == 5)
+               return;
+       char pn[26];
+       memcpy(pn, x + 4, length - 5);
+       pn[length - 5] = 0;
+       for (unsigned i = 0; i < length - 5; i++)
+               if (x[4 + i] < 0x20 || x[4 + i] >= 0x80)
+                       fail("Product Name: invalid ASCII value at position 
%u.\n", i);
+       printf("    Product Name: %s\n", pn);
+}
+
 void edid_state::cta_displayid_type_7(const unsigned char *x, unsigned length)
 {
        check_displayid_datablock_revision(x[0], 0x00, 2);
@@ -2606,6 +2630,7 @@ void edid_state::cta_block(const unsigned char *x, 
std::vector<unsigned> &found_
        case 0x714: data_block = "Speaker Location Data Block"; audio_block = 
true; break;
 
        case 0x720: data_block = "InfoFrame Data Block"; break;
+       case 0x721: data_block = "Product Information Data Block"; break;
 
        case 0x722: data_block = "DisplayID Type VII Video Timing Data Block"; 
break;
        case 0x723: data_block = "DisplayID Type VIII Video Timing Data Block"; 
break;
@@ -2659,6 +2684,7 @@ void edid_state::cta_block(const unsigned char *x, 
std::vector<unsigned> &found_
        case 0x70f:
        case 0x712:
        case 0x713:
+       case 0x721:
        case 0x778:
        case 0x779:
        case 0x77a:
@@ -2719,6 +2745,7 @@ void edid_state::cta_block(const unsigned char *x, 
std::vector<unsigned> &found_
        case 0x713: cta_rcdb(x, length); break;
        case 0x714: cta_sldb(x, length); break;
        case 0x720: cta_ifdb(x, length); break;
+       case 0x721: cta_pidb(x, length); break;
        case 0x722: cta_displayid_type_7(x, length); break;
        case 0x723: cta_displayid_type_8(x, length); break;
        case 0x72a: cta_displayid_type_10(x, length); break;
@@ -2812,6 +2839,8 @@ void edid_state::preparse_cta_block(unsigned char *x)
                                cta.has_cdb = true;
                        else if (x[i + 1] == 0x08)
                                cta.has_nvrdb = true;
+                       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);
                                cta.preparsed_sld = x[i + 2] & 0x20;

Reply via email to