diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-04-20 10:04:09 +0200 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-04-20 10:04:09 +0200 |
commit | e908154d87394de9e84e900162a3035e6c398fb2 (patch) | |
tree | e3b21e6c7d1505a429744bde563a686c16ff2a71 | |
parent | 4b7d16dc41fee40989911a8274fd071eccd7fb89 (diff) |
edid-decode: add support for CVT RBv3
This new CVT 1.2 reduced blanking formula was published in the CVT 1.2
Errata E1 and is used by CTA-861 and DisplayID 2.0.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r-- | calc-gtf-cvt.cpp | 27 | ||||
-rw-r--r-- | edid-decode.1 | 7 | ||||
-rw-r--r-- | edid-decode.cpp | 16 | ||||
-rw-r--r-- | edid-decode.h | 3 |
4 files changed, 38 insertions, 15 deletions
diff --git a/calc-gtf-cvt.cpp b/calc-gtf-cvt.cpp index 78c64c3..bc32ea0 100644 --- a/calc-gtf-cvt.cpp +++ b/calc-gtf-cvt.cpp @@ -126,12 +126,9 @@ void edid_state::edid_gtf_mode(unsigned refresh, struct timings &t) // If rb == RB_CVT_V2, then alt means video-optimized (i.e. 59.94 instead of 60 Hz, etc.). // If rb == RB_CVT_V3, then alt means that rb_h_blank is 160 instead of 80. -// Note: for RB_CVT_V3 this calculation is slightly different, but -// since CVT 1.3 is not yet public, I cannot update the calculation yet. For now -// it will follow V2. So RBv3 timings will be off for now. timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines, double ip_freq_rqd, unsigned rb, bool int_rqd, - bool margins_rqd, bool alt) + bool margins_rqd, bool alt, unsigned rb_h_blank) { timings t = {}; @@ -159,6 +156,14 @@ timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines, double v_blank; double v_sync_bp; + if (rb == RB_CVT_V3 && rb_h_blank) { + h_blank = rb_h_blank & ~7; + if (h_blank < 80) + h_blank = 80; + else if (h_blank > 200) + h_blank = 200; + } + /* Determine VSync Width from aspect ratio */ if ((t.vact * 4 / 3) == t.hact) v_sync = 4; @@ -204,8 +209,11 @@ timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines, else v_sync_bp = v_sync + CVT_MIN_V_BPORCH; double total_pixels = h_blank + total_active_pixels; - pixel_freq = floor((v_field_rate_rqd * total_v_lines * total_pixels / 1000000.0 * - refresh_multiplier) / clock_step) * clock_step; + double freq = v_field_rate_rqd * total_v_lines * total_pixels * refresh_multiplier; + if (rb == RB_CVT_V3) + pixel_freq = ceil((freq / 1000000.0) / clock_step) * clock_step; + else + pixel_freq = floor((freq / 1000000.0) / clock_step) * clock_step; } t.vbp = v_sync_bp - v_sync; @@ -213,8 +221,11 @@ timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines, t.vfp = v_blank - t.vbp - t.vsync; t.pixclk_khz = round(1000.0 * pixel_freq); t.hsync = h_sync; - t.hfp = (h_blank / 2.0) - t.hsync; - t.hbp = t.hfp + t.hsync; + if (rb == RB_CVT_V3) + t.hfp = 8; + else + t.hfp = (h_blank / 2.0) - t.hsync; + t.hbp = h_blank - t.hfp - t.hsync; t.hborder = hor_margin; t.vborder = vert_margin; t.rb = rb; diff --git a/edid-decode.1 b/edid-decode.1 index e87570f..ecd7fe3 100644 --- a/edid-decode.1 +++ b/edid-decode.1 @@ -148,6 +148,8 @@ DMT 1.3: VESA and Industry Standards and Guidelines for Computer Display Monitor .TP CVT 1.2: VESA Coordinated Video Timings (CVT) Standard, Version 1.2 .TP +CVT 1.2: VESA CVT v1.2 Errata E1 +.TP GTF 1.1: VESA Generalized Timing Formula Standard, Version: 1.1 .RE @@ -253,7 +255,7 @@ Show the timings for this VIC. \fB\-\-hdmi\-vic\fR \fI<hdmivic>\fR Show the timings for this HDMI VIC. .TP -\fB\-\-cvt\fR \fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR,\fBfps\fR=\fI<fps>\fR[,\fBrb\fR=\fI<rb>\fR][,\fBinterlaced\fR][,\fBoverscan\fR][,\fBalt\fR] +\fB\-\-cvt\fR \fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR,\fBfps\fR=\fI<fps>\fR[,\fBrb\fR=\fI<rb>\fR][,\fBinterlaced\fR][,\fBoverscan\fR][,\fBalt\fR][,\fBhblank\fR=\fI<hblank>\fR] .br Calculate the CVT timings for the given format. @@ -272,6 +274,9 @@ optimized for video: 1000 / 1001 * \fI<fps>\fR. .br If \fBalt\fR is given and \fI<rb>\fR=3, then the horizontal blanking is 160 instead of 80 pixels. +.br +If \fBhblank\fR is given and \fI<rb>\fR=3, then the horizontal blanking +is \fI<hblank>\fR pixels (range of 80-200 and divisible by 8), overriding \fBalt\fR. .TP \fB\-\-gtf\fR \fBw\fR=\fI<width>\fR,\fBh\fR=\fI<height>\fR[,\fBfps\fR=\fI<fps>\fR][,\fBhorfreq\fR=\fI<horfreq>\fR][,\fBpixclk\fR=\fI<pixclk>\fR] [,\fBinterlaced\fR][,\fBoverscan\fR][,\fBsecondary\fR][,\fBC\fR=\fI<c>\fR][,\fBM\fR=\fI<m>\fR][,\fBK\fR=\fI<k>\fR][,\fBJ\fR=\fI<j>\fR] diff --git a/edid-decode.cpp b/edid-decode.cpp index e28a3a3..de70242 100644 --- a/edid-decode.cpp +++ b/edid-decode.cpp @@ -139,7 +139,7 @@ static void usage(void) " --dmt <dmt> Show the timings for the DMT with the given DMT ID.\n" " --vic <vic> Show the timings for this VIC.\n" " --hdmi-vic <hdmivic> Show the timings for this HDMI VIC.\n" - " --cvt w=<width>,h=<height>,fps=<fps>[,rb=<rb>][,interlaced][,overscan][,alt]\n" + " --cvt w=<width>,h=<height>,fps=<fps>[,rb=<rb>][,interlaced][,overscan][,alt][,hblank=<hblank]\n" " Calculate the CVT timings for the given format.\n" " <fps> is frames per second for progressive timings,\n" " or fields per second for interlaced timings.\n" @@ -151,6 +151,8 @@ static void usage(void) " optimized for video: 1000 / 1001 * <fps>.\n" " If 'alt' is given and <rb>=3, then the horizontal blanking\n" " is 160 instead of 80 pixels.\n" + " If 'hblank' is given and <rb>=3, then the horizontal blanking\n" + " is <hblank> pixels (range of 80-200), overriding 'alt'.\n" " --gtf w=<width>,h=<height>[,fps=<fps>][,horfreq=<horfreq>][,pixclk=<pixclk>][,interlaced]\n" " [,overscan][,secondary][,C=<c>][,M=<m>][,K=<k>][,J=<j>]\n" " Calculate the GTF timings for the given format.\n" @@ -540,12 +542,10 @@ bool edid_state::print_timings(const char *prefix, const struct timings *t, if (rb) { bool alt = t->rb & RB_ALT; s = "RB"; - // Mark RB_CVT_V3 as preliminary since CVT 1.3 has not been - // released yet. if (rb == RB_CVT_V2) s += std::string("v2") + (alt ? ",video-optimized" : ""); else if (rb == RB_CVT_V3) - s += std::string("v3-is-preliminary") + (alt ? ",h-blank-160" : ""); + s += std::string("v3") + (alt ? ",h-blank-160" : ""); } add_str(s, flags); if (t->hsize_mm || t->vsize_mm) @@ -1334,6 +1334,7 @@ enum cvt_opts { CVT_OVERSCAN, CVT_RB, CVT_ALT, + CVT_RB_H_BLANK, }; static int parse_cvt_subopt(char **subopt_str, double *value) @@ -1349,6 +1350,7 @@ static int parse_cvt_subopt(char **subopt_str, double *value) "overscan", "rb", "alt", + "hblank", nullptr }; @@ -1377,6 +1379,7 @@ static void parse_cvt(char *optarg) unsigned w = 0, h = 0; double fps = 0; unsigned rb = RB_NONE; + unsigned rb_h_blank = 0; bool interlaced = false; bool alt = false; bool overscan = false; @@ -1409,6 +1412,9 @@ static void parse_cvt(char *optarg) case CVT_ALT: alt = opt_val; break; + case CVT_RB_H_BLANK: + rb_h_blank = opt_val; + break; default: break; } @@ -1421,7 +1427,7 @@ static void parse_cvt(char *optarg) } if (interlaced) fps /= 2; - timings t = state.calc_cvt_mode(w, h, fps, rb, interlaced, overscan, alt); + timings t = state.calc_cvt_mode(w, h, fps, rb, interlaced, overscan, alt, rb_h_blank); state.print_timings("", &t, "CVT", "", true, false); } diff --git a/edid-decode.h b/edid-decode.h index 4b73fd4..f3fdfd0 100644 --- a/edid-decode.h +++ b/edid-decode.h @@ -313,7 +313,8 @@ struct edid_state { void edid_gtf_mode(unsigned refresh, struct timings &t); timings calc_cvt_mode(unsigned h_pixels, unsigned v_lines, double ip_freq_rqd, unsigned rb, bool int_rqd = false, - bool margins_rqd = false, bool alt = false); + bool margins_rqd = false, bool alt = false, + unsigned rb_h_blank = 0); void edid_cvt_mode(unsigned refresh, struct timings &t); 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, |