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: generalize the InfoFrame/ELD parse code
Author:  Hans Verkuil <[email protected]>
Date:    Mon May 11 08:02:16 2026 +0200

This avoids having almost identical copies. In addition,
this makes it easier to add support for parsing HDCP and
SCDC.

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

 utils/edid-decode/edid-decode.cpp | 304 +++++++++++---------------------------
 utils/edid-decode/edid-decode.h   |  11 +-
 2 files changed, 98 insertions(+), 217 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=33c193b89d2e2e8251e75362344a7b521f30c681
diff --git a/utils/edid-decode/edid-decode.cpp 
b/utils/edid-decode/edid-decode.cpp
index 8e5d0d8a9b3d..dcb0c88cba21 100644
--- a/utils/edid-decode/edid-decode.cpp
+++ b/utils/edid-decode/edid-decode.cpp
@@ -1660,28 +1660,40 @@ int edid_state::parse_edid()
        return failures ? -2 : 0;
 }
 
-/* InfoFrame parsing */
+/* InfoFrame/ELD parsing */
 
 static unsigned char infoframe[32];
-static unsigned if_size;
+
+static struct parse_data if_pdata = {
+       "InfoFrame",
+       infoframe,
+       sizeof(infoframe),
+       0
+};
 
 static unsigned char eld[128];
-static unsigned eld_size;
 
-static bool if_add_byte(const char *s)
+static struct parse_data eld_pdata = {
+       "ELD",
+       eld,
+       sizeof(eld),
+       0
+};
+
+static bool data_add_byte(parse_data &pdata, const char *s)
 {
        char buf[3];
 
-       if (if_size == sizeof(infoframe))
+       if (pdata.buf_size == pdata.buf_max_size)
                return false;
        buf[0] = s[0];
        buf[1] = s[1];
        buf[2] = 0;
-       infoframe[if_size++] = strtoul(buf, NULL, 16);
+       pdata.buf[pdata.buf_size++] = strtoul(buf, NULL, 16);
        return true;
 }
 
-static bool extract_if_hex(const char *s)
+static bool extract_data_hex(parse_data &pdata, const char *s)
 {
        for (; *s; s++) {
                if (isspace(*s) || strchr(ignore_chars, *s))
@@ -1695,16 +1707,17 @@ static bool extract_if_hex(const char *s)
                        odd_hex_digits = true;
                        return false;
                }
-               if (!if_add_byte(s))
+               if (!data_add_byte(pdata, s))
                        return false;
                s++;
        }
-       return if_size;
+       return pdata.buf_size;
 }
 
