diff options
-rw-r--r-- | edid-decode.cpp | 43 | ||||
-rw-r--r-- | edid-decode.h | 3 | ||||
-rw-r--r-- | parse-base-block.cpp | 12 | ||||
-rw-r--r-- | parse-cta-block.cpp | 14 |
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]; |