aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--edid-decode.cpp43
-rw-r--r--edid-decode.h3
-rw-r--r--parse-base-block.cpp12
-rw-r--r--parse-cta-block.cpp14
4 files changed, 72 insertions, 0 deletions
diff --git a/edid-decode.cpp b/edid-decode.cpp
index 07bcbe8..1f8c32e 100644
--- a/edid-decode.cpp
+++ b/edid-decode.cpp
@@ -295,6 +295,37 @@ static void or_str(std::string &s, const std::string &flag, unsigned &num_flags)
num_flags++;
}
+/*
+ * Return true if the timings are a close, but not identical,
+ * match. The only differences allowed are polarities and
+ * porches and syncs, provided the total blanking remains the
+ * same.
+ */
+bool timings_close_match(const timings &t1, const timings &t2)
+{
+ // We don't want to deal with borders, you're on your own
+ // if you are using those.
+ if (t1.hborder || t1.vborder ||
+ t2.hborder || t2.vborder)
+ return false;
+ if (t1.hact != t2.hact || t1.vact != t2.vact ||
+ t1.interlaced != t2.interlaced ||
+ t1.pixclk_khz != t2.pixclk_khz ||
+ t1.hfp + t1.hsync + t1.hbp != t2.hfp + t2.hsync + t2.hbp ||
+ t1.vfp + t1.vsync + t1.vbp != t2.vfp + t2.vsync + t2.vbp)
+ return false;
+ if (t1.hfp == t2.hfp &&
+ t1.hsync == t2.hsync &&
+ t1.hbp == t2.hbp &&
+ t1.pos_pol_hsync == t2.pos_pol_hsync &&
+ t1.vfp == t2.vfp &&
+ t1.vsync == t2.vsync &&
+ t1.vbp == t2.vbp &&
+ t1.pos_pol_vsync == t2.pos_pol_vsync)
+ return false;
+ return true;
+}
+
static void print_modeline(unsigned indent, const struct timings *t, double refresh)
{
unsigned offset = (!t->even_vtotal && t->interlaced) ? 1 : 0;
@@ -553,6 +584,18 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
if (!do_checks)
return ok;
+ if (!memcmp(type, "DTD", 3)) {
+ unsigned vic, dmt;
+ const timings *vic_t = cta_close_match_to_vic(*t, vic);
+
+ if (vic_t)
+ warn("DTD is similar but not identical to VIC %u.\n", vic);
+
+ const timings *dmt_t = close_match_to_dmt(*t, dmt);
+ if (!vic_t && dmt_t)
+ warn("DTD is similar but not identical to DMT 0x%02x.\n", dmt);
+ }
+
if (refresh) {
min_vert_freq_hz = min(min_vert_freq_hz, refresh);
max_vert_freq_hz = max(max_vert_freq_hz, refresh);
diff --git a/edid-decode.h b/edid-decode.h
index f9f7064..4b73fd4 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -453,9 +453,12 @@ std::string block_name(unsigned char block);
void calc_ratio(struct timings *t);
const char *oui_name(unsigned oui, bool reverse = false);
+bool timings_close_match(const timings &t1, const timings &t2);
const struct timings *find_dmt_id(unsigned char dmt_id);
+const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt);
const struct timings *find_vic_id(unsigned char vic);
const struct timings *find_hdmi_vic_id(unsigned char hdmi_vic);
+const struct timings *cta_close_match_to_vic(const timings &t, unsigned &vic);
unsigned char hdmi_vic_to_vic(unsigned char hdmi_vic);
char *extract_string(const unsigned char *x, unsigned len);
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index 5d6d77d..2b1a6e0 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -383,6 +383,18 @@ void edid_state::list_established_timings()
}
}
+const struct timings *close_match_to_dmt(const timings &t, unsigned &dmt)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(dmt_timings); i++) {
+ if (timings_close_match(t, dmt_timings[i].t)) {
+ dmt = dmt_timings[i].dmt_id;
+ return &dmt_timings[i].t;
+ }
+ }
+ dmt = 0;
+ return NULL;
+}
+
void edid_state::list_dmts()
{
char type[16];
diff --git a/parse-cta-block.cpp b/parse-cta-block.cpp
index b85d87e..6ce8e6c 100644
--- a/parse-cta-block.cpp
+++ b/parse-cta-block.cpp
@@ -213,6 +213,20 @@ const struct timings *find_hdmi_vic_id(unsigned char hdmi_vic)
return NULL;
}
+const struct timings *cta_close_match_to_vic(const timings &t, unsigned &vic)
+{
+ for (vic = 1; vic <= ARRAY_SIZE(edid_cta_modes1); vic++) {
+ if (timings_close_match(t, edid_cta_modes1[vic - 1]))
+ return &edid_cta_modes1[vic - 1];
+ }
+ for (vic = 193; vic < ARRAY_SIZE(edid_cta_modes2) + 193; vic++) {
+ if (timings_close_match(t, edid_cta_modes1[vic - 193]))
+ return &edid_cta_modes1[vic - 193];
+ }
+ vic = 0;
+ return NULL;
+}
+
void edid_state::cta_list_vics()
{
char type[16];

Privacy Policy