diff options
-rw-r--r-- | edid-decode.cpp | 58 | ||||
-rw-r--r-- | edid-decode.h | 10 | ||||
-rw-r--r-- | parse-base-block.cpp | 7 |
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) |