aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2021-02-03 10:19:33 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-02-03 10:19:33 +0100
commit863038c16a0e380f54cd5560413dbb426a4abf29 (patch)
tree5a1d441f757520e4903e28639a5f23fa75f66696
parenta004802a68f85992fb92bc0c93b2773d413d7f9e (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.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