1 // Supports CVT 1.2 reduced blanking modes v1 and v2
2
3 #include <kms++/kms++.h>
4 #include <cmath>
5
6 using namespace std;
7
8 namespace kms
9 {
10
11 static float CELL_GRAN = 8;
12 static float CELL_GRAN_RND = round(CELL_GRAN);
13
14 struct CVTConsts
15 {
16 float CLOCK_STEP;
17 float MIN_V_BPORCH;
18 float RB_H_BLANK;
19 float RB_H_FPORCH;
20 float RB_H_SYNC;
21 float RB_H_BPORCH;
22 float RB_MIN_V_BLANK;
23 float RB_V_FPORCH;
24 float REFRESH_MULTIPLIER;
25 };
26
27 static const CVTConsts cvt_consts_v1 =
28 {
29 .CLOCK_STEP = 0.25, // Fixed
30 .MIN_V_BPORCH = 6, // Min
31 .RB_H_BLANK = 160, // Fixed
32 .RB_H_FPORCH = 48, // Fixed
33 .RB_H_SYNC = 32, // Fixed
34 .RB_H_BPORCH = 80, // Fixed
35 .RB_MIN_V_BLANK = 460, // Min
36 .RB_V_FPORCH = 3, // Fixed
37 .REFRESH_MULTIPLIER = 1,// Fixed
38 };
39
40 static const CVTConsts cvt_consts_v2 =
41 {
42 .CLOCK_STEP = 0.001, // Fixed
43 .MIN_V_BPORCH = 6, // Fixed
44 .RB_H_BLANK = 80, // Fixed
45 .RB_H_FPORCH = 8, // Fixed
46 .RB_H_SYNC = 32, // Fixed
47 .RB_H_BPORCH = 40, // Fixed
48 .RB_MIN_V_BLANK = 460, // Min
49 .RB_V_FPORCH = 1, // Min
50 .REFRESH_MULTIPLIER = 1,// or 1000/1001
51 };
52
videomode_from_cvt(uint32_t hact,uint32_t vact,uint32_t refresh,bool ilace,bool reduced_v2,bool video_optimized)53 Videomode videomode_from_cvt(uint32_t hact, uint32_t vact, uint32_t refresh, bool ilace, bool reduced_v2, bool video_optimized)
54 {
55 CVTConsts c = reduced_v2 ? cvt_consts_v2 : cvt_consts_v1;
56
57 if (video_optimized)
58 c.REFRESH_MULTIPLIER = 1000.0/1001.0;
59
60 bool INT_RQD = ilace;
61
62 float H_PIXELS = hact;
63 float V_LINES = vact;
64 float IP_FREQ_RQD = refresh ? refresh : 60;
65 if (ilace)
66 IP_FREQ_RQD /= 2;
67
68 float V_SYNC_RND;
69
70 if (reduced_v2) {
71 V_SYNC_RND = 8;
72 } else {
73 if (hact * 3 == vact * 4)
74 V_SYNC_RND = 4;
75 else if (hact * 9 == vact * 16)
76 V_SYNC_RND = 5;
77 else if (hact * 10 == vact * 16)
78 V_SYNC_RND = 6;
79 else if (hact == 1280 && (vact == 1024 || vact == 768))
80 V_SYNC_RND = 7;
81 else
82 V_SYNC_RND = 10;
83 }
84
85 // 5.2.1
86 float V_FIELD_RATE_RQD = INT_RQD ? IP_FREQ_RQD * 2 : IP_FREQ_RQD;
87
88 // 5.2.2
89 float H_PIXELS_RND = floor(H_PIXELS / CELL_GRAN_RND) * CELL_GRAN_RND;
90
91 // 5.2.3
92 float LEFT_MARGIN = 0;
93 float RIGHT_MARGIN = 0;
94
95 // 5.2.4
96 float TOTAL_ACTIVE_PIXELS = H_PIXELS_RND + LEFT_MARGIN + RIGHT_MARGIN;
97
98 // 5.2.5
99 float V_LINES_RND = INT_RQD ? floor(V_LINES / 2) : floor(V_LINES);
100
101 // 5.2.6
102 float TOP_MARGIN = 0;
103 float BOT_MARGIN = 0;
104
105 // 5.2.7
106 float INTERLACE = INT_RQD ? 0.5 : 0;
107
108 // 5.4.8
109 float H_PERIOD_EST = ((1000000 / V_FIELD_RATE_RQD) - c.RB_MIN_V_BLANK) / (V_LINES_RND + TOP_MARGIN + BOT_MARGIN);
110
111 // 5.4.9
112 float VBI_LINES = floor(c.RB_MIN_V_BLANK / H_PERIOD_EST) + 1;
113
114 // 5.4.10
115 float RB_MIN_VBI = c.RB_V_FPORCH + V_SYNC_RND + c.MIN_V_BPORCH;
116 float ACT_VBI_LINES = VBI_LINES < RB_MIN_VBI ? RB_MIN_VBI : VBI_LINES;
117
118 // 5.4.11
119 float TOTAL_V_LINES = ACT_VBI_LINES + V_LINES_RND + TOP_MARGIN + BOT_MARGIN + INTERLACE;
120
121 // 5.4.12
122 float TOTAL_PIXELS = c.RB_H_BLANK + TOTAL_ACTIVE_PIXELS;
123
124 // 5.4.13
125 float ACT_PIXEL_FREQ = c.CLOCK_STEP * floor((V_FIELD_RATE_RQD * TOTAL_V_LINES * TOTAL_PIXELS / 1000000 * c.REFRESH_MULTIPLIER) / c.CLOCK_STEP);
126
127 // 5.4.14
128 //float ACT_H_FREQ = 1000 * ACT_PIXEL_FREQ / TOTAL_PIXELS;
129
130 // 5.4.15
131 //float ACT_FIELD_RATE = 1000 * ACT_H_FREQ / TOTAL_V_LINES;
132
133 // 5.4.16
134 //float ACT_FRAME_RATE = INT_RQD ? ACT_FIELD_RATE / 2 : ACT_FIELD_RATE;
135
136 // 3.4.3.7 Adjust vfp
137 if (reduced_v2)
138 c.RB_V_FPORCH = ACT_VBI_LINES - V_SYNC_RND - c.MIN_V_BPORCH;
139
140 Videomode mode;
141
142 mode = videomode_from_timings(ACT_PIXEL_FREQ * 1000,
143 H_PIXELS_RND, c.RB_H_FPORCH, c.RB_H_SYNC, c.RB_H_BPORCH,
144 V_LINES_RND * (INT_RQD ? 2 : 1), c.RB_V_FPORCH, V_SYNC_RND, ACT_VBI_LINES - V_SYNC_RND - c.RB_V_FPORCH);
145
146 mode.set_hsync(SyncPolarity::Positive);
147 mode.set_vsync(SyncPolarity::Negative);
148
149 mode.set_interlace(INT_RQD);
150
151 return mode;
152 }
153
154 }
155