Mercurial > mplayer.hg
annotate libvo/vo_syncfb.c @ 3779:b987b69d1bd6
101
author | michael |
---|---|
date | Wed, 26 Dec 2001 23:31:30 +0000 |
parents | 742d9e286b5d |
children | ed5b85b713a3 |
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 | |
63 static syncfb_config_t config; | |
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 | |
93 bespitch = config.src_pitch; | |
94 dest32 = (uint_32 *)vid_data; | |
95 | |
96 for(h=0; h < config.src_height/2; h++) | |
97 { | |
98 cbp = cb; | |
99 crp = cr; | |
100 for(w=0; w < config.src_width/2; w++) | |
101 { | |
102 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
103 y++; y++; cb++; cr++; | |
104 } | |
105 dest32 += (bespitch - config.src_width) / 2; | |
106 | |
107 for(w=0; w < config.src_width/2; w++) | |
108 { | |
109 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
110 y++; y++; cbp++; crp++; | |
111 } | |
112 dest32 += (bespitch - config.src_width) / 2; | |
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 | |
123 bespitch = config.src_pitch; | |
124 dest = frame_mem + bufinfo.offset; | |
125 | |
126 for(h=0; h < config.src_height; h++) | |
127 { | |
128 memcpy(dest, y, config.src_width); | |
129 y += config.src_width; | |
130 dest += bespitch; | |
131 } | |
132 | |
133 dest = frame_mem + bufinfo.offset_p2; | |
134 for(h=0; h < config.src_height/2; h++) | |
135 { | |
136 tmp = dest; | |
137 for(w=0; w < config.src_width/2; w++) | |
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 | |
157 bespitch = config.src_pitch; | |
158 dest = frame_mem + bufinfo.offset + (bespitch * 16 * slice_num); | |
159 | |
160 for(h=0; h < 16; h++) | |
161 { | |
162 memcpy(dest, y, config.src_width); | |
163 y += config.src_width; | |
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; | |
171 for(w=0; w < config.src_width/2; w++) | |
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 | |
186 bespitch = config.src_pitch; | |
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 | |
227 bespitch = config.src_pitch; | |
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; | |
234 for(w=0; w < config.src_width/2; w++) | |
235 { | |
236 *dest32++ = (*y) + ((*cr)<<8) + ((*(y+1))<<16) + ((*cb)<<24); | |
237 y++; y++; cb++; cr++; | |
238 } | |
239 dest32 += (bespitch - config.src_width) / 2; | |
240 | |
241 for(w=0; w < config.src_width/2; w++) | |
242 { | |
243 *dest32++ = (*y) + ((*crp)<<8) + ((*(y+1))<<16) + ((*cbp)<<24); | |
244 y++; y++; cbp++; crp++; | |
245 } | |
246 dest32 += (bespitch - config.src_width) / 2; | |
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 | |
283 // memset(frame_mem + bufinfo.offset_p2, 0x80, config.src_width*config.src_height); | |
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 | |
349 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format) | |
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) ) { | |
369 config.src_palette= VIDEO_PALETTE_YUV420P3; | |
370 printf("using palette yuv420p3\n"); | |
371 }else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV420P2) ) { | |
372 config.src_palette= VIDEO_PALETTE_YUV420P2; | |
373 printf("using palette yuv420p2\n"); | |
374 } else if ( sfb_caps.palettes & (1<<VIDEO_PALETTE_YUV422) ) { | |
375 config.src_palette= VIDEO_PALETTE_YUV422; | |
376 printf("using palette yuv422\n"); | |
377 } else { | |
378 printf("no supported palette found\n"); | |
1633 | 379 return -1; |
1 | 380 } |
381 | |
382 // config.src_palette= VIDEO_PALETTE_YUV422; | |
383 | |
384 if ( vo_conf_cinemode ) { | |
385 config.default_repeat = 3; | |
386 } else { | |
387 config.default_repeat = 2; | |
388 } | |
389 | |
390 conf_palette = config.src_palette; | |
391 if ( vo_conf_deinterlace ) { | |
392 config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST | SYNCFB_FEATURE_DEINTERLACE; | |
393 config.default_repeat = 1; | |
394 } else { | |
395 config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_BLOCK_REQUEST; | |
396 } | |
397 | |
398 config.fb_screen_size = (RAM_SIZE-4)*0x100000; //(1280 * 1024 * 32) / 8; | |
399 config.src_width = width; | |
400 config.src_height= height; | |
401 | |
402 config.image_width = d_width; | |
403 config.image_height= d_height; | |
404 //config.image_width = 1024; | |
405 //config.image_height= 576; | |
406 | |
407 config.image_xorg= 0; | |
408 config.image_yorg= 0; | |
409 | |
410 | |
411 printf ("BES Sourcer size: %d x %d\n", width, height); | |
412 | |
413 ioctl(f,SYNCFB_ON,0); | |
414 if (ioctl(f,SYNCFB_SET_CONFIG,&config)) perror("Error in mga_vid_config ioctl"); | |
415 | |
416 printf ("Framebuffer memory: %ld in %ld buffers\n", sfb_caps.memory_size, config.buffers); | |
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 |