Mercurial > mplayer.hg
annotate libvo/vo_fbdev.c @ 264:39afcd42f63e
added vo_dga to VidMode author
author | gabucino |
---|---|
date | Sat, 31 Mar 2001 12:58:29 +0000 |
parents | ea2dcb082185 |
children | 8d526cf59ffe |
rev | line source |
---|---|
225 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <fcntl.h> | |
5 #include <unistd.h> | |
6 #include <errno.h> | |
7 | |
8 #include <sys/mman.h> | |
9 #include <sys/ioctl.h> | |
10 #include <linux/fb.h> | |
11 #include <linux/vt.h> | |
12 | |
13 #include "config.h" | |
14 #include "video_out.h" | |
15 #include "video_out_internal.h" | |
16 | |
17 #include "yuv2rgb.h" | |
18 | |
19 LIBVO_EXTERN(fbdev) | |
20 | |
21 //#include "yuv2rgb.h" | |
22 | |
23 static vo_info_t vo_info = { | |
24 "Framebuffer Device", | |
25 "fbdev", | |
26 "Szabolcs Berecz <szabi@inf.elte.hu>", | |
27 "" | |
28 }; | |
29 | |
230 | 30 static int vt_active = -1; |
225 | 31 static int vt_fd; |
32 | |
33 char *fb_dev_name = NULL; | |
34 static int fb_dev_fd; | |
35 static size_t fb_size; | |
36 static uint8_t *frame_buffer; | |
37 static int fb_bpp; | |
229 | 38 struct fb_fix_screeninfo fb_fix_info; |
39 struct fb_var_screeninfo fb_var_info; | |
246 | 40 static uint32_t fb_xres_virtual; |
41 static uint32_t fb_yres_virtual; | |
225 | 42 |
43 static int in_width; | |
44 static int in_height; | |
45 static int out_width; | |
46 static int out_height; | |
47 static uint8_t *next_frame; | |
48 static int screen_width; | |
49 static uint32_t pixel_format; | |
50 | |
229 | 51 static int fb_init_done = 0; |
225 | 52 |
229 | 53 static int fb_init(void) |
225 | 54 { |
55 int fd, vt; | |
56 char vt_name[11]; | |
57 struct vt_stat vt_state; | |
58 struct vt_mode vt_mode; | |
59 | |
229 | 60 #if 0 |
225 | 61 /* get a free vt */ |
62 if ((fd = open("/dev/tty0", O_WRONLY, 0)) == -1) { | |
63 printf("Can't open /dev/tty0: %s\n", strerror(errno)); | |
64 return 1; | |
65 } | |
66 if (ioctl(fd, VT_OPENQRY, &vt) < 0 || vt == -1) { | |
67 printf("Can't open a free VT: %s\n", strerror(errno)); | |
68 return 1; | |
69 } | |
70 close(fd); | |
229 | 71 #endif |
72 #if 0 | |
225 | 73 /* open the vt */ |
74 snprintf(vt_name, 10, "/dev/tty%d", vt); | |
75 if ((vt_fd = open(vt_name, O_RDWR | O_NONBLOCK, 0)) == -1) { | |
76 printf("Can't open %s: %s\n", vt_name, strerror(errno)); | |
77 return 1; | |
78 } | |
79 | |
80 /* save the current vtnum */ | |
81 if (!ioctl(vt_fd, VT_GETSTATE, &vt_state)) | |
82 vt_active = vt_state.v_active; | |
83 | |
84 /* detach the controlling tty */ | |
85 if ((fd = open("/dev/tty", O_RDWR)) >= 0) { | |
86 ioctl(fd, TIOCNOTTY, 0); | |
87 close(fd); | |
88 } | |
229 | 89 #endif |
225 | 90 #if 0 |
91 /* switch to the new vt */ | |
92 if (ioctl(vt_fd, VT_ACTIVATE, vt_active)) | |
93 printf("ioctl VT_ACTIVATE: %s\n", strerror(errno)); | |
94 if (ioctl(vt_fd, VT_WAITACTIVE, vt_active)) | |
95 printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno)); | |
96 if (ioctl(vt_fd, VT_GETMODE, &vt_mode) < 0) { | |
97 printf("ioctl VT_GETMODE: %s\n", strerror(errno)); | |
98 return 1; | |
99 } | |
100 signal(SIGUSR1, vt_request); | |
101 vt_mode.mode = VT_PROCESS; | |
102 vt_mode.relsig = SIGUSR1; | |
103 vt_mode.acqsig = SIGUSR1; | |
104 if (ioctl(vt_fd, VT_SETMODE, &vt_mode) < 0) { | |
105 printf("ioctl VT_SETMODE: %s\n", strerror(errno)); | |
106 return 1; | |
107 } | |
108 #endif | |
109 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) | |
110 fb_dev_name = "/dev/fb0"; | |
229 | 111 printf("fb_init: using %s\n", fb_dev_name); |
245
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
112 |
225 | 113 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { |
229 | 114 printf("fb_init: Can't open %s: %s\n", fb_dev_name, strerror(errno)); |
225 | 115 return 1; |
116 } | |
245
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
117 |
229 | 118 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_var_info)) { |
119 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); | |
225 | 120 return 1; |
121 } | |
245
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
122 |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
123 /* disable scrolling */ |
246 | 124 fb_xres_virtual = fb_var_info.xres_virtual; |
125 fb_yres_virtual = fb_var_info.yres_virtual; | |
245
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
126 fb_var_info.xres_virtual = fb_var_info.xres; |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
127 fb_var_info.yres_virtual = fb_var_info.yres; |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
128 |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
129 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) { |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
130 printf("fb_init: Can't put VSCREENINFO: %s\n", strerror(errno)); |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
131 return 1; |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
132 } |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
133 |
229 | 134 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_fix_info)) { |
135 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); | |
225 | 136 return 1; |
137 } | |
229 | 138 switch (fb_fix_info.type) { |
225 | 139 case FB_TYPE_VGA_PLANES: |
229 | 140 printf("fb_init: FB_TYPE_VGA_PLANES not supported.\n"); |
225 | 141 return 1; |
142 break; | |
143 case FB_TYPE_PLANES: | |
229 | 144 printf("fb_init: FB_TYPE_PLANES not supported.\n"); |
225 | 145 return 1; |
146 break; | |
147 case FB_TYPE_INTERLEAVED_PLANES: | |
229 | 148 printf("fb_init: FB_TYPE_INTERLEAVED_PLANES not supported.\n"); |
225 | 149 return 1; |
150 break; | |
151 #ifdef FB_TYPE_TEXT | |
152 case FB_TYPE_TEXT: | |
229 | 153 printf("fb_init: FB_TYPE_TEXT not supported.\n"); |
225 | 154 return 1; |
155 break; | |
156 #endif | |
157 case FB_TYPE_PACKED_PIXELS: | |
158 /* OK */ | |
229 | 159 printf("fb_init: FB_TYPE_PACKED_PIXELS: OK\n"); |
225 | 160 break; |
161 default: | |
229 | 162 printf("fb_init: unknown FB_TYPE: %d\n", fb_fix_info.type); |
225 | 163 return 1; |
245
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
164 } |
cb4c682746c0
disabled scrollback buffer (virtual fb size set to real screen size)
szabii
parents:
231
diff
changeset
|
165 |
229 | 166 fb_bpp = fb_var_info.bits_per_pixel; |
167 screen_width = fb_fix_info.line_length; | |
168 fb_size = fb_fix_info.smem_len; | |
225 | 169 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, |
170 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { | |
229 | 171 printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); |
225 | 172 return 1; |
173 } | |
229 | 174 |
175 printf("fb_init: framebuffer @ %p\n", frame_buffer); | |
176 printf("fb_init: framebuffer size: %d bytes\n", fb_size); | |
177 printf("fb_init: bpp: %d\n", fb_bpp); | |
178 printf("fb_init: pixel per line: %d\n", screen_width / (fb_bpp / 8)); | |
179 printf("fb_init: visual: %d\n", fb_fix_info.visual); | |
225 | 180 |
229 | 181 fb_init_done = 1; |
182 return 0; | |
183 } | |
184 | |
185 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | |
186 uint32_t d_height, uint32_t fullscreen, char *title, | |
187 uint32_t format) | |
188 { | |
189 if (!fb_init_done) | |
190 if (fb_init()) | |
191 return 1; | |
225 | 192 |
193 in_width = width; | |
194 in_height = height; | |
195 out_width = width; | |
196 out_height = height; | |
197 pixel_format = format; | |
198 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * (fb_bpp / 8)))) { | |
199 printf("Can't malloc next_frame: %s\n", strerror(errno)); | |
200 return 1; | |
201 } | |
202 | |
203 if (format == IMGFMT_YV12) | |
204 yuv2rgb_init(fb_bpp, MODE_RGB); | |
205 return 0; | |
206 } | |
207 | |
208 static uint32_t query_format(uint32_t format) | |
209 { | |
229 | 210 if (!fb_init_done) |
211 if (fb_init()) | |
212 return 0; | |
213 printf("vo_fbdev: query_format(%#x): ", format); | |
230 | 214 // if (format & IMGFMT_BGR_MASK == IMGFMT_BGR) |
215 // goto not_supported; | |
225 | 216 switch (format) { |
217 case IMGFMT_YV12: | |
229 | 218 goto supported; |
225 | 219 case IMGFMT_RGB32: |
220 if (fb_bpp == 32) | |
229 | 221 goto supported; |
225 | 222 break; |
223 case IMGFMT_RGB24: | |
224 if (fb_bpp == 24) | |
229 | 225 goto supported; |
225 | 226 break; |
227 case IMGFMT_RGB16: | |
228 if (fb_bpp == 16) | |
229 | 229 goto supported; |
225 | 230 break; |
231 case IMGFMT_RGB15: | |
232 if (fb_bpp == 15) | |
229 | 233 goto supported; |
234 break; | |
235 case IMGFMT_BGR|32: | |
236 if (fb_bpp == 32) | |
237 goto supported; | |
238 break; | |
239 case IMGFMT_BGR|24: | |
240 if (fb_bpp == 24) | |
241 goto supported; | |
242 break; | |
243 case IMGFMT_BGR|16: | |
244 if (fb_bpp == 16) | |
245 goto supported; | |
246 break; | |
247 case IMGFMT_BGR|15: | |
248 if (fb_bpp == 15) | |
249 goto supported; | |
225 | 250 break; |
251 } | |
229 | 252 not_supported: |
253 printf("not_supported\n"); | |
225 | 254 return 0; |
229 | 255 supported: |
256 printf("supported\n"); | |
257 return 1; | |
225 | 258 } |
259 | |
260 static const vo_info_t *get_info(void) | |
261 { | |
262 return &vo_info; | |
263 } | |
264 | |
265 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
266 unsigned char *srca, int stride) | |
267 { | |
268 int x, y; | |
269 uint8_t *dst; | |
270 | |
271 if (pixel_format == IMGFMT_YV12) { | |
272 for (y = 0; y < h; y++){ | |
273 dst = next_frame + (in_width * (y0 + y) + x0) * (fb_bpp / 8); | |
274 for (x = 0; x < w; x++) { | |
275 if (srca[x]) { | |
251 | 276 dst[0]=((dst[0]*srca[x])>>8)+src[x]; |
277 dst[1]=((dst[1]*srca[x])>>8)+src[x]; | |
278 dst[2]=((dst[2]*srca[x])>>8)+src[x]; | |
225 | 279 } |
280 dst += fb_bpp / 8; | |
281 } | |
282 src += stride; | |
283 srca += stride; | |
284 } | |
285 } | |
286 } | |
287 | |
288 static uint32_t draw_frame(uint8_t *src[]) | |
289 { | |
290 if (pixel_format == IMGFMT_YV12) { | |
291 yuv2rgb(next_frame, src[0], src[1], src[2], in_width, | |
292 in_height, in_width * (fb_bpp / 8), | |
293 in_width, in_width / 2); | |
230 | 294 } else if ((pixel_format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { |
231 | 295 memcpy(next_frame, src[0], in_width * in_height * (fb_bpp / 8)); |
230 | 296 } else if ((pixel_format & IMGFMT_RGB_MASK) == IMGFMT_RGB) { |
225 | 297 } |
298 return 0; | |
299 } | |
300 | |
301 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, | |
302 int y) | |
303 { | |
304 uint8_t *dest; | |
305 | |
306 dest = next_frame + (in_width * y + x) * (fb_bpp / 8); | |
307 yuv2rgb(dest, src[0], src[1], src[2], w, h, in_width * (fb_bpp / 8), | |
308 stride[0], stride[1]); | |
309 return 0; | |
310 } | |
311 | |
312 static void check_events(void) | |
313 { | |
314 } | |
315 | |
246 | 316 static void put_frame(void) |
225 | 317 { |
318 int i, out_offset = 0, in_offset = 0; | |
319 | |
320 for (i = 0; i < in_height; i++) { | |
321 memcpy(frame_buffer + out_offset, next_frame + in_offset, | |
322 in_width * (fb_bpp / 8)); | |
323 out_offset += screen_width; | |
324 in_offset += in_width * (fb_bpp / 8); | |
325 } | |
326 } | |
327 | |
246 | 328 static void flip_page(void) |
329 { | |
330 vo_draw_text(in_width, in_height, draw_alpha); | |
331 check_events(); | |
332 put_frame(); | |
333 } | |
334 | |
225 | 335 static void uninit(void) |
336 { | |
246 | 337 printf("vo_fbdev: uninit\n"); |
338 fb_var_info.xres_virtual = fb_xres_virtual; | |
339 fb_var_info.yres_virtual = fb_yres_virtual; | |
340 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) | |
341 printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno)); | |
251 | 342 close(fb_dev_fd); |
246 | 343 memset(next_frame, '\0', in_height * in_width * (fb_bpp / 8)); |
344 put_frame(); | |
225 | 345 if (vt_active >= 0) |
346 ioctl(vt_fd, VT_ACTIVATE, vt_active); | |
347 free(next_frame); | |
348 munmap(frame_buffer, fb_size); | |
349 } |