Mercurial > mplayer.hg
annotate libvo/vo_syncfb.c @ 6624:122efdee5b52
sync
author | nexus |
---|---|
date | Wed, 03 Jul 2002 08:06:43 +0000 |
parents | 32e1f5042f65 |
children | eca7dbad0166 |
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 LIBVO_EXTERN(syncfb) | |
38 | |
39 #include <sys/ioctl.h> | |
40 #include <unistd.h> | |
41 #include <fcntl.h> | |
42 #include <sys/mman.h> | |
43 #include <linux/videodev.h> | |
44 | |
45 #include "drivers/syncfb/syncfb.h" | |
46 | |
354 | 47 #include "fastmemcpy.h" |
350 | 48 |
1 | 49 static vo_info_t vo_info = |
50 { | |
51 "Matrox G200/G400 Synchronous framebuffer (/dev/syncfb)", | |
52 "syncfb", | |
53 "Matthias Oelmann <mao@well.com>", | |
54 "" | |
55 }; | |
56 | |
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 | |
4433 | 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,const vo_tune_info_t *info) |
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 static const vo_info_t* | |
435 get_info(void) | |
436 { | |
437 return &vo_info; | |
438 } | |
439 | |
440 | |
441 static void | |
442 uninit(void) | |
443 { | |
444 if (ioctl(f,SYNCFB_OFF,0)) perror("Error in OFF ioctl"); | |
445 | |
446 } | |
447 | |
31 | 448 static void check_events(void) |
449 { | |
450 } | |
1 | 451 |
4352 | 452 static uint32_t preinit(const char *arg) |
453 { | |
4737
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
454 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
|
455 { |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
456 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
|
457 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
|
458 } |
32e1f5042f65
I don't like such reports: '-vo dga:vidix or -vo x11:vidix works fine for me'
nick
parents:
4596
diff
changeset
|
459 return 0; |
4352 | 460 } |
461 | |
4596 | 462 static uint32_t control(uint32_t request, void *data, ...) |
4352 | 463 { |
4592
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
464 switch (request) { |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
465 case VOCTRL_QUERY_FORMAT: |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
466 return query_format(*((uint32_t*)data)); |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
467 } |
5fbfd8545c3b
query_ stuff replaced by new control() - patch by David Holm
arpi
parents:
4433
diff
changeset
|
468 return VO_NOTIMPL; |
4352 | 469 } |