aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--edid-decode.cpp58
-rw-r--r--edid-decode.h10
-rw-r--r--parse-base-block.cpp7
3 files changed, 47 insertions, 28 deletions
diff --git a/edid-decode.cpp b/edid-decode.cpp
index b98c941..e3ead8c 100644
--- a/edid-decode.cpp
+++ b/edid-decode.cpp
@@ -387,11 +387,12 @@ static void print_detailed_timing(unsigned indent, const struct timings *t)
bool edid_state::print_timings(const char *prefix, const struct timings *t,
const char *type, const char *flags,
- bool detailed)
+ bool detailed, bool do_checks)
{
if (!t) {
// Should not happen
- fail("Unknown video timings.\n");
+ if (do_checks)
+ fail("Unknown video timings.\n");
return false;
}
@@ -418,12 +419,13 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
if (!t->hact || !hbl || !t->hfp || !t->hsync ||
!vact || !vbl || (!t->vfp && !t->interlaced && !t->even_vtotal) || !t->vsync) {
- fail("0 values in the video timing:\n"
- " Horizontal Active/Blanking %u/%u\n"
- " Horizontal Frontporch/Sync Width %u/%u\n"
- " Vertical Active/Blanking %u/%u\n"
- " Vertical Frontporch/Sync Width %u/%u\n",
- t->hact, hbl, t->hfp, t->hsync, vact, vbl, t->vfp, t->vsync);
+ if (do_checks)
+ fail("0 values in the video timing:\n"
+ " Horizontal Active/Blanking %u/%u\n"
+ " Horizontal Frontporch/Sync Width %u/%u\n"
+ " Vertical Active/Blanking %u/%u\n"
+ " Vertical Frontporch/Sync Width %u/%u\n",
+ t->hact, hbl, t->hfp, t->hsync, vact, vbl, t->vfp, t->vsync);
ok = false;
}
@@ -445,6 +447,10 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
add_str(s, flags);
if (t->hsize_mm || t->vsize_mm)
add_str(s, std::to_string(t->hsize_mm) + " mm x " + std::to_string(t->vsize_mm) + " mm");
+ if (t->hsize_mm > dtd_max_hsize_mm)
+ dtd_max_hsize_mm = t->hsize_mm;
+ if (t->vsize_mm > dtd_max_vsize_mm)
+ dtd_max_vsize_mm = t->vsize_mm;
if (!s.empty())
s = " (" + s + ")";
unsigned pixclk_khz = t->pixclk_khz / (t->ycbcr420 ? 2 : 1);
@@ -472,6 +478,18 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
else if (detailed)
print_detailed_timing(len + strlen(type) + 6, t);
+ if (refresh) {
+ min_vert_freq_hz = min(min_vert_freq_hz, refresh);
+ max_vert_freq_hz = max(max_vert_freq_hz, refresh);
+ }
+ if (pixclk_khz && (t->hact + hbl)) {
+ min_hor_freq_hz = min(min_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
+ max_hor_freq_hz = max(max_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
+ max_pixclk_khz = max(max_pixclk_khz, pixclk_khz);
+ }
+ if (!do_checks)
+ return ok;
+
if (t->ycbcr420 && t->pixclk_khz < 590000)
warn_once("Some YCbCr 4:2:0 timings are invalid for HDMI (which requires an RGB timings pixel rate >= 590 MHz).\n");
if (t->hfp <= 0)
@@ -480,9 +498,8 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
fail("0 or negative horizontal back porch.\n");
if (t->vbp <= 0)
fail("0 or negative vertical back porch.\n");
- if ((!base.max_display_width_mm && t->hsize_mm) ||
- (!base.max_display_height_mm && t->vsize_mm)) {
- fail("Mismatch of image size vs display size: image size is set, but not display size.\n");
+ if (!base.max_display_width_mm && !base.max_display_height_mm) {
+ /* this is valid */
} else if (!t->hsize_mm && !t->vsize_mm) {
/* this is valid */
} else if (t->hsize_mm > base.max_display_width_mm + 9 ||
@@ -494,15 +511,6 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t,
fail("Mismatch of image size %ux%u mm vs display size %ux%u mm.\n",
t->hsize_mm, t->vsize_mm, base.max_display_width_mm, base.max_display_height_mm);
}
- if (refresh) {
- min_vert_freq_hz = min(min_vert_freq_hz, refresh);
- max_vert_freq_hz = max(max_vert_freq_hz, refresh);
- }
- if (pixclk_khz && (t->hact + hbl)) {
- min_hor_freq_hz = min(min_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
- max_hor_freq_hz = max(max_hor_freq_hz, (pixclk_khz * 1000) / (t->hact + hbl));
- max_pixclk_khz = max(max_pixclk_khz, pixclk_khz);
- }
return ok;
}
@@ -1117,14 +1125,14 @@ int edid_state::parse_edid()
if (options[OptPreferredTimings] && base.preferred_timing.is_valid()) {
printf("\n----------------\n");
printf("\nPreferred Video Timing if only Block 0 is parsed:\n");
- print_timings(" ", base.preferred_timing, true);
+ print_timings(" ", base.preferred_timing, true, false);
}
if (options[OptNativeTimings] &&
base.preferred_timing.is_valid() && base.preferred_is_also_native) {
printf("\n----------------\n");
printf("\nNative Video Timing if only Block 0 is parsed:\n");
- print_timings(" ", base.preferred_timing, true);
+ print_timings(" ", base.preferred_timing, true, false);
}
if (options[OptPreferredTimings] && !cta.preferred_timings.empty()) {
@@ -1133,7 +1141,7 @@ int edid_state::parse_edid()
cta.preferred_timings.size() > 1 ? "s" : "");
for (vec_timings_ext::iterator iter = cta.preferred_timings.begin();
iter != cta.preferred_timings.end(); ++iter)
- print_timings(" ", *iter, true);
+ print_timings(" ", *iter, true, false);
}
if (options[OptNativeTimings] && !cta.native_timings.empty()) {
@@ -1142,7 +1150,7 @@ int edid_state::parse_edid()
cta.native_timings.size() > 1 ? "s" : "");
for (vec_timings_ext::iterator iter = cta.native_timings.begin();
iter != cta.native_timings.end(); ++iter)
- print_timings(" ", *iter, true);
+ print_timings(" ", *iter, true, false);
}
if (options[OptPreferredTimings] && !dispid.preferred_timings.empty()) {
@@ -1151,7 +1159,7 @@ int edid_state::parse_edid()
dispid.preferred_timings.size() > 1 ? "s" : "");
for (vec_timings_ext::iterator iter = dispid.preferred_timings.begin();
iter != dispid.preferred_timings.end(); ++iter)
- print_timings(" ", *iter, true);
+ print_timings(" ", *iter, true, false);
}
if (!options[OptCheck] && !options[OptCheckInline])
diff --git a/edid-decode.h b/edid-decode.h
index 51c6173..07469ff 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -100,6 +100,7 @@ struct edid_state {
max_hor_freq_hz = max_vert_freq_hz = max_pixclk_khz = 0;
min_hor_freq_hz = 0xffffff;
min_vert_freq_hz = 0xffffffff;
+ dtd_max_vsize_mm = dtd_max_hsize_mm = 0;
warnings = failures = 0;
has_cta = has_dispid = false;
hide_serial_numbers = false;
@@ -166,6 +167,8 @@ struct edid_state {
double min_vert_freq_hz;
double max_vert_freq_hz;
unsigned max_pixclk_khz;
+ unsigned dtd_max_hsize_mm;
+ unsigned dtd_max_vsize_mm;
unsigned warnings;
unsigned failures;
@@ -263,11 +266,12 @@ struct edid_state {
std::string dtd_type() { return dtd_type(base.dtd_cnt); }
bool print_timings(const char *prefix, const struct timings *t,
const char *type, const char *flags = "",
- bool detailed = false);
+ bool detailed = false, bool do_checks = true);
bool print_timings(const char *prefix, const struct timings_ext &t,
- bool detailed = false)
+ bool detailed = false, bool do_checks = true)
{
- return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(), detailed);
+ return print_timings(prefix, &t.t, t.type.c_str(), t.flags.c_str(),
+ detailed, do_checks);
};
bool match_timings(const timings &t1, const timings &t2);
void edid_gtf_mode(unsigned refresh, struct timings &t);
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index 03abdbc..7ada311 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -1940,6 +1940,13 @@ void edid_state::check_base_block()
*/
msg(!out_of_range || base.edid_minor >= 4, "%s", err.c_str());
}
+ // The base block will only go up to 255x255 cm for the display size,
+ // so don't fail if one or more image sizes exceeds that.
+ if (!base.max_display_width_mm && !base.max_display_height_mm &&
+ dtd_max_hsize_mm && dtd_max_vsize_mm &&
+ dtd_max_hsize_mm <= 2559 && dtd_max_vsize_mm <= 2559) {
+ fail("One or more DTDs specified an image size, but no display size was set.\n");
+ }
if (base.edid_minor == 3 && num_blocks > 2 && !block_map.saw_block_1)
fail("EDID 1.3 requires a Block Map Extension in Block 1 if there are more than 2 blocks in the EDID.\n");
if (base.edid_minor == 3 && num_blocks > 128 && !block_map.saw_block_128)

Privacy Policy