-static bool extract_if(int fd)
+static bool extract_data(parse_data &pdata, int fd)
 {
-       std::vector<char> if_data;
+       std::string hdr = std::string("edid-decode ") + pdata.name + " (hex):";
+       std::vector<char> data;
        char buf[128];
 
        for (;;) {
@@ -1714,48 +1727,48 @@ static bool extract_if(int fd)
                        return false;
                if (i == 0)
                        break;
-               if_data.insert(if_data.end(), buf, buf + i);
+               data.insert(data.end(), buf, buf + i);
        }
 
-       if (if_data.empty()) {
-               if_size = 0;
+       if (data.empty()) {
+               pdata.buf_size = 0;
                return false;
        }
        // Ensure it is safely terminated by a 0 char
-       if_data.push_back('\0');
+       data.push_back('\0');
 
-       const char *data = &if_data[0];
+       const char *d = &data[0];
        const char *start;
 
        /* Look for edid-decode output */
-       start = strstr(data, "edid-decode InfoFrame (hex):");
+       start = strstr(d, hdr.c_str());
        if (start)
-               return extract_if_hex(strchr(start, ':') + 1);
+               return extract_data_hex(pdata, strchr(start, ':') + 1);
 
        unsigned i;
 
-       for (i = 0; i < 32 && (isspace(data[i]) || strchr(ignore_chars, 
data[i]) ||
-                              tolower(data[i]) == 'x' || isxdigit(data[i])); 
i++);
+       for (i = 0; i < 32 && (isspace(d[i]) || strchr(ignore_chars, d[i]) ||
+                              tolower(d[i]) == 'x' || isxdigit(d[i])); i++);
 
        if (i == 32)
-               return extract_if_hex(data);
+               return extract_data_hex(pdata, d);
 
        // Drop the extra '\0' byte since we now assume binary data
-       if_data.pop_back();
+       data.pop_back();
 
-       if_size = if_data.size();
+       pdata.buf_size = data.size();
 
        /* Assume binary */
-       if (if_size > sizeof(infoframe)) {
-               fprintf(stderr, "Binary InfoFrame length %u is greater than 
%zu.\n",
-                       if_size, sizeof(infoframe));
+       if (pdata.buf_size > pdata.buf_max_size) {
+               fprintf(stderr, "Binary %s length %u is greater than %u.\n",
+                       pdata.name, pdata.buf_size, pdata.buf_max_size);
                return false;
        }
-       memcpy(infoframe, data, if_size);
+       memcpy(pdata.buf, d, pdata.buf_size);
        return true;
 }
 
-static int if_from_file(const char *from_file)
+static int data_from_file(parse_data &pdata, const char *from_file)
 {
 #ifdef O_BINARY
        // Windows compatibility
@@ -1765,8 +1778,8 @@ static int if_from_file(const char *from_file)
 #endif
        int fd;
 
-       memset(infoframe, 0, sizeof(infoframe));
-       if_size = 0;
+       memset(pdata.buf, 0, pdata.buf_max_size);
+       pdata.buf_size = 0;
 
        if (!strcmp(from_file, "-")) {
                from_file = "stdin";
@@ -1777,12 +1790,12 @@ static int if_from_file(const char *from_file)
        }
 
        odd_hex_digits = false;
-       if (!extract_if(fd)) {
-               if (!if_size) {
-                       fprintf(stderr, "InfoFrame of '%s' was empty.\n", 
from_file);
+       if (!extract_data(pdata, fd)) {
+               if (!pdata.buf_size) {
+                       fprintf(stderr, "%s of '%s' was empty.\n", pdata.name, 
from_file);
                        return -1;
                }
-               fprintf(stderr, "InfoFrame extraction of '%s' failed: ", 
from_file);
+               fprintf(stderr, "%s extraction of '%s' failed: ", pdata.name, 
from_file);
                if (odd_hex_digits)
                        fprintf(stderr, "odd number of hexadecimal digits.\n");
                else
@@ -1794,18 +1807,18 @@ static int if_from_file(const char *from_file)
        return 0;
 }
 
-static void show_if_msgs(bool is_warn)
+static void show_data_msgs(const char *name, bool is_warn)
 {
        printf("\n%s:\n\n", is_warn ? "Warnings" : "Failures");
        if (s_msgs[0][is_warn].empty())
                return;
-       printf("InfoFrame:\n%s",
-              s_msgs[0][is_warn].c_str());
+       printf("%s:\n%s", name, s_msgs[0][is_warn].c_str());
 }
 
-int edid_state::parse_if(const std::string &fname)
+int edid_state::parse_if_file(const std::string &fname)
 {
-       int ret = if_from_file(fname.c_str());
+       parse_data &pdata = if_pdata;
+       int ret = data_from_file(pdata, fname.c_str());
        unsigned min_size = 4;
        bool is_hdmi = false;
 
@@ -1816,8 +1829,8 @@ int edid_state::parse_if(const std::string &fname)
        state.data_block.clear();
 
        if (!options[OptSkipHexDump]) {
-               printf("edid-decode InfoFrame (hex):\n\n");
-               hex_block("", infoframe, if_size, false);
+               printf("edid-decode %s (hex):\n\n", pdata.name);
+               hex_block("", infoframe, pdata.buf_size, false);
                if (options[OptOnlyHexDump])
                        return 0;
                printf("\n----------------\n\n");
@@ -1828,46 +1841,46 @@ int edid_state::parse_if(const std::string &fname)
                min_size++;
        }
 
-       if (if_size < min_size) {
-               fail("InfoFrame is too small to parse.\n");
+       if (pdata.buf_size < min_size) {
+               fail("%s is too small to parse.\n", pdata.name);
                return -1;
        }
 
        if (is_hdmi) {
-               do_checksum("HDMI InfoFrame ", infoframe, if_size, 3);
+               do_checksum("HDMI InfoFrame ", pdata.buf, pdata.buf_size, 3);
                printf("\n");
-               memcpy(infoframe + 3, infoframe + 4, if_size - 4);
-               infoframe[0] &= 0x7f;
-               if_size--;
+               memcpy(pdata.buf + 3, pdata.buf + 4, pdata.buf_size - 4);
+               pdata.buf[0] &= 0x7f;
+               pdata.buf_size--;
        }
 
-       switch (infoframe[0]) {
+       switch (pdata.buf[0]) {
        case 0x01:
-               parse_if_vendor(infoframe, if_size);
+               parse_if_vendor(pdata.buf, pdata.buf_size);
                break;
        case 0x02:
-               parse_if_avi(infoframe, if_size);
+               parse_if_avi(pdata.buf, pdata.buf_size);
                break;
        case 0x03:
-               parse_if_spd(infoframe, if_size);
+               parse_if_spd(pdata.buf, pdata.buf_size);
                break;
        case 0x04:
-               parse_if_audio(infoframe, if_size);
+               parse_if_audio(pdata.buf, pdata.buf_size);
                break;
        case 0x05:
-               parse_if_mpeg_source(infoframe, if_size);
+               parse_if_mpeg_source(pdata.buf, pdata.buf_size);
                break;
        case 0x06:
-               parse_if_ntsc_vbi(infoframe, if_size);
+               parse_if_ntsc_vbi(pdata.buf, pdata.buf_size);
                break;
        case 0x07:
-               parse_if_drm(infoframe, if_size);
+               parse_if_drm(pdata.buf, pdata.buf_size);
                break;
        default:
-               if (infoframe[0] <= 0x1f)
-                       fail("Reserved InfoFrame type %hhx.\n", infoframe[0]);
+               if (pdata.buf[0] <= 0x1f)
+                       fail("Reserved %s type %hhx.\n", pdata.name, 
pdata.buf[0]);
                else
-                       fail("Forbidden InfoFrame type %hhx.\n", infoframe[0]);
+                       fail("Forbidden %s type %hhx.\n", pdata.name, 
pdata.buf[0]);
                break;
        }
 
@@ -1884,161 +1897,21 @@ int edid_state::parse_if(const std::string &fname)
 
        if (options[OptCheck]) {
                if (warnings)
-                       show_if_msgs(true);
+                       show_data_msgs(pdata.name, true);
                if (failures)
-                       show_if_msgs(false);
+                       show_data_msgs(pdata.name, false);
        }
 
        printf("\n%s conformity: %s\n",
-              state.data_block.empty() ? "InfoFrame" : 
state.data_block.c_str(),
+              state.data_block.empty() ? pdata.name : state.data_block.c_str(),
               failures ? "FAIL" : "PASS");
        return failures ? -2 : 0;
 }
 
-static bool eld_add_byte(const char *s)
-{
-       char buf[3];
-
-       if (eld_size == sizeof(eld))
-               return false;
-       buf[0] = s[0];
-       buf[1] = s[1];
-       buf[2] = 0;
-       eld[eld_size++] = strtoul(buf, NULL, 16);
-       return true;
-}
-
-static bool extract_eld_hex(const char *s)
-{
-       for (; *s; s++) {
-               if (isspace(*s) || strchr(ignore_chars, *s))
-                       continue;
-
-               if (*s == '0' && tolower(s[1]) == 'x') {
-                       s++;
-                       continue;
-               }
-
-               /* Read one or two hex digits from the log */
-               if (!isxdigit(s[0]))
-                       break;
-
-               if (!isxdigit(s[1])) {
-                       odd_hex_digits = true;
-                       return false;
-               }
-               if (!eld_add_byte(s))
-                       return false;
-               s++;
-       }
-       return eld_size;
-}
-
-static bool extract_eld(int fd)
-{
-       std::vector<char> eld_data;
-       char buf[128];
-
-       for (;;) {
-               ssize_t i = read(fd, buf, sizeof(buf));
-
-               if (i < 0)
-                       return false;
-               if (i == 0)
-                       break;
-               eld_data.insert(eld_data.end(), buf, buf + i);
-       }
-
-       if (eld_data.empty()) {
-               eld_size = 0;
-               return false;
-       }
-       // Ensure it is safely terminated by a 0 char
-       eld_data.push_back('\0');
-
-       const char *data = &eld_data[0];
-       const char *start;
-
-       /* Look for edid-decode output */
-       start = strstr(data, "edid-decode ELD (hex):");
-       if (start)
-               return extract_eld_hex(strchr(start, ':') + 1);
-
-       unsigned i;
-
-       /* Is the EDID provided in hex? */
-       for (i = 0; i < 32 && (isspace(data[i]) || strchr(ignore_chars, 
data[i]) ||
-                              tolower(data[i]) == 'x' || isxdigit(data[i])); 
i++);
-
-       if (i == 32)
-               return extract_eld_hex(data);
-
-       // Drop the extra '\0' byte since we now assume binary data
-       eld_data.pop_back();
-
-       eld_size = eld_data.size();
-
-       /* Assume binary */
-       if (eld_size > sizeof(eld)) {
-               fprintf(stderr, "Binary ELD length %u is greater than %zu.\n",
-                       eld_size, sizeof(eld));
-               return false;
-       }
-       memcpy(eld, data, eld_size);
-       return true;
-}
-
-static int eld_from_file(const char *from_file)
-{
-#ifdef O_BINARY
-       // Windows compatibility
-       int flags = O_RDONLY | O_BINARY;
-#else
-       int flags = O_RDONLY;
-#endif
-       int fd;
-
-       memset(eld, 0, sizeof(eld));
-       eld_size = 0;
-
-       if (!strcmp(from_file, "-")) {
-               from_file = "stdin";
-               fd = 0;
-       } else if ((fd = open(from_file, flags)) == -1) {
-               perror(from_file);
-               return -1;
-       }
-
-       odd_hex_digits = false;
-       if (!extract_eld(fd)) {
-               if (!eld_size) {
-                       fprintf(stderr, "ELD of '%s' was empty.\n", from_file);
-                       return -1;
-               }
-               fprintf(stderr, "ELD extraction of '%s' failed: ", from_file);
-               if (odd_hex_digits)
-                       fprintf(stderr, "odd number of hexadecimal digits.\n");
-               else
-                       fprintf(stderr, "unknown format.\n");
-               return -1;
-       }
-       close(fd);
-
-       return 0;
-}
-
-static void show_eld_msgs(bool is_warn)
-{
-       printf("\n%s:\n\n", is_warn ? "Warnings" : "Failures");
-       if (s_msgs[0][is_warn].empty())
-               return;
-       printf("ELD:\n%s",
-              s_msgs[0][is_warn].c_str());
-}
-
-int edid_state::parse_eld(const std::string &fname)
+int edid_state::parse_eld_file(const std::string &fname)
 {
-       int ret = eld_from_file(fname.c_str());
+       parse_data &pdata = eld_pdata;
+       int ret = data_from_file(pdata, fname.c_str());
        unsigned int min_size = 4;
        unsigned baseline_size;
        unsigned char ver;
@@ -2047,19 +1920,19 @@ int edid_state::parse_eld(const std::string &fname)
                return ret;
 
        if (!options[OptSkipHexDump]) {
-               printf("edid-decode ELD (hex):\n\n");
-               hex_block("", eld, eld_size, false);
+               printf("edid-decode %s (hex):\n\n", pdata.name);
+               hex_block("", pdata.buf, pdata.buf_size, false);
                if (options[OptOnlyHexDump])
                        return 0;
                printf("\n----------------\n\n");
        }
 
-       if (eld_size < min_size) {
-               fail("ELD is too small to parse.\n");
+       if (pdata.buf_size < min_size) {
+               fail("%s is too small to parse.\n", pdata.name);
                return -1;
        }
 
-       ver = eld[0] >> 3;
+       ver = pdata.buf[0] >> 3;
        switch (ver) {
        case 1:
                warn("Obsolete Baseline ELD version (%d)\n", ver);
@@ -2072,11 +1945,11 @@ int edid_state::parse_eld(const std::string &fname)
                break;
        }
 
-       baseline_size = eld[2] * 4;
+       baseline_size = pdata.buf[2] * 4;
        if (baseline_size > 80)
                warn("ELD too big\n");
 
-       parse_eld_baseline(&eld[4], baseline_size);
+       parse_eld_baseline(&pdata.buf[4], baseline_size);
 
        if (!options[OptCheck] && !options[OptCheckInline])
                return 0;
@@ -2091,9 +1964,9 @@ int edid_state::parse_eld(const std::string &fname)
 
        if (options[OptCheck]) {
                if (warnings)
-                       show_eld_msgs(true);
+                       show_data_msgs(pdata.name, true);
                if (failures)
-                       show_eld_msgs(false);
+                       show_data_msgs(pdata.name, false);
        }
 
        printf("\n%s conformity: %s\n",
@@ -2858,6 +2731,7 @@ int main(int argc, char **argv)
        }
 
        if (optind == argc) {
+               ret = 0;
                if (adapter_fd >= 0 && options[OptI2CEDID]) {
                        ret = read_edid(adapter_fd, edid, 
options[OptPhysicalAddress]);
                        if (ret > 0) {
@@ -2931,7 +2805,7 @@ int main(int argc, char **argv)
                        s_msgs[i][0].clear();
                        s_msgs[i][1].clear();
                }
-               int r = state.parse_if(n);
+               int r = state.parse_if_file(n);
                if (r && !ret)
                        ret = r;
        }
@@ -2946,7 +2820,7 @@ int main(int argc, char **argv)
                        s_msgs[i][0].clear();
                        s_msgs[i][1].clear();
                }
-               int r = state.parse_eld(n);
+               int r = state.parse_eld_file(n);
                if (r && !ret)
                        ret = r;
        }
diff --git a/utils/edid-decode/edid-decode.h b/utils/edid-decode/edid-decode.h
index a5482039a304..39b5dfbf3c5e 100644
--- a/utils/edid-decode/edid-decode.h
+++ b/utils/edid-decode/edid-decode.h
@@ -140,6 +140,13 @@ struct cta_vfd {
        unsigned int fr48:1;
 };
 
+struct parse_data {
+       const char *name;
+       unsigned char *buf;
+       const unsigned buf_max_size;
+       unsigned buf_size;
+};
+
 struct edid_state {
        edid_state()
        {
@@ -543,7 +550,7 @@ struct edid_state {
        void print_native_res();
        int parse_edid();
 
-       int parse_if(const std::string &fname);
+       int parse_if_file(const std::string &fname);
        int parse_if_hdr(const unsigned char *x, unsigned size, unsigned char 
mask = 0xff);
        void parse_if_hdmi(const unsigned char *x, unsigned len);
        void parse_if_hdmi_forum(const unsigned char *x, unsigned len);
@@ -555,7 +562,7 @@ struct edid_state {
        void parse_if_ntsc_vbi(const unsigned char *x, unsigned size);
        void parse_if_drm(const unsigned char *x, unsigned size);
 
-       int parse_eld(const std::string &fname);
+       int parse_eld_file(const std::string &fname);
        void parse_eld_baseline(const unsigned char *x, unsigned size);
 
        int read_hdcp(int adapter_fd);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to