diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-02-03 10:19:33 +0100 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-02-03 10:19:33 +0100 |
commit | 863038c16a0e380f54cd5560413dbb426a4abf29 (patch) | |
tree | 5a1d441f757520e4903e28639a5f23fa75f66696 | |
parent | a004802a68f85992fb92bc0c93b2773d413d7f9e (diff) |
edid-decode: improve image/display size checks
1) when print_timings is called to show preferred and/or native
timings, skip any checks. Those have been done already when these
timings were first parsed, and doing it again results in duplicate
messages.
2) if the display size is 0x0 and the max image size > 2559x2559mm, then
do not fail since the display size can only report sizes smaller than
that.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-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) |