aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2020-11-23 09:43:44 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2020-12-30 11:34:26 +0100
commit95d81c95f89424bc5ff541d941eeea4addeeda1c (patch)
treefda0b956366d893ee492300b0e327e8562c0978c
parentfa87c71f11a17400def68dad20dc26fd0c447dcd (diff)
edid-decode: use DTD or T10VTDB for a T7VTDB if possible
Check if a T7VTDB can also be represented by a DTD or a T10VTDB. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--edid-decode.cpp21
-rw-r--r--edid-decode.h2
-rw-r--r--parse-base-block.cpp12
-rw-r--r--parse-displayid-block.cpp22
4 files changed, 57 insertions, 0 deletions
diff --git a/edid-decode.cpp b/edid-decode.cpp
index f6da158..a8fcb94 100644
--- a/edid-decode.cpp
+++ b/edid-decode.cpp
@@ -207,6 +207,27 @@ std::string edid_state::dtd_type(unsigned cnt)
return buf;
}
+bool edid_state::match_timings(const timings &t1, const timings &t2)
+{
+ if (t1.hact != t2.hact ||
+ t1.vact != t2.vact ||
+ t1.rb != t2.rb ||
+ t1.interlaced != t2.interlaced ||
+ t1.hfp != t2.hfp ||
+ t1.hbp != t2.hbp ||
+ t1.hsync != t2.hsync ||
+ t1.pos_pol_hsync != t2.pos_pol_hsync ||
+ t1.hratio != t2.hratio ||
+ t1.vfp != t2.vfp ||
+ t1.vbp != t2.vbp ||
+ t1.vsync != t2.vsync ||
+ t1.pos_pol_vsync != t2.pos_pol_vsync ||
+ t1.vratio != t2.vratio ||
+ t1.pixclk_khz != t2.pixclk_khz)
+ return false;
+ return true;
+}
+
static void or_str(std::string &s, const std::string &flag, unsigned &num_flags)
{
if (!num_flags)
diff --git a/edid-decode.h b/edid-decode.h
index 20390a6..2f3589e 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -253,8 +253,10 @@ struct edid_state {
{
return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(), detailed);
};
+ bool match_timings(const timings &t1, const timings &t2);
void edid_gtf_mode(unsigned refresh, struct timings &t);
void edid_cvt_mode(unsigned refresh, struct timings &t);
+ timings calc_cvt_mode(unsigned refresh, unsigned hact, unsigned vact, unsigned rb);
void detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first);
void print_standard_timing(const char *prefix, unsigned char b1, unsigned char b2,
bool gtf_only = false, unsigned vrefresh_offset = 60);
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index 37da226..f18b495 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -714,6 +714,18 @@ void edid_state::edid_cvt_mode(unsigned refresh, struct timings &t)
t.interlaced = false;
}
+timings edid_state::calc_cvt_mode(unsigned refresh, unsigned hact, unsigned vact, unsigned rb)
+{
+ timings t = {};
+
+ t.hact = hact;
+ t.vact = vact;
+ t.rb = rb;
+ calc_ratio(&t);
+ edid_cvt_mode(refresh, t);
+ return t;
+}
+
void edid_state::detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first)
{
static const unsigned char empty[3] = { 0, 0, 0 };
diff --git a/parse-displayid-block.cpp b/parse-displayid-block.cpp
index 44b8bec..96c8191 100644
--- a/parse-displayid-block.cpp
+++ b/parse-displayid-block.cpp
@@ -324,6 +324,28 @@ void edid_state::parse_displayid_type_1_7_timing(const unsigned char *x,
if (is_cta) {
timings_ext te(t, "DTD", s);
cta.vec_vtdbs.push_back(te);
+
+ // Only use a T7VTDB if is cannot be expressed by a
+ // DTD or a T10VTDB.
+ if (t.hact <= 4095 && t.vact <= 4095 &&
+ t.pixclk_khz <= 655360 && !(x[3] & 0xe0)) {
+ fail("This T7VTDB can be represented as an 18-byte DTD.\n");
+ return;
+ }
+ unsigned htot = t.hact + t.hfp + t.hsync + t.hbp;
+ unsigned vtot = t.vact + t.vfp + t.vsync + t.vbp;
+ unsigned refresh = (t.pixclk_khz * 1000ULL) / (htot * vtot);
+
+ for (unsigned rb = 0; rb <= 3; rb++) {
+ timings cvt_t = calc_cvt_mode(refresh, t.hact, t.vact, rb);
+ if (match_timings(t, cvt_t)) {
+ fail("This T7VTDB can be represented as a T10VTDB.\n");
+ return;
+ }
+ }
+ timings cvt_t = calc_cvt_mode(refresh, t.hact, t.vact, 3 | RB_FLAG);
+ if (match_timings(t, cvt_t))
+ fail("This T7VTDB can be represented as a T10VTDB.\n");
}
}

Privacy Policy