Mercurial > mplayer.hg
annotate libvo/gtf.c @ 25317:7f3cb5408f28
Fixed VIDIX color bug that was introduced when Radeon VIDIX driver
was synchronized with vidix.sf.net.
The red color was saturating.
Corrected value fixes the issue and restore the color to the level
it used to have before synchronization.
Meaning of the value remains unknow but was retrieved from
register's value of a Radeon 9000 card, so it may need further testing.
Patch by Guillaume Lecerf (foxcore at gmail dot com)
author | ben |
---|---|
date | Mon, 10 Dec 2007 19:27:46 +0000 |
parents | 807aaa6415b3 |
children | 1e9ef4ed8e8f |
rev | line source |
---|---|
7069 | 1 /* |
2 * Copyright (C) Rudolf Marek <r.marek@sh.cvut.cz> - Aug 2002 | |
3 * | |
4 * You can redistribute this file under terms and conditions | |
5 * of GNU General Public licence v2. | |
6 * | |
7 * GTF calculations formulas are taken from GTF_V1R1.xls | |
8 * created by ANDY.MORRISH@NSC.COM | |
9 */ | |
10 | |
11 //Version 0.4 | |
15394
d701716bfbbc
if define HAVE_ROUND do not define round again. patch by Steven M. Schultz <sms@2BSD.COM>
nplourde
parents:
7069
diff
changeset
|
12 #include "config.h" |
7069 | 13 #include <stdio.h> |
14 #include <stdlib.h> | |
15 #include <math.h> | |
16 #include "gtf.h" | |
17 | |
18 #undef GTF_DEBUG | |
19 | |
20 #ifdef GTF_DEBUG | |
21 #define DEBUG_PRINTF(a,b) printf(a,b); | |
22 #else | |
23 #define DEBUG_PRINTF(a,b) | |
24 #endif | |
25 | |
26 static GTF_constants GTF_given_constants = { 3.0,550.0,1,8,1.8,8,40,20,128,600 }; | |
27 | |
28 static void GetRoundedConstants(GTF_constants *c) | |
29 { | |
30 c->Vsync_need = round(GTF_given_constants.Vsync_need); | |
31 c->min_Vsync_BP = GTF_given_constants.min_Vsync_BP; | |
32 c->min_front_porch = round(GTF_given_constants.min_front_porch); | |
33 c->char_cell_granularity = GTF_given_constants.char_cell_granularity; | |
34 c->margin_width = GTF_given_constants.margin_width; | |
35 c->sync_width = GTF_given_constants.sync_width; | |
36 c->c = ((GTF_given_constants.c - GTF_given_constants.j)*(GTF_given_constants.k / 256)) + GTF_given_constants.j; | |
37 c->j = GTF_given_constants.j; | |
38 c->k = GTF_given_constants.k; | |
39 c->m = (GTF_given_constants.k / 256) * GTF_given_constants.m; | |
40 } | |
41 | |
42 void GTF_calcTimings(double X,double Y,double freq, int type, | |
43 int want_margins, int want_interlace,struct VesaCRTCInfoBlock *result ) | |
44 { | |
45 GTF_constants c; | |
46 double RR, margin_top, margin_bottom, margin_left, margin_right; | |
47 double estimated_H_period,sync_plus_BP,BP,interlace,V_total_lines_field; | |
48 double estimated_V_field_rate,actual_H_period,actual_V_field_freq; | |
49 double total_active_pixels, ideal_duty_cycle, blanking_time, H_total_pixels; | |
50 double H_freq, pixel_freq,actual_V_frame_freq; | |
51 double H_sync_start, H_sync_end, H_back_porch, H_front_porch, H_sync_width; | |
52 double V_back_porch, V_front_porch, V_sync_start, V_sync_end,V_sync_width; | |
53 double ideal_H_period; | |
54 GetRoundedConstants(&c); | |
55 | |
56 | |
57 pixel_freq = RR = freq; | |
58 | |
59 /* DETERMINE IF 1/2 LINE INTERLACE IS PRESENT */ | |
60 | |
61 interlace = 0; | |
62 | |
63 if (want_interlace) { | |
64 RR = RR * 2; | |
65 Y=Y/2; | |
66 interlace = 0.5; | |
67 } | |
68 | |
69 result->Flags = 0; | |
70 | |
71 if ((Y==300)||(Y==200)||(Y==240)) | |
72 { | |
73 Y*=2; | |
74 result->Flags = VESA_CRTC_DOUBLESCAN; /* TODO: check if mode support */ | |
75 } | |
76 | |
77 /* DETERMINE NUMBER OF LINES IN V MARGIN */ | |
78 /* DETERMINE NUMBER OF PIXELS IN H MARGIN [pixels] */ | |
79 | |
80 margin_left = margin_right = 0; | |
81 margin_top = margin_bottom = 0; | |
82 | |
83 if (want_margins) { | |
84 margin_top = margin_bottom = (c.margin_width / 100) * Y; | |
85 margin_left = round(( X* c.margin_width/100)/c.char_cell_granularity) \ | |
86 * c.char_cell_granularity; | |
87 margin_right = margin_left; | |
88 DEBUG_PRINTF("margin_left_right : %f\n",margin_right) | |
89 DEBUG_PRINTF("margin_top_bottom : %f\n",margin_top) | |
90 } | |
91 | |
92 /* FIND TOTAL NUMBER OF ACTIVE PIXELS (IMAGE + MARGIN) [pixels] */ | |
93 | |
94 total_active_pixels = margin_left + margin_right + X; | |
95 DEBUG_PRINTF("total_active_pixels: %f\n",total_active_pixels) | |
96 | |
97 if (type == GTF_PF) | |
98 { | |
99 ideal_H_period = ((c.c-100)+(sqrt(((100-c.c)*(100-c.c) )+(0.4*c.m*(total_active_pixels + margin_left + margin_right) / freq))))/2/c.m*1000; | |
100 | |
101 DEBUG_PRINTF("ideal_H_period: %f\n",ideal_H_period) | |
102 | |
103 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
104 ideal_duty_cycle = c.c - (c.m * ideal_H_period /1000); | |
105 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
106 | |
107 /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */ | |
108 | |
109 blanking_time = round(total_active_pixels * ideal_duty_cycle \ | |
110 / (100-ideal_duty_cycle) / (2*c.char_cell_granularity)) \ | |
111 * (2*c.char_cell_granularity); | |
112 DEBUG_PRINTF("blanking_time : %f\n",blanking_time ) | |
113 | |
114 /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */ | |
115 H_total_pixels = total_active_pixels + blanking_time ; | |
116 DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels) | |
117 H_freq = freq / H_total_pixels * 1000; | |
118 DEBUG_PRINTF("H_freq: %f\n",H_freq) | |
119 actual_H_period = 1000 / H_freq; | |
120 DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period) | |
121 sync_plus_BP = round(H_freq * c.min_Vsync_BP/1000); | |
122 // sync_plus_BP = round( freq / H_total_pixels * c.min_Vsync_BP); | |
123 | |
124 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
125 | |
126 } else if (type == GTF_VF) | |
127 { | |
128 | |
129 /* ESTIMATE HORIZ. PERIOD [us] */ | |
130 | |
131 estimated_H_period = (( 1/RR ) - c.min_Vsync_BP/1000000 ) / (Y + (2 * margin_top) + c.min_front_porch + interlace) * 1000000; | |
132 | |
133 DEBUG_PRINTF("estimated_H_period: %f\n",estimated_H_period) | |
134 | |
135 /* FIND NUMBER OF LINES IN (SYNC + BACK PORCH) [lines] */ | |
136 | |
137 sync_plus_BP = round( c.min_Vsync_BP / estimated_H_period ); | |
138 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
139 | |
140 } else if (type == GTF_HF) | |
141 { | |
142 sync_plus_BP = round(freq * c.min_Vsync_BP/1000); | |
143 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
144 } | |
145 | |
146 | |
147 | |
148 /* FIND TOTAL NUMBER OF LINES IN VERTICAL FIELD */ | |
149 | |
150 V_total_lines_field = sync_plus_BP+interlace+margin_bottom+margin_top+Y+c.min_front_porch; | |
151 DEBUG_PRINTF("V_total_lines_field : %f\n",V_total_lines_field ) | |
152 | |
153 if (type == GTF_VF) | |
154 { | |
155 /* ESTIMATE VERTICAL FIELD RATE [hz] */ | |
156 | |
157 estimated_V_field_rate = 1 / estimated_H_period / V_total_lines_field * 1000000; | |
158 DEBUG_PRINTF(" estimated_V_field_rate: %f\n", estimated_V_field_rate) | |
159 /* FIND ACTUAL HORIZONTAL PERIOD [us] */ | |
160 | |
161 actual_H_period = estimated_H_period / (RR / estimated_V_field_rate); | |
162 DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period) | |
163 /* FIND ACTUAL VERTICAL FIELD FREQUENCY [Hz] */ | |
164 | |
165 actual_V_field_freq = 1 / actual_H_period / V_total_lines_field * 1000000; | |
166 DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq) | |
167 | |
168 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
169 ideal_duty_cycle = c.c - (c.m * actual_H_period /1000); | |
170 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
171 //if (type == GTF_VF) | |
172 //{ | |
173 //moved | |
174 //} | |
175 } else if (type == GTF_HF) | |
176 { | |
177 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
178 ideal_duty_cycle = c.c - (c.m / freq); | |
179 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
180 } | |
181 | |
182 /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */ | |
183 | |
184 if (!(type == GTF_PF)) | |
185 { | |
186 blanking_time = round(total_active_pixels * ideal_duty_cycle \ | |
187 / (100-ideal_duty_cycle) / (2*c.char_cell_granularity)) \ | |
188 * (2*c.char_cell_granularity); | |
189 DEBUG_PRINTF("blanking_time : %f\n",blanking_time ) | |
190 } | |
191 else | |
192 // if (type == GTF_PF) | |
193 { | |
194 actual_V_field_freq = H_freq / V_total_lines_field * 1000; | |
195 } | |
196 | |
197 if (type == GTF_HF) | |
198 { | |
199 /* Hz */ | |
200 actual_V_field_freq = freq / V_total_lines_field * 1000; | |
201 DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq) | |
202 } | |
203 | |
204 | |
205 actual_V_frame_freq = actual_V_field_freq; | |
206 | |
207 /* FIND ACTUAL VERTICAL FRAME FREQUENCY [Hz]*/ | |
208 | |
209 if (want_interlace) actual_V_frame_freq = actual_V_field_freq / 2; | |
210 DEBUG_PRINTF("actual_V_frame_freq: %f\n",actual_V_frame_freq) | |
211 | |
212 // V_freq = actual_V_frame_freq; | |
213 // DEBUG_PRINTF("V_freq %f\n",V_freq) | |
214 | |
215 | |
216 if (!(type == GTF_PF)) | |
217 { | |
218 /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */ | |
219 H_total_pixels = total_active_pixels + blanking_time ; | |
220 DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels) | |
221 if (type == GTF_VF) | |
222 { | |
223 /* FIND PIXEL FREQUENCY [Mhz] */ | |
224 pixel_freq = H_total_pixels / actual_H_period ; | |
225 DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq) | |
226 } else if (type == GTF_HF) | |
227 { | |
228 /* FIND PIXEL FREQUENCY [Mhz] */ | |
229 pixel_freq = H_total_pixels * freq / 1000 ; | |
230 DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq) | |
231 actual_H_period = 1000/freq; | |
232 } | |
233 | |
234 /* FIND ACTUAL HORIZONTAL FREQUENCY [KHz] */ | |
235 | |
236 H_freq = 1000 / actual_H_period; | |
237 DEBUG_PRINTF("H_freq %f\n",H_freq) | |
238 | |
239 | |
240 } | |
241 | |
242 /* FIND NUMBER OF LINES IN BACK PORCH [lines] */ | |
243 | |
244 BP = sync_plus_BP - c.Vsync_need; | |
245 DEBUG_PRINTF("BP: %f\n",BP) | |
246 | |
247 /*------------------------------------------------------------------------------------------------*/ | |
248 /* FIND H SYNC WIDTH (TO NEAREST CHAR CELL) */ | |
249 H_sync_width = round(c.sync_width/100*H_total_pixels/c.char_cell_granularity)*c.char_cell_granularity; | |
250 DEBUG_PRINTF("H_sync_width %f\n",H_sync_width) | |
251 | |
252 /* FIND FRONT H PORCH(TO NEAREST CHAR CELL) */ | |
253 H_front_porch = (blanking_time/2) - H_sync_width; | |
254 DEBUG_PRINTF("H_front_porch %f\n",H_front_porch) | |
255 /* FIND BACK H PORCH(TO NEAREST CHAR CELL) */ | |
256 H_back_porch = H_sync_width + H_front_porch; | |
257 DEBUG_PRINTF("H_back_porch%f\n",H_back_porch) | |
258 | |
259 H_sync_start = H_total_pixels - (H_sync_width + H_back_porch); | |
260 DEBUG_PRINTF("H_sync_start %f\n",H_sync_start) | |
261 H_sync_end = H_total_pixels - H_back_porch; | |
262 DEBUG_PRINTF("H_sync_end %f\n",H_sync_end) | |
263 | |
264 V_back_porch = interlace + BP; | |
265 DEBUG_PRINTF("V_back_porch%f\n",V_back_porch) | |
266 V_front_porch = interlace + c.min_front_porch; | |
267 DEBUG_PRINTF("V_front_porch%f\n",V_front_porch) | |
268 | |
269 V_sync_width = c.Vsync_need; | |
270 V_sync_start = V_total_lines_field - (V_sync_width + V_back_porch); | |
271 DEBUG_PRINTF("V_sync_start %f\n",V_sync_start) | |
272 V_sync_end = V_total_lines_field - V_back_porch; | |
273 DEBUG_PRINTF("V_sync_end %f\n",V_sync_end) | |
274 | |
275 result->hTotal = H_total_pixels; | |
276 result-> hSyncStart = H_sync_start; /* Horizontal sync start in pixels */ | |
277 result-> hSyncEnd = H_sync_end; /* Horizontal sync end in pixels */ | |
278 result-> vTotal= V_total_lines_field; /* Vertical total in lines */ | |
279 result-> vSyncStart = V_sync_start; /* Vertical sync start in lines */ | |
280 result-> vSyncEnd = V_sync_end; /* Vertical sync end in lines */ | |
281 result-> Flags = (result->Flags)|VESA_CRTC_HSYNC_NEG; /* Flags (Interlaced, Double Scan etc) */ | |
282 | |
283 if (want_interlace) | |
284 { | |
285 result->Flags = (result->Flags) | VESA_CRTC_INTERLACED; | |
286 } | |
287 | |
288 result-> PixelClock = pixel_freq*1000000; /* Pixel clock in units of Hz */ | |
289 result-> RefreshRate = actual_V_frame_freq*100;/* Refresh rate in units of 0.01 Hz*/ | |
290 | |
291 } | |
292 | |
293 |