aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2021-10-12 11:17:29 +0200
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2021-10-12 11:17:29 +0200
commitb85a0568e388ef51c444de4ccc724eb76b84c967 (patch)
tree31d570dbd305a8fa2bf0318853e805b127751141
parent66d8451280e15245eaf8a73ab20e78fd3498bc65 (diff)
edid-decode: support CVT 2.0 RBv3 early-vsync option
Support this new option added in CVT 2.0. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--calc-gtf-cvt.cpp16
-rw-r--r--edid-decode.16
-rw-r--r--edid-decode.cpp13
-rw-r--r--edid-decode.h5
4 files changed, 25 insertions, 15 deletions
diff --git a/calc-gtf-cvt.cpp b/calc-gtf-cvt.cpp
index 441735f..4ce098e 100644
--- a/calc-gtf-cvt.cpp
+++ b/calc-gtf-cvt.cpp
@@ -131,7 +131,8 @@ void edid_state::edid_gtf_mode(unsigned refresh, struct timings &t)
// If rb == RB_CVT_V3, then alt means that rb_h_blank is 160 instead of 80.
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, unsigned rb_h_blank)
+ bool margins_rqd, bool alt, unsigned rb_h_blank,
+ bool early_vsync_rqd)
{
timings t = {};
@@ -205,14 +206,16 @@ timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
double h_period_est = ((1000000.0 / v_field_rate_rqd) - rb_min_vblank) /
(v_lines_rnd + vert_margin * 2);
double vbi_lines = floor(rb_min_vblank / h_period_est) + 1;
- double rb_min_vbi = rb_v_fporch + v_sync +
- (rb == RB_CVT_V1 ? CVT_MIN_V_BPORCH : CVT_FIXED_V_BPORCH);
+ double rb_v_bporch = (rb == RB_CVT_V1 ? CVT_MIN_V_BPORCH : CVT_FIXED_V_BPORCH);
+ double rb_min_vbi = rb_v_fporch + v_sync + rb_v_bporch;
v_blank = vbi_lines < rb_min_vbi ? rb_min_vbi : vbi_lines;
double total_v_lines = v_blank + v_lines_rnd + vert_margin * 2 + interlace;
+ if (rb == RB_CVT_V3 && early_vsync_rqd)
+ rb_v_bporch = floor(vbi_lines / 2.0);
if (rb == RB_CVT_V1)
v_sync_bp = v_blank - rb_v_fporch;
else
- v_sync_bp = v_sync + CVT_FIXED_V_BPORCH;
+ v_sync_bp = v_sync + rb_v_bporch;
double total_pixels = h_blank + total_active_pixels;
double freq = v_field_rate_rqd * total_v_lines * total_pixels * refresh_multiplier;
if (rb == RB_CVT_V3)
@@ -242,13 +245,14 @@ timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
return t;
}
-void edid_state::edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank)
+void edid_state::edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank,
+ bool early_vsync_rqd)
{
unsigned hratio = t.hratio;
unsigned vratio = t.vratio;
t = calc_cvt_mode(t.hact, t.vact, refresh, t.rb & ~RB_ALT, t.interlaced,
- false, t.rb & RB_ALT, rb_h_blank);
+ false, t.rb & RB_ALT, rb_h_blank, early_vsync_rqd);
t.hratio = hratio;
t.vratio = vratio;
}
diff --git a/edid-decode.1 b/edid-decode.1
index 5a4ddbf..a9d7eae 100644
--- a/edid-decode.1
+++ b/edid-decode.1
@@ -266,7 +266,7 @@ Show the timings for this VIC.
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][,\fBhblank\fR=\fI<hblank>\fR][,\fBadd\-vblank\fR=\fI<add\-vblank>\fR]
+[,\fBalt\fR][,\fBhblank\fR=\fI<hblank>\fR][,\fBearly\-vsync\fR]
.br
Calculate the CVT timings for the given format.
@@ -289,9 +289,7 @@ is 160 instead of 80 pixels.
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.
.br
-If \fBadd\-vblank\fR is given and \fI<rb>\fR=3, then \fI<add\-vblank>\fR microseconds are
-added to the minimum vertical blank time of 460 microseconds as long as the total blank
-time does not exceed 25% of the frame time.
+If \fBearly\-vsync\fR is given and \fI<rb>\fR=3, then select an early vsync timing.
.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 0295101..84a59d3 100644
--- a/edid-decode.cpp
+++ b/edid-decode.cpp
@@ -142,7 +142,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][,hblank=<hblank]\n"
+ " --cvt w=<width>,h=<height>,fps=<fps>[,rb=<rb>][,interlaced][,overscan][,alt][,hblank=<hblank][,early-vsync]\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"
@@ -156,6 +156,7 @@ static void usage(void)
" 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"
+ " If 'early-vsync' is given and <rb=3>, then select early vsync.\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"
@@ -1508,6 +1509,7 @@ enum cvt_opts {
CVT_RB,
CVT_ALT,
CVT_RB_H_BLANK,
+ CVT_EARLY_VSYNC,
};
static int parse_cvt_subopt(char **subopt_str, double *value)
@@ -1524,6 +1526,7 @@ static int parse_cvt_subopt(char **subopt_str, double *value)
"rb",
"alt",
"hblank",
+ "early-vsync",
nullptr
};
@@ -1535,7 +1538,7 @@ static int parse_cvt_subopt(char **subopt_str, double *value)
std::exit(EXIT_FAILURE);
}
if (opt_str == nullptr && opt != CVT_INTERLACED && opt != CVT_ALT &&
- opt != CVT_OVERSCAN) {
+ opt != CVT_OVERSCAN && opt != CVT_EARLY_VSYNC) {
fprintf(stderr, "No value given to suboption <%s>.\n",
subopt_list[opt]);
usage();
@@ -1556,6 +1559,7 @@ static void parse_cvt(char *optarg)
bool interlaced = false;
bool alt = false;
bool overscan = false;
+ bool early_vsync = false;
while (*optarg != '\0') {
int opt;
@@ -1588,6 +1592,9 @@ static void parse_cvt(char *optarg)
case CVT_RB_H_BLANK:
rb_h_blank = opt_val;
break;
+ case CVT_EARLY_VSYNC:
+ early_vsync = true;
+ break;
default:
break;
}
@@ -1601,7 +1608,7 @@ static void parse_cvt(char *optarg)
if (interlaced)
fps /= 2;
timings t = state.calc_cvt_mode(w, h, fps, rb, interlaced, overscan, alt,
- rb_h_blank);
+ rb_h_blank, early_vsync);
state.print_timings("", &t, "CVT", "", true, false);
}
diff --git a/edid-decode.h b/edid-decode.h
index 310c7cf..fad66fc 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -318,8 +318,9 @@ struct edid_state {
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,
- unsigned rb_h_blank = 0);
- void edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank = 0);
+ unsigned rb_h_blank = 0, bool early_vsync_rqd = false);
+ void edid_cvt_mode(unsigned refresh, struct timings &t, unsigned rb_h_blank = 0,
+ bool early_vsync_rqd = false);
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,
bool gtf_only = false, bool show_both = false);

Privacy Policy