Mercurial > mplayer.hg
annotate libvo/vo_syncfb.c @ 8843:c70444c5b516
I have seen problems where DVD subtitles don't display
at the right time and sometimes they don't appear at
all. The problem stems from the fact that subtitle
command packets are being applied as soon as they are
read and assembled from the input stream. Sometimes,
a fully assembled subtitle packet arrives at the
spudec_assemble function before the previous subtitle
appears onscreen and thus the viewer only sees the
second subtitle. So I created a patch that queues
assembled subtitle packets and applies them at the
appropriate time within the heartbeat function. The
reset function clears the packet queue when seeking
through the video.
Tomasz Farkas <tomasz_farkas@yahoo.co.uk>
author | arpi |
---|---|
date | Wed, 08 Jan 2003 18:36:36 +0000 |
parents | 5b39e79af5fe |
children | 05aa13cdf92f |
rev | line source |
---|---|
1 | 1 |
2 // How many MegaBytes of RAM is on your G200/G400 card? | |
3 #define RAM_SIZE 16 | |
4 | |
5 /* | |
6 * video_out_syncfb.c | |
7 * | |
8 * Copyright (C) Aaron Holtzman - Aug 1999 | |
9 * | |
10 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. | |
11 * | |
12 * mpeg2dec is free software; you can redistribute it and/or modify | |
13 * it under the terms of the GNU General Public License as published by | |
14 * the Free Software Foundation; either version 2, or (at your option) | |
15 * any later version. | |
16 * | |
17 * mpeg2dec is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with GNU Make; see the file COPYING. If not, write to | |
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 * | |
26 */ | |
27 | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 #include <string.h> | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
31 #include <errno.h> |
1 | 32 |
33 #include "config.h" | |
34 #include "video_out.h" | |
35 #include "video_out_internal.h" | |
36 | |
37 #include <sys/ioctl.h> | |
38 #include <unistd.h> | |
39 #include <fcntl.h> | |
40 #include <sys/mman.h> | |
41 #include <linux/videodev.h> | |
42 | |
43 #include "drivers/syncfb/syncfb.h" | |
44 | |
354 | 45 #include "fastmemcpy.h" |
350 | 46 |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
7124
diff
changeset
|
47 static vo_info_t info = |
1 | 48 { |
49 "Matrox G200/G400 Synchronous framebuffer (/dev/syncfb)", | |
50 "syncfb", | |
51 "Matthias Oelmann <mao@well.com>", | |
52 "" | |
53 }; | |
54 | |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
7124
diff
changeset
|
55 LIBVO_EXTERN(syncfb) |
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
7124
diff
changeset
|
56 |
1 | 57 /* deinterlacing on? looks only good in 50 Hz(PAL) or 60 Hz(NTSC) modes */ |
58 static int vo_conf_deinterlace = 0; | |
59 | |
60 /* 72/75 Hz Monitor frequency for progressive output */ | |
61 static int vo_conf_cinemode = 0; | |
62 | |
63 | |
4433 | 64 static syncfb_config_t _config; |
1 | 65 static syncfb_capability_t sfb_caps; |
66 | |
67 static syncfb_buffer_info_t bufinfo; | |
68 | |
69 static uint_8 *vid_data; | |
70 static uint_8 *frame_mem; | |
71 | |
72 static int debug_skip_first = 250; | |
73 static int dbg_singleframe = 0; | |
74 | |
75 static int conf_palette; | |
76 | |
77 static int f; | |
78 | |
79 | |
80 | |
81 /* | |
82 it seems that mpeg2dec never calls | |
83 draw_frame, so i could not test it.... | |
84 */ | |
85 | |
86 static void | |
87 write_frame_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
88 { | |
89 uint_8 *crp, *cbp; | |
90 uint_32 *dest32; | |
91 uint_32 bespitch,h,w; | |
92 | |
93 | |
4433 | 94 bespitch = _config.src_pitch; |
1 | 95 dest32 = (uint_32 *)vid_data; |
96 | |
4433 | 97 for(h=0; h < _config.src_height/2; h++) |
1 | 98 { |
99 cbp = cb; | |
100 crp = cr; | |
4433 | 101 for(w=0; w < _config.src_width/2; w++) |
1 | 102 { |
103 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
104 y++; y++; cb++; cr++; | |
105 } | |
4433 | 106 dest32 += (bespitch - _config.src_width) / 2; |
1 | 107 |
4433 | 108 for(w=0; w < _config.src_width/2; w++) |
1 | 109 { |
110 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
111 y++; y++; cbp++; crp++; | |
112 } | |
4433 | 113 dest32 += (bespitch - _config.src_width) / 2; |
1 | 114 } |
115 } | |
116 | |
117 | |
118 static void | |
119 write_frame_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
120 { | |
121 uint_8 *dest, *tmp; | |
122 uint_32 bespitch,h,w; | |
123 | |
4433 | 124 bespitch = _config.src_pitch; |
1 | 125 dest = frame_mem + bufinfo.offset; |
126 | |
4433 | 127 for(h=0; h < _config.src_height; h++) |
1 | 128 { |
4433 | 129 memcpy(dest, y, _config.src_width); |
130 y += _config.src_width; | |
1 | 131 dest += bespitch; |
132 } | |
133 | |
134 dest = frame_mem + bufinfo.offset_p2; | |
4433 | 135 for(h=0; h < _config.src_height/2; h++) |
1 | 136 { |
137 tmp = dest; | |
4433 | 138 for(w=0; w < _config.src_width/2; w++) |
1 | 139 { |
140 *tmp++ = *cr++; | |
141 *tmp++ = *cb++; | |
142 } | |
143 dest += bespitch; | |
144 } | |
145 } | |
146 | |
147 static void | |
148 write_frame_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
149 { | |
150 } | |
151 | |
152 static void | |
153 write_slice_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) | |
154 { | |
155 uint_8 *dest, *tmp; | |
156 uint_32 bespitch,h,w; | |
157 | |
4433 | 158 bespitch = _config.src_pitch; |
1 | 159 dest = frame_mem + bufinfo.offset + (bespitch * 16 * slice_num); |
160 | |
161 for(h=0; h < 16; h++) | |
162 { | |
4433 | 163 memcpy(dest, y, _config.src_width); |
164 y += _config.src_width; | |
1 | 165 dest += bespitch; |
166 } | |
167 | |
168 dest = frame_mem + bufinfo.offset_p2 + (bespitch * 16 * slice_num) /2; | |
169 for(h=0; h < 8; h++) | |
170 { | |
171 tmp = dest; | |
4433 | 172 for(w=0; w < _config.src_width/2; w++) |
1 | 173 { |
174 *tmp++ = *cr++; | |
175 *tmp++ = *cb++; | |
176 } | |
177 dest += bespitch; | |
178 } | |
179 } | |
180 | |
181 static void | |
182 write_slice_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb,int stride[],uint_32 ypos,uint_32 xsize,uint_32 ysize) | |
183 { | |
184 uint_8 *dest; | |
185 uint_32 bespitch,h; | |
186 | |
4433 | 187 bespitch = _config.src_pitch; |
1 | 188 |
189 dest = frame_mem + bufinfo.offset + (bespitch * ypos); | |
190 for(h=0; h < ysize; h++) | |
191 { | |
192 memcpy(dest, y, xsize); | |
193 y += stride[0]; | |
194 dest += bespitch; | |
195 } | |
196 | |
197 xsize/=2; | |
198 ysize/=2; | |
199 | |
200 dest = frame_mem + bufinfo.offset_p2 + (bespitch * ypos)/4; | |
201 for(h=0; h < ysize; h++) | |
202 { | |
203 memcpy(dest, cr, xsize); | |
204 cr += stride[1]; | |
205 dest += bespitch/2; | |
206 } | |
207 | |
208 dest = frame_mem + bufinfo.offset_p3 + (bespitch * ypos)/4; | |
209 for(h=0; h < ysize; h++) | |
210 { | |
211 memcpy(dest, cb, xsize); | |
212 cb += stride[2]; | |
213 dest += bespitch/2; | |
214 } | |
215 | |
216 | |
217 } | |
218 | |
219 | |
220 static void | |
221 write_slice_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) | |
222 { | |
223 uint_8 *crp, *cbp; | |
224 uint_32 *dest32; | |
225 uint_32 bespitch,h,w; | |
226 | |
227 | |
4433 | 228 bespitch = _config.src_pitch; |
1 | 229 dest32 = (uint_32 *)(vid_data + (bespitch * 16 * slice_num) * 2); |
230 | |
231 for(h=0; h < 8; h++) | |
232 { | |
233 cbp = cb; | |
234 crp = cr; | |
4433 | 235 for(w=0; w < _config.src_width/2; w++) |
1 | 236 { |
237 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
238 y++; y++; cb++; cr++; | |
239 } | |
4433 | 240 dest32 += (bespitch - _config.src_width) / 2; |
1 | 241 |
4433 | 242 for(w=0; w < _config.src_width/2; w++) |
1 | 243 { |
244 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
245 y++; y++; cbp++; crp++; | |
246 } | |
4433 | 247 dest32 += (bespitch - _config.src_width) / 2; |
1 | 248 } |
249 } | |
250 | |
251 //static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num) | |
252 static uint32_t | |
253 draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) | |
254 { | |
255 | |
256 if ( vid_data == NULL ) return 0; | |
257 | |
258 write_slice_YUV420P3(src[0],src[1], src[2],stride,y,w,h); | |
259 | |
260 //printf("sorry, not syncfb/draw_slice() implemented yet...\n"); | |
261 | |
262 #if 0 | |
263 | |
264 if ( conf_palette == VIDEO_PALETTE_YUV422 ) { | |
265 write_slice_YUV422(src[0],src[1], src[2],slice_num); | |
266 } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { | |
267 write_slice_YUV420P2(src[0],src[1], src[2],slice_num); | |
268 } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { | |
269 write_slice_YUV420P3(src[0],src[1], src[2],slice_num); | |
270 } | |
271 #endif | |
272 | |
273 return 0; | |
274 } | |
275 | |
1501
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
276 static void draw_osd(void) |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
277 { |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
278 } |
1 | 279 |
280 static void | |
281 flip_page(void) | |
282 { | |
283 | |
4433 | 284 // memset(frame_mem + bufinfo.offset_p2, 0x80, _config.src_width*config.src_height); |
1 | 285 ioctl(f,SYNCFB_COMMIT_BUFFER,&bufinfo); |
286 | |
287 if ( dbg_singleframe ) { | |
288 if ( debug_skip_first == 0 ) { | |
289 printf( "Press 'anykey' for field 1\n" ); | |
290 getchar(); | |
291 ioctl(f,SYNCFB_VBI,0); | |
292 } | |
293 | |
294 if ( debug_skip_first > 0 ) { | |
295 debug_skip_first--; | |
296 // debug_skip_first = 0; | |
297 if ( debug_skip_first == 0 ) { | |
298 ioctl(f,SYNCFB_VBI,0); | |
299 ioctl(f,SYNCFB_VBI,0); | |
300 ioctl(f,SYNCFB_VBI,0); | |
301 } | |
302 } | |
303 | |
304 if ( debug_skip_first == 0 ) { | |
305 printf( "Press 'anykey' for field 2\n" ); | |
306 getchar(); | |
307 ioctl(f,SYNCFB_VBI,0); | |
308 } | |
309 } | |
310 | |
311 ioctl(f,SYNCFB_REQUEST_BUFFER,&bufinfo); | |
312 if ( bufinfo.id == -1 ) printf( "Got buffer #%d\n", bufinfo.id ); | |
313 | |
314 vid_data = (uint_8 *)(frame_mem + bufinfo.offset); | |
315 if ( bufinfo.id == -1 ) { | |
316 //vid_data = frame_mem; | |
317 vid_data = NULL; | |
318 } | |
319 // printf("Flip %d\n", bufinfo.offset); | |
320 | |
321 } | |
322 | |
323 static uint32_t draw_frame(uint8_t *src[]) | |
324 { | |
325 printf("DRAW FRAME!!!\n"); | |
326 if ( conf_palette == VIDEO_PALETTE_YUV422 ) { | |
327 write_frame_YUV422(src[0],src[1], src[2]); | |
328 } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { | |
329 write_frame_YUV420P2(src[0],src[1], src[2]); | |
330 } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { | |
331 write_frame_YUV420P3(src[0],src[1], src[2]); | |
332 } | |
333 | |
334 flip_page(); | |
335 return 0; | |
336 } | |
337 | |
338 static uint32_t | |
339 query_format(uint32_t format) | |
340 { | |
341 switch(format){ | |
342 case IMGFMT_YV12: | |
343 // case IMGFMT_RGB|24: | |
344 // case IMGFMT_BGR|24: | |
345 return 1; | |
346 } | |
347 return 0; | |
348 } | |
349 | |
7124
eca7dbad0166
finally removed query_vaa, bes_da and vo_tune_info - the obsoleted libvo api
alex
parents:
4737
diff
changeset
|
350 static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) |
1 | 351 { |
352 uint_32 frame_size; | |
353 | |
354 f = open("/dev/syncfb",O_RDWR); | |
355 | |
356 if(f == -1) | |
357 { | |
358 f = open("/dev/mga_vid",O_RDWR); | |
359 if(f == -1) | |
360 { | |
614 | 361 printf("Couldn't open /dev/syncfb or /dev/mga_vid\n"); |
1 | 362 return(-1); |
363 } | |
364 } | |
365 | |
366 if (ioctl(f,SYNCFB_GET_CAPS,&sfb_caps)) perror("Error in mga_vid_config ioctl"); | |
367 if (ioctl(f,SYNCFB_GET_CONFIG,&config)) perror("Error in mga_vid_config ioctl"); | |
368 | |
369 if (sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV420P3) ) { | |
4433 | 370 _config.src_palette= VIDEO_PALETTE_YUV420P3; |
1 | 371 printf("using palette yuv420p3\n"); |
372 }else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV420P2) ) { | |
4433 | 373 _config.src_palette= VIDEO_PALETTE_YUV420P2; |
1 | 374 printf("using palette yuv420p2\n"); |
375 } else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV422) ) { | |
4433 | 376 _config.src_palette= VIDEO_PALETTE_YUV422; |
1 | 377 printf("using palette yuv422\n"); |
378 } else { | |
379 printf("no supported palette found\n"); | |
1633 | 380 return -1; |
1 | 381 } |
382 | |
4433 | 383 // _config.src_palette= VIDEO_PALETTE_YUV422; |
1 | 384 |
385 if ( vo_conf_cinemode ) { | |
4433 | 386 _config.default_repeat = 3; |
1 | 387 } else { |
4433 | 388 _config.default_repeat = 2; |
1 | 389 } |
390 | |
4433 | 391 conf_palette = _config.src_palette; |
1 | 392 if ( vo_conf_deinterlace ) { |
4433 | 393 _config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST | SYNCFB_FEATURE_DEINTERLACE; |
394 _config.default_repeat = 1; | |
1 | 395 } else { |
4433 | 396 _config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST; |
1 | 397 } |
398 | |
4433 | 399 _config.fb_screen_size = (RAM_SIZE-4)*0x100000; //(1280 * 1024 * 32) / 8; |
400 _config.src_width = width; | |
401 _config.src_height= height; | |
1 | 402 |
4433 | 403 _config.image_width = d_width; |
404 _config.image_height= d_height; | |
405 //_config.image_width = 1024; | |
406 //_config.image_height= 576; | |
1 | 407 |
4433 | 408 _config.image_xorg= 0; |
409 _config.image_yorg= 0; | |
1 | 410 |
411 | |
412 printf ("BES Sourcer size: %d x %d\n", width, height); | |
413 | |
414 ioctl(f,SYNCFB_ON,0); | |
4433 | 415 if (ioctl(f,SYNCFB_SET_CONFIG,&_config)) perror("Error in mga_vid_config ioctl"); |
1 | 416 |
4433 | 417 printf ("Framebuffer memory: %ld in %ld buffers\n", sfb_caps.memory_size, _config.buffers); |
1 | 418 |
419 frame_size = ((width + 31) & ~31) * height + (((width + 31) & ~31) * height) / 2; | |
420 frame_mem = (uint_8*)mmap(0,sfb_caps.memory_size,PROT_WRITE,MAP_SHARED,f,0); | |
421 | |
422 printf( "Requesting first buffer #%d\n", bufinfo.id ); | |
423 ioctl(f,SYNCFB_REQUEST_BUFFER,&bufinfo); | |
424 printf( "Got first buffer #%d\n", bufinfo.id ); | |
425 | |
426 | |
427 vid_data = (uint_8 *)(frame_mem + bufinfo.offset); | |
428 | |
429 //clear the buffer | |
430 // memset(frame_mem,0x80,frame_size*2); | |
431 return 0; | |
432 } | |
433 | |
434 | |
435 static void | |
436 uninit(void) | |
437 { | |
438 if (ioctl(f,SYNCFB_OFF,0)) perror("Error in OFF ioctl"); | |
439 | |
440 } | |
441 | |
31 | 442 static void check_events(void) |
443 { | |
444 } | |
1 | 445 |
4352 | 446 static uint32_t preinit(const char *arg) |
447 { | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
448 if(arg) |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
449 { |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
450 printf("vo_syncfb: Unknown subdevice: %s\n",arg); |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
451 return ENOSYS; |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
452 } |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
453 return 0; |
4352 | 454 } |
455 | |
4596 | 456 static uint32_t control(uint32_t request, void *data, ...) |
4352 | 457 { |
4592
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
458 switch (request) { |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
459 case VOCTRL_QUERY_FORMAT: |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
460 return query_format(*((uint32_t*)data)); |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
461 } |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
462 return VO_NOTIMPL; |
4352 | 463 } |