Mercurial > mplayer.hg
annotate libvo/vo_syncfb.c @ 4488:7e8910727e7a
config file support for mencoder
author | rfelker |
---|---|
date | Sat, 02 Feb 2002 23:39:53 +0000 |
parents | df8e0f71cc3c |
children | 5fbfd8545c3b |
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> | |
31 | |
32 #include "config.h" | |
33 #include "video_out.h" | |
34 #include "video_out_internal.h" | |
35 | |
36 LIBVO_EXTERN(syncfb) | |
37 | |
38 #include <sys/ioctl.h> | |
39 #include <unistd.h> | |
40 #include <fcntl.h> | |
41 #include <sys/mman.h> | |
42 #include <linux/videodev.h> | |
43 | |
44 #include "drivers/syncfb/syncfb.h" | |
45 | |
354 | 46 #include "fastmemcpy.h" |
350 | 47 |
1 | 48 static vo_info_t vo_info = |
49 { | |
50 "Matrox G200/G400 Synchronous framebuffer (/dev/syncfb)", | |
51 "syncfb", | |
52 "Matthias Oelmann <mao@well.com>", | |
53 "" | |
54 }; | |
55 | |
56 /* deinterlacing on? looks only good in 50 Hz(PAL) or 60 Hz(NTSC) modes */ | |
57 static int vo_conf_deinterlace = 0; | |
58 | |
59 /* 72/75 Hz Monitor frequency for progressive output */ | |
60 static int vo_conf_cinemode = 0; | |
61 | |
62 | |
4433 | 63 static syncfb_config_t _config; |
1 | 64 static syncfb_capability_t sfb_caps; |
65 | |
66 static syncfb_buffer_info_t bufinfo; | |
67 | |
68 static uint_8 *vid_data; | |
69 static uint_8 *frame_mem; | |
70 | |
71 static int debug_skip_first = 250; | |
72 static int dbg_singleframe = 0; | |
73 | |
74 static int conf_palette; | |
75 | |
76 static int f; | |
77 | |
78 | |
79 | |
80 /* | |
81 it seems that mpeg2dec never calls | |
82 draw_frame, so i could not test it.... | |
83 */ | |
84 | |
85 static void | |
86 write_frame_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
87 { | |
88 uint_8 *crp, *cbp; | |
89 uint_32 *dest32; | |
90 uint_32 bespitch,h,w; | |
91 | |
92 | |
4433 | 93 bespitch = _config.src_pitch; |
1 | 94 dest32 = (uint_32 *)vid_data; |
95 | |
4433 | 96 for(h=0; h < _config.src_height/2; h++) |
1 | 97 { |
98 cbp = cb; | |
99 crp = cr; | |
4433 | 100 for(w=0; w < _config.src_width/2; w++) |
1 | 101 { |
102 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
103 y++; y++; cb++; cr++; | |
104 } | |
4433 | 105 dest32 += (bespitch - _config.src_width) / 2; |
1 | 106 |
4433 | 107 for(w=0; w < _config.src_width/2; w++) |
1 | 108 { |
109 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
110 y++; y++; cbp++; crp++; | |
111 } | |
4433 | 112 dest32 += (bespitch - _config.src_width) / 2; |
1 | 113 } |
114 } | |
115 | |
116 | |
117 static void | |
118 write_frame_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
119 { | |
120 uint_8 *dest, *tmp; | |
121 uint_32 bespitch,h,w; | |
122 | |
4433 | 123 bespitch = _config.src_pitch; |
1 | 124 dest = frame_mem + bufinfo.offset; |
125 | |
4433 | 126 for(h=0; h < _config.src_height; h++) |
1 | 127 { |
4433 | 128 memcpy(dest, y, _config.src_width); |
129 y += _config.src_width; | |
1 | 130 dest += bespitch; |
131 } | |
132 | |
133 dest = frame_mem + bufinfo.offset_p2; | |
4433 | 134 for(h=0; h < _config.src_height/2; h++) |
1 | 135 { |
136 tmp = dest; | |
4433 | 137 for(w=0; w < _config.src_width/2; w++) |
1 | 138 { |
139 *tmp++ = *cr++; | |
140 *tmp++ = *cb++; | |
141 } | |
142 dest += bespitch; | |
143 } | |
144 } | |
145 | |
146 static void | |
147 write_frame_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb) | |
148 { | |
149 } | |
150 | |
151 static void | |
152 write_slice_YUV420P2(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) | |
153 { | |
154 uint_8 *dest, *tmp; | |
155 uint_32 bespitch,h,w; | |
156 | |
4433 | 157 bespitch = _config.src_pitch; |
1 | 158 dest = frame_mem + bufinfo.offset + (bespitch * 16 * slice_num); |
159 | |
160 for(h=0; h < 16; h++) | |
161 { | |
4433 | 162 memcpy(dest, y, _config.src_width); |
163 y += _config.src_width; | |
1 | 164 dest += bespitch; |
165 } | |
166 | |
167 dest = frame_mem + bufinfo.offset_p2 + (bespitch * 16 * slice_num) /2; | |
168 for(h=0; h < 8; h++) | |
169 { | |
170 tmp = dest; | |
4433 | 171 for(w=0; w < _config.src_width/2; w++) |
1 | 172 { |
173 *tmp++ = *cr++; | |
174 *tmp++ = *cb++; | |
175 } | |
176 dest += bespitch; | |
177 } | |
178 } | |
179 | |
180 static void | |
181 write_slice_YUV420P3(uint_8 *y,uint_8 *cr, uint_8 *cb,int stride[],uint_32 ypos,uint_32 xsize,uint_32 ysize) | |
182 { | |
183 uint_8 *dest; | |
184 uint_32 bespitch,h; | |
185 | |
4433 | 186 bespitch = _config.src_pitch; |
1 | 187 |
188 dest = frame_mem + bufinfo.offset + (bespitch * ypos); | |
189 for(h=0; h < ysize; h++) | |
190 { | |
191 memcpy(dest, y, xsize); | |
192 y += stride[0]; | |
193 dest += bespitch; | |
194 } | |
195 | |
196 xsize/=2; | |
197 ysize/=2; | |
198 | |
199 dest = frame_mem + bufinfo.offset_p2 + (bespitch * ypos)/4; | |
200 for(h=0; h < ysize; h++) | |
201 { | |
202 memcpy(dest, cr, xsize); | |
203 cr += stride[1]; | |
204 dest += bespitch/2; | |
205 } | |
206 | |
207 dest = frame_mem + bufinfo.offset_p3 + (bespitch * ypos)/4; | |
208 for(h=0; h < ysize; h++) | |
209 { | |
210 memcpy(dest, cb, xsize); | |
211 cb += stride[2]; | |
212 dest += bespitch/2; | |
213 } | |
214 | |
215 | |
216 } | |
217 | |
218 | |
219 static void | |
220 write_slice_YUV422(uint_8 *y,uint_8 *cr, uint_8 *cb,uint_32 slice_num) | |
221 { | |
222 uint_8 *crp, *cbp; | |
223 uint_32 *dest32; | |
224 uint_32 bespitch,h,w; | |
225 | |
226 | |
4433 | 227 bespitch = _config.src_pitch; |
1 | 228 dest32 = (uint_32 *)(vid_data + (bespitch * 16 * slice_num) * 2); |
229 | |
230 for(h=0; h < 8; h++) | |
231 { | |
232 cbp = cb; | |
233 crp = cr; | |
4433 | 234 for(w=0; w < _config.src_width/2; w++) |
1 | 235 { |
236 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
237 y++; y++; cb++; cr++; | |
238 } | |
4433 | 239 dest32 += (bespitch - _config.src_width) / 2; |
1 | 240 |
4433 | 241 for(w=0; w < _config.src_width/2; w++) |
1 | 242 { |
243 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
244 y++; y++; cbp++; crp++; | |
245 } | |
4433 | 246 dest32 += (bespitch - _config.src_width) / 2; |
1 | 247 } |
248 } | |
249 | |
250 //static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num) | |
251 static uint32_t | |
252 draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y) | |
253 { | |
254 | |
255 if ( vid_data == NULL ) return 0; | |
256 | |
257 write_slice_YUV420P3(src[0],src[1], src[2],stride,y,w,h); | |
258 | |
259 //printf("sorry, not syncfb/draw_slice() implemented yet...\n"); | |
260 | |
261 #if 0 | |
262 | |
263 if ( conf_palette == VIDEO_PALETTE_YUV422 ) { | |
264 write_slice_YUV422(src[0],src[1], src[2],slice_num); | |
265 } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { | |
266 write_slice_YUV420P2(src[0],src[1], src[2],slice_num); | |
267 } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { | |
268 write_slice_YUV420P3(src[0],src[1], src[2],slice_num); | |
269 } | |
270 #endif | |
271 | |
272 return 0; | |
273 } | |
274 | |
1501
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
275 static void draw_osd(void) |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
276 { |
d40f2b686846
changes according to -utf8 option, draw_osd() function added
atlka
parents:
614
diff
changeset
|
277 } |
1 | 278 |
279 static void | |
280 flip_page(void) | |
281 { | |
282 | |
4433 | 283 // memset(frame_mem + bufinfo.offset_p2, 0x80, _config.src_width*config.src_height); |
1 | 284 ioctl(f,SYNCFB_COMMIT_BUFFER,&bufinfo); |
285 | |
286 if ( dbg_singleframe ) { | |
287 if ( debug_skip_first == 0 ) { | |
288 printf( "Press 'anykey' for field 1\n" ); | |
289 getchar(); | |
290 ioctl(f,SYNCFB_VBI,0); | |
291 } | |
292 | |
293 if ( debug_skip_first > 0 ) { | |
294 debug_skip_first--; | |
295 // debug_skip_first = 0; | |
296 if ( debug_skip_first == 0 ) { | |
297 ioctl(f,SYNCFB_VBI,0); | |
298 ioctl(f,SYNCFB_VBI,0); | |
299 ioctl(f,SYNCFB_VBI,0); | |
300 } | |
301 } | |
302 | |
303 if ( debug_skip_first == 0 ) { | |
304 printf( "Press 'anykey' for field 2\n" ); | |
305 getchar(); | |
306 ioctl(f,SYNCFB_VBI,0); | |
307 } | |
308 } | |
309 | |
310 ioctl(f,SYNCFB_REQUEST_BUFFER,&bufinfo); | |
311 if ( bufinfo.id == -1 ) printf( "Got buffer #%d\n", bufinfo.id ); | |
312 | |
313 vid_data = (uint_8 *)(frame_mem + bufinfo.offset); | |
314 if ( bufinfo.id == -1 ) { | |
315 //vid_data = frame_mem; | |
316 vid_data = NULL; | |
317 } | |
318 // printf("Flip %d\n", bufinfo.offset); | |
319 | |
320 } | |
321 | |
322 static uint32_t draw_frame(uint8_t *src[]) | |
323 { | |
324 printf("DRAW FRAME!!!\n"); | |
325 if ( conf_palette == VIDEO_PALETTE_YUV422 ) { | |
326 write_frame_YUV422(src[0],src[1], src[2]); | |
327 } else if ( conf_palette == VIDEO_PALETTE_YUV420P2 ) { | |
328 write_frame_YUV420P2(src[0],src[1], src[2]); | |
329 } else if ( conf_palette == VIDEO_PALETTE_YUV420P3 ) { | |
330 write_frame_YUV420P3(src[0],src[1], src[2]); | |
331 } | |
332 | |
333 flip_page(); | |
334 return 0; | |
335 } | |
336 | |
337 static uint32_t | |
338 query_format(uint32_t format) | |
339 { | |
340 switch(format){ | |
341 case IMGFMT_YV12: | |
342 // case IMGFMT_RGB|24: | |
343 // case IMGFMT_BGR|24: | |
344 return 1; | |
345 } | |
346 return 0; | |
347 } | |
348 | |
4433 | 349 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 | 350 { |
351 uint_32 frame_size; | |
352 | |
353 f = open("/dev/syncfb",O_RDWR); | |
354 | |
355 if(f == -1) | |
356 { | |
357 f = open("/dev/mga_vid",O_RDWR); | |
358 if(f == -1) | |
359 { | |
614 | 360 printf("Couldn't open /dev/syncfb or /dev/mga_vid\n"); |
1 | 361 return(-1); |
362 } | |
363 } | |
364 | |
365 if (ioctl(f,SYNCFB_GET_CAPS,&sfb_caps)) perror("Error in mga_vid_config ioctl"); | |
366 if (ioctl(f,SYNCFB_GET_CONFIG,&config)) perror("Error in mga_vid_config ioctl"); | |
367 | |
368 if (sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV420P3) ) { | |
4433 | 369 _config.src_palette= VIDEO_PALETTE_YUV420P3; |
1 | 370 printf("using palette yuv420p3\n"); |
371 }else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV420P2) ) { | |
4433 | 372 _config.src_palette= VIDEO_PALETTE_YUV420P2; |
1 | 373 printf("using palette yuv420p2\n"); |
374 } else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV422) ) { | |
4433 | 375 _config.src_palette= VIDEO_PALETTE_YUV422; |
1 | 376 printf("using palette yuv422\n"); |
377 } else { | |
378 printf("no supported palette found\n"); | |
1633 | 379 return -1; |
1 | 380 } |
381 | |
4433 | 382 // _config.src_palette= VIDEO_PALETTE_YUV422; |
1 | 383 |
384 if ( vo_conf_cinemode ) { | |
4433 | 385 _config.default_repeat = 3; |
1 | 386 } else { |
4433 | 387 _config.default_repeat = 2; |
1 | 388 } |
389 | |
4433 | 390 conf_palette = _config.src_palette; |
1 | 391 if ( vo_conf_deinterlace ) { |
4433 | 392 _config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST | SYNCFB_FEATURE_DEINTERLACE; |
393 _config.default_repeat = 1; | |
1 | 394 } else { |
4433 | 395 _config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST; |
1 | 396 } |
397 | |
4433 | 398 _config.fb_screen_size = (RAM_SIZE-4)*0x100000; //(1280 * 1024 * 32) / 8; |
399 _config.src_width = width; | |
400 _config.src_height= height; | |
1 | 401 |
4433 | 402 _config.image_width = d_width; |
403 _config.image_height= d_height; | |
404 //_config.image_width = 1024; | |
405 //_config.image_height= 576; | |
1 | 406 |
4433 | 407 _config.image_xorg= 0; |
408 _config.image_yorg= 0; | |
1 | 409 |
410 | |
411 printf ("BES Sourcer size: %d x %d\n", width, height); | |
412 | |
413 ioctl(f,SYNCFB_ON,0); | |
4433 | 414 if (ioctl(f,SYNCFB_SET_CONFIG,&_config)) perror("Error in mga_vid_config ioctl"); |
1 | 415 |
4433 | 416 printf ("Framebuffer memory: %ld in %ld buffers\n", sfb_caps.memory_size, _config.buffers); |
1 | 417 |
418 frame_size = ((width + 31) & ~31) * height + (((width + 31) & ~31) * height) / 2; | |
419 frame_mem = (uint_8*)mmap(0,sfb_caps.memory_size,PROT_WRITE,MAP_SHARED,f,0); | |
420 | |
421 printf( "Requesting first buffer #%d\n", bufinfo.id ); | |
422 ioctl(f,SYNCFB_REQUEST_BUFFER,&bufinfo); | |
423 printf( "Got first buffer #%d\n", bufinfo.id ); | |
424 | |
425 | |
426 vid_data = (uint_8 *)(frame_mem + bufinfo.offset); | |
427 | |
428 //clear the buffer | |
429 // memset(frame_mem,0x80,frame_size*2); | |
430 return 0; | |
431 } | |
432 | |
433 static const vo_info_t* | |
434 get_info(void) | |
435 { | |
436 return &vo_info; | |
437 } | |
438 | |
439 | |
440 static void | |
441 uninit(void) | |
442 { | |
443 if (ioctl(f,SYNCFB_OFF,0)) perror("Error in OFF ioctl"); | |
444 | |
445 } | |
446 | |
31 | 447 static void check_events(void) |
448 { | |
449 } | |
1 | 450 |
4352 | 451 static uint32_t preinit(const char *arg) |
452 { | |
453 return 0; | |
454 } | |
455 | |
456 static void query_vaa(vo_vaa_t *vaa) | |
457 { | |
458 memset(vaa,0,sizeof(vo_vaa_t)); | |
459 } |