Mercurial > mplayer.hg
annotate libvo/gtf.c @ 22616:09dc129234a0
Matroska seeking fixes
If a relative seek forward went past the last index position the
Matroska demuxer did not seek to any index position. It did however set
the mkv_d->skip_to_timecode variable which meant that the next
fill_buffer() call would read from the current position until the target
position (probably the end of the file). Fix this by changing the code
to seek to the last index position if that is between the current and
target positions.
Also change backwards relative seek to accept an exactly matching index
position (<= vs <) and reorganize the seeking conditionals to allow
making the above change without turning the code into a complete mess.
author | uau |
---|---|
date | Fri, 16 Mar 2007 14:55:41 +0000 |
parents | d701716bfbbc |
children | 807aaa6415b3 |
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 | |
15394
d701716bfbbc
if define HAVE_ROUND do not define round again. patch by Steven M. Schultz <sms@2BSD.COM>
nplourde
parents:
7069
diff
changeset
|
28 #ifndef HAVE_ROUND |
7069 | 29 static double round(double v) |
30 { | |
31 return floor(v + 0.5); | |
32 } | |
15394
d701716bfbbc
if define HAVE_ROUND do not define round again. patch by Steven M. Schultz <sms@2BSD.COM>
nplourde
parents:
7069
diff
changeset
|
33 #endif |
7069 | 34 |
35 static void GetRoundedConstants(GTF_constants *c) | |
36 { | |
37 c->Vsync_need = round(GTF_given_constants.Vsync_need); | |
38 c->min_Vsync_BP = GTF_given_constants.min_Vsync_BP; | |
39 c->min_front_porch = round(GTF_given_constants.min_front_porch); | |
40 c->char_cell_granularity = GTF_given_constants.char_cell_granularity; | |
41 c->margin_width = GTF_given_constants.margin_width; | |
42 c->sync_width = GTF_given_constants.sync_width; | |
43 c->c = ((GTF_given_constants.c - GTF_given_constants.j)*(GTF_given_constants.k / 256)) + GTF_given_constants.j; | |
44 c->j = GTF_given_constants.j; | |
45 c->k = GTF_given_constants.k; | |
46 c->m = (GTF_given_constants.k / 256) * GTF_given_constants.m; | |
47 } | |
48 | |
49 void GTF_calcTimings(double X,double Y,double freq, int type, | |
50 int want_margins, int want_interlace,struct VesaCRTCInfoBlock *result ) | |
51 { | |
52 GTF_constants c; | |
53 double RR, margin_top, margin_bottom, margin_left, margin_right; | |
54 double estimated_H_period,sync_plus_BP,BP,interlace,V_total_lines_field; | |
55 double estimated_V_field_rate,actual_H_period,actual_V_field_freq; | |
56 double total_active_pixels, ideal_duty_cycle, blanking_time, H_total_pixels; | |
57 double H_freq, pixel_freq,actual_V_frame_freq; | |
58 double H_sync_start, H_sync_end, H_back_porch, H_front_porch, H_sync_width; | |
59 double V_back_porch, V_front_porch, V_sync_start, V_sync_end,V_sync_width; | |
60 double ideal_H_period; | |
61 GetRoundedConstants(&c); | |
62 | |
63 | |
64 pixel_freq = RR = freq; | |
65 | |
66 /* DETERMINE IF 1/2 LINE INTERLACE IS PRESENT */ | |
67 | |
68 interlace = 0; | |
69 | |
70 if (want_interlace) { | |
71 RR = RR * 2; | |
72 Y=Y/2; | |
73 interlace = 0.5; | |
74 } | |
75 | |
76 result->Flags = 0; | |
77 | |
78 if ((Y==300)||(Y==200)||(Y==240)) | |
79 { | |
80 Y*=2; | |
81 result->Flags = VESA_CRTC_DOUBLESCAN; /* TODO: check if mode support */ | |
82 } | |
83 | |
84 /* DETERMINE NUMBER OF LINES IN V MARGIN */ | |
85 /* DETERMINE NUMBER OF PIXELS IN H MARGIN [pixels] */ | |
86 | |
87 margin_left = margin_right = 0; | |
88 margin_top = margin_bottom = 0; | |
89 | |
90 if (want_margins) { | |
91 margin_top = margin_bottom = (c.margin_width / 100) * Y; | |
92 margin_left = round(( X* c.margin_width/100)/c.char_cell_granularity) \ | |
93 * c.char_cell_granularity; | |
94 margin_right = margin_left; | |
95 DEBUG_PRINTF("margin_left_right : %f\n",margin_right) | |
96 DEBUG_PRINTF("margin_top_bottom : %f\n",margin_top) | |
97 } | |
98 | |
99 /* FIND TOTAL NUMBER OF ACTIVE PIXELS (IMAGE + MARGIN) [pixels] */ | |
100 | |
101 total_active_pixels = margin_left + margin_right + X; | |
102 DEBUG_PRINTF("total_active_pixels: %f\n",total_active_pixels) | |
103 | |
104 if (type == GTF_PF) | |
105 { | |
106 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; | |
107 | |
108 DEBUG_PRINTF("ideal_H_period: %f\n",ideal_H_period) | |
109 | |
110 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
111 ideal_duty_cycle = c.c - (c.m * ideal_H_period /1000); | |
112 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
113 | |
114 /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */ | |
115 | |
116 blanking_time = round(total_active_pixels * ideal_duty_cycle \ | |
117 / (100-ideal_duty_cycle) / (2*c.char_cell_granularity)) \ | |
118 * (2*c.char_cell_granularity); | |
119 DEBUG_PRINTF("blanking_time : %f\n",blanking_time ) | |
120 | |
121 /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */ | |
122 H_total_pixels = total_active_pixels + blanking_time ; | |
123 DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels) | |
124 H_freq = freq / H_total_pixels * 1000; | |
125 DEBUG_PRINTF("H_freq: %f\n",H_freq) | |
126 actual_H_period = 1000 / H_freq; | |
127 DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period) | |
128 sync_plus_BP = round(H_freq * c.min_Vsync_BP/1000); | |
129 // sync_plus_BP = round( freq / H_total_pixels * c.min_Vsync_BP); | |
130 | |
131 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
132 | |
133 } else if (type == GTF_VF) | |
134 { | |
135 | |
136 /* ESTIMATE HORIZ. PERIOD [us] */ | |
137 | |
138 estimated_H_period = (( 1/RR ) - c.min_Vsync_BP/1000000 ) / (Y + (2 * margin_top) + c.min_front_porch + interlace) * 1000000; | |
139 | |
140 DEBUG_PRINTF("estimated_H_period: %f\n",estimated_H_period) | |
141 | |
142 /* FIND NUMBER OF LINES IN (SYNC + BACK PORCH) [lines] */ | |
143 | |
144 sync_plus_BP = round( c.min_Vsync_BP / estimated_H_period ); | |
145 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
146 | |
147 } else if (type == GTF_HF) | |
148 { | |
149 sync_plus_BP = round(freq * c.min_Vsync_BP/1000); | |
150 DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP) | |
151 } | |
152 | |
153 | |
154 | |
155 /* FIND TOTAL NUMBER OF LINES IN VERTICAL FIELD */ | |
156 | |
157 V_total_lines_field = sync_plus_BP+interlace+margin_bottom+margin_top+Y+c.min_front_porch; | |
158 DEBUG_PRINTF("V_total_lines_field : %f\n",V_total_lines_field ) | |
159 | |
160 if (type == GTF_VF) | |
161 { | |
162 /* ESTIMATE VERTICAL FIELD RATE [hz] */ | |
163 | |
164 estimated_V_field_rate = 1 / estimated_H_period / V_total_lines_field * 1000000; | |
165 DEBUG_PRINTF(" estimated_V_field_rate: %f\n", estimated_V_field_rate) | |
166 /* FIND ACTUAL HORIZONTAL PERIOD [us] */ | |
167 | |
168 actual_H_period = estimated_H_period / (RR / estimated_V_field_rate); | |
169 DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period) | |
170 /* FIND ACTUAL VERTICAL FIELD FREQUENCY [Hz] */ | |
171 | |
172 actual_V_field_freq = 1 / actual_H_period / V_total_lines_field * 1000000; | |
173 DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq) | |
174 | |
175 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
176 ideal_duty_cycle = c.c - (c.m * actual_H_period /1000); | |
177 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
178 //if (type == GTF_VF) | |
179 //{ | |
180 //moved | |
181 //} | |
182 } else if (type == GTF_HF) | |
183 { | |
184 /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */ | |
185 ideal_duty_cycle = c.c - (c.m / freq); | |
186 DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle) | |
187 } | |
188 | |
189 /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */ | |
190 | |
191 if (!(type == GTF_PF)) | |
192 { | |
193 blanking_time = round(total_active_pixels * ideal_duty_cycle \ | |
194 / (100-ideal_duty_cycle) / (2*c.char_cell_granularity)) \ | |
195 * (2*c.char_cell_granularity); | |
196 DEBUG_PRINTF("blanking_time : %f\n",blanking_time ) | |
197 } | |
198 else | |
199 // if (type == GTF_PF) | |
200 { | |
201 actual_V_field_freq = H_freq / V_total_lines_field * 1000; | |
202 } | |
203 | |
204 if (type == GTF_HF) | |
205 { | |
206 /* Hz */ | |
207 actual_V_field_freq = freq / V_total_lines_field * 1000; | |
208 DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq) | |
209 } | |
210 | |
211 | |
212 actual_V_frame_freq = actual_V_field_freq; | |
213 | |
214 /* FIND ACTUAL VERTICAL FRAME FREQUENCY [Hz]*/ | |
215 | |
216 if (want_interlace) actual_V_frame_freq = actual_V_field_freq / 2; | |
217 DEBUG_PRINTF("actual_V_frame_freq: %f\n",actual_V_frame_freq) | |
218 | |
219 // V_freq = actual_V_frame_freq; | |
220 // DEBUG_PRINTF("V_freq %f\n",V_freq) | |
221 | |
222 | |
223 if (!(type == GTF_PF)) | |
224 { | |
225 /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */ | |
226 H_total_pixels = total_active_pixels + blanking_time ; | |
227 DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels) | |
228 if (type == GTF_VF) | |
229 { | |
230 /* FIND PIXEL FREQUENCY [Mhz] */ | |
231 pixel_freq = H_total_pixels / actual_H_period ; | |
232 DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq) | |
233 } else if (type == GTF_HF) | |
234 { | |
235 /* FIND PIXEL FREQUENCY [Mhz] */ | |
236 pixel_freq = H_total_pixels * freq / 1000 ; | |
237 DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq) | |
238 actual_H_period = 1000/freq; | |
239 } | |
240 | |
241 /* FIND ACTUAL HORIZONTAL FREQUENCY [KHz] */ | |
242 | |
243 H_freq = 1000 / actual_H_period; | |
244 DEBUG_PRINTF("H_freq %f\n",H_freq) | |
245 | |
246 | |
247 } | |
248 | |
249 /* FIND NUMBER OF LINES IN BACK PORCH [lines] */ | |
250 | |
251 BP = sync_plus_BP - c.Vsync_need; | |
252 DEBUG_PRINTF("BP: %f\n",BP) | |
253 | |
254 /*------------------------------------------------------------------------------------------------*/ | |
255 /* FIND H SYNC WIDTH (TO NEAREST CHAR CELL) */ | |
256 H_sync_width = round(c.sync_width/100*H_total_pixels/c.char_cell_granularity)*c.char_cell_granularity; | |
257 DEBUG_PRINTF("H_sync_width %f\n",H_sync_width) | |
258 | |
259 /* FIND FRONT H PORCH(TO NEAREST CHAR CELL) */ | |
260 H_front_porch = (blanking_time/2) - H_sync_width; | |
261 DEBUG_PRINTF("H_front_porch %f\n",H_front_porch) | |
262 /* FIND BACK H PORCH(TO NEAREST CHAR CELL) */ | |
263 H_back_porch = H_sync_width + H_front_porch; | |
264 DEBUG_PRINTF("H_back_porch%f\n",H_back_porch) | |
265 | |
266 H_sync_start = H_total_pixels - (H_sync_width + H_back_porch); | |
267 DEBUG_PRINTF("H_sync_start %f\n",H_sync_start) | |
268 H_sync_end = H_total_pixels - H_back_porch; | |
269 DEBUG_PRINTF("H_sync_end %f\n",H_sync_end) | |
270 | |
271 V_back_porch = interlace + BP; | |
272 DEBUG_PRINTF("V_back_porch%f\n",V_back_porch) | |
273 V_front_porch = interlace + c.min_front_porch; | |
274 DEBUG_PRINTF("V_front_porch%f\n",V_front_porch) | |
275 | |
276 V_sync_width = c.Vsync_need; | |
277 V_sync_start = V_total_lines_field - (V_sync_width + V_back_porch); | |
278 DEBUG_PRINTF("V_sync_start %f\n",V_sync_start) | |
279 V_sync_end = V_total_lines_field - V_back_porch; | |
280 DEBUG_PRINTF("V_sync_end %f\n",V_sync_end) | |
281 | |
282 result->hTotal = H_total_pixels; | |
283 result-> hSyncStart = H_sync_start; /* Horizontal sync start in pixels */ | |
284 result-> hSyncEnd = H_sync_end; /* Horizontal sync end in pixels */ | |
285 result-> vTotal= V_total_lines_field; /* Vertical total in lines */ | |
286 result-> vSyncStart = V_sync_start; /* Vertical sync start in lines */ | |
287 result-> vSyncEnd = V_sync_end; /* Vertical sync end in lines */ | |
288 result-> Flags = (result->Flags)|VESA_CRTC_HSYNC_NEG; /* Flags (Interlaced, Double Scan etc) */ | |
289 | |
290 if (want_interlace) | |
291 { | |
292 result->Flags = (result->Flags) | VESA_CRTC_INTERLACED; | |
293 } | |
294 | |
295 result-> PixelClock = pixel_freq*1000000; /* Pixel clock in units of Hz */ | |
296 result-> RefreshRate = actual_V_frame_freq*100;/* Refresh rate in units of 0.01 Hz*/ | |
297 | |
298 } | |
299 | |
300 |