Mercurial > mplayer.hg
annotate libvo/vo_fbdev.c @ 290:f40a55208b76
Mode detect bugfix.
author | se7encode |
---|---|
date | Thu, 05 Apr 2001 20:42:24 +0000 |
parents | 604b37178b3d |
children | 6c3a6322f81c |
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; | |
278 | 37 static int fb_pixel_size; |
225 | 38 static int fb_bpp; |
229 | 39 struct fb_fix_screeninfo fb_fix_info; |
40 struct fb_var_screeninfo fb_var_info; | |
246 | 41 static uint32_t fb_xres_virtual; |
42 static uint32_t fb_yres_virtual; | |
225 | 43 |
44 static int in_width; | |
45 static int in_height; | |
46 static int out_width; | |
47 static int out_height; | |
48 static uint8_t *next_frame; | |
49 static int screen_width; | |
50 static uint32_t pixel_format; | |
51 | |
229 | 52 static int fb_init_done = 0; |
225 | 53 |
229 | 54 static int fb_init(void) |
225 | 55 { |
277 | 56 int fd; |
57 #if 0 | |
58 int vt; | |
225 | 59 char vt_name[11]; |
60 struct vt_stat vt_state; | |
61 struct vt_mode vt_mode; | |
62 | |
63 /* get a free vt */ | |
64 if ((fd = open("/dev/tty0", O_WRONLY, 0)) == -1) { | |
65 printf("Can't open /dev/tty0: %s\n", strerror(errno)); | |
66 return 1; | |
67 } | |
68 if (ioctl(fd, VT_OPENQRY, &vt) < 0 || vt == -1) { | |
69 printf("Can't open a free VT: %s\n", strerror(errno)); | |
70 return 1; | |
71 } | |
72 close(fd); | |
277 | 73 |
225 | 74 /* open the vt */ |
75 snprintf(vt_name, 10, "/dev/tty%d", vt); | |
76 if ((vt_fd = open(vt_name, O_RDWR | O_NONBLOCK, 0)) == -1) { | |
77 printf("Can't open %s: %s\n", vt_name, strerror(errno)); | |
78 return 1; | |
79 } | |
80 | |
81 /* save the current vtnum */ | |
82 if (!ioctl(vt_fd, VT_GETSTATE, &vt_state)) | |
83 vt_active = vt_state.v_active; | |
84 | |
85 /* detach the controlling tty */ | |
86 if ((fd = open("/dev/tty", O_RDWR)) >= 0) { | |
87 ioctl(fd, TIOCNOTTY, 0); | |
88 close(fd); | |
89 } | |
277 | 90 |
225 | 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 |
278 | 166 fb_pixel_size = fb_var_info.bits_per_pixel / 8; |
167 fb_bpp = fb_var_info.red.length + fb_var_info.green.length + | |
168 fb_var_info.blue.length; | |
229 | 169 screen_width = fb_fix_info.line_length; |
170 fb_size = fb_fix_info.smem_len; | |
225 | 171 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, |
172 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { | |
229 | 173 printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); |
225 | 174 return 1; |
175 } | |
229 | 176 |
177 printf("fb_init: framebuffer @ %p\n", frame_buffer); | |
178 printf("fb_init: framebuffer size: %d bytes\n", fb_size); | |
179 printf("fb_init: bpp: %d\n", fb_bpp); | |
278 | 180 printf("fb_init: pixel size: %d\n", fb_pixel_size); |
181 printf("fb_init: pixel per line: %d\n", screen_width / fb_pixel_size); | |
229 | 182 printf("fb_init: visual: %d\n", fb_fix_info.visual); |
277 | 183 printf("fb_init: red: %d %d %d\n", fb_var_info.red.offset, |
184 fb_var_info.red.length, fb_var_info.red.msb_right); | |
185 printf("fb_init: green: %d %d %d\n", fb_var_info.green.offset, | |
186 fb_var_info.green.length, fb_var_info.green.msb_right); | |
187 printf("fb_init: blue: %d %d %d\n", fb_var_info.blue.offset, | |
188 fb_var_info.blue.length, fb_var_info.blue.msb_right); | |
225 | 189 |
229 | 190 fb_init_done = 1; |
191 return 0; | |
192 } | |
193 | |
194 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | |
195 uint32_t d_height, uint32_t fullscreen, char *title, | |
196 uint32_t format) | |
197 { | |
198 if (!fb_init_done) | |
199 if (fb_init()) | |
200 return 1; | |
225 | 201 |
202 in_width = width; | |
203 in_height = height; | |
204 out_width = width; | |
205 out_height = height; | |
206 pixel_format = format; | |
278 | 207 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) { |
225 | 208 printf("Can't malloc next_frame: %s\n", strerror(errno)); |
209 return 1; | |
210 } | |
211 | |
212 if (format == IMGFMT_YV12) | |
278 | 213 // yuv2rgb_init(fb_pixel_size * 8, MODE_RGB); |
214 yuv2rgb_init((fb_pixel_size == 4) ? 32 : fb_bpp, MODE_RGB); | |
225 | 215 return 0; |
216 } | |
217 | |
218 static uint32_t query_format(uint32_t format) | |
219 { | |
229 | 220 if (!fb_init_done) |
221 if (fb_init()) | |
222 return 0; | |
278 | 223 printf("vo_fbdev: query_format(%#x(%.4s)): ", format, &format); |
230 | 224 // if (format & IMGFMT_BGR_MASK == IMGFMT_BGR) |
225 // goto not_supported; | |
225 | 226 switch (format) { |
227 case IMGFMT_YV12: | |
229 | 228 goto supported; |
277 | 229 /* |
225 | 230 case IMGFMT_RGB32: |
231 if (fb_bpp == 32) | |
229 | 232 goto supported; |
225 | 233 break; |
234 case IMGFMT_RGB24: | |
235 if (fb_bpp == 24) | |
229 | 236 goto supported; |
225 | 237 break; |
238 case IMGFMT_RGB16: | |
239 if (fb_bpp == 16) | |
229 | 240 goto supported; |
225 | 241 break; |
242 case IMGFMT_RGB15: | |
243 if (fb_bpp == 15) | |
229 | 244 goto supported; |
245 break; | |
277 | 246 */ |
229 | 247 case IMGFMT_BGR|32: |
278 | 248 if (fb_bpp == 24 && fb_pixel_size == 4) |
229 | 249 goto supported; |
250 break; | |
251 case IMGFMT_BGR|24: | |
278 | 252 if (fb_bpp == 24 && fb_pixel_size == 3) |
229 | 253 goto supported; |
254 break; | |
255 case IMGFMT_BGR|16: | |
256 if (fb_bpp == 16) | |
257 goto supported; | |
258 break; | |
259 case IMGFMT_BGR|15: | |
260 if (fb_bpp == 15) | |
261 goto supported; | |
225 | 262 break; |
263 } | |
229 | 264 not_supported: |
265 printf("not_supported\n"); | |
225 | 266 return 0; |
229 | 267 supported: |
268 printf("supported\n"); | |
269 return 1; | |
225 | 270 } |
271 | |
272 static const vo_info_t *get_info(void) | |
273 { | |
274 return &vo_info; | |
275 } | |
276 | |
277 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, | |
278 unsigned char *srca, int stride) | |
279 { | |
280 int x, y; | |
281 uint8_t *dst; | |
282 | |
283 if (pixel_format == IMGFMT_YV12) { | |
284 for (y = 0; y < h; y++){ | |
278 | 285 dst = next_frame + (in_width * (y0 + y) + x0) * fb_pixel_size; |
225 | 286 for (x = 0; x < w; x++) { |
287 if (srca[x]) { | |
251 | 288 dst[0]=((dst[0]*srca[x])>>8)+src[x]; |
289 dst[1]=((dst[1]*srca[x])>>8)+src[x]; | |
290 dst[2]=((dst[2]*srca[x])>>8)+src[x]; | |
225 | 291 } |
278 | 292 dst += fb_pixel_size; |
225 | 293 } |
294 src += stride; | |
295 srca += stride; | |
296 } | |
297 } | |
298 } | |
299 | |
300 static uint32_t draw_frame(uint8_t *src[]) | |
301 { | |
302 if (pixel_format == IMGFMT_YV12) { | |
303 yuv2rgb(next_frame, src[0], src[1], src[2], in_width, | |
278 | 304 in_height, in_width * fb_pixel_size, |
225 | 305 in_width, in_width / 2); |
230 | 306 } else if ((pixel_format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { |
278 | 307 memcpy(next_frame, src[0], in_width * in_height * fb_pixel_size); |
230 | 308 } else if ((pixel_format & IMGFMT_RGB_MASK) == IMGFMT_RGB) { |
225 | 309 } |
310 return 0; | |
311 } | |
312 | |
313 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, | |
314 int y) | |
315 { | |
316 uint8_t *dest; | |
317 | |
278 | 318 dest = next_frame + (in_width * y + x) * fb_pixel_size; |
319 yuv2rgb(dest, src[0], src[1], src[2], w, h, in_width * fb_pixel_size, | |
225 | 320 stride[0], stride[1]); |
321 return 0; | |
322 } | |
323 | |
324 static void check_events(void) | |
325 { | |
326 } | |
327 | |
246 | 328 static void put_frame(void) |
225 | 329 { |
330 int i, out_offset = 0, in_offset = 0; | |
331 | |
332 for (i = 0; i < in_height; i++) { | |
333 memcpy(frame_buffer + out_offset, next_frame + in_offset, | |
278 | 334 in_width * fb_pixel_size); |
225 | 335 out_offset += screen_width; |
278 | 336 in_offset += in_width * fb_pixel_size; |
225 | 337 } |
338 } | |
339 | |
246 | 340 static void flip_page(void) |
341 { | |
342 vo_draw_text(in_width, in_height, draw_alpha); | |
343 check_events(); | |
344 put_frame(); | |
345 } | |
346 | |
225 | 347 static void uninit(void) |
348 { | |
246 | 349 printf("vo_fbdev: uninit\n"); |
350 fb_var_info.xres_virtual = fb_xres_virtual; | |
351 fb_var_info.yres_virtual = fb_yres_virtual; | |
352 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) | |
353 printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno)); | |
251 | 354 close(fb_dev_fd); |
278 | 355 memset(next_frame, '\0', in_height * in_width * fb_pixel_size); |
246 | 356 put_frame(); |
225 | 357 if (vt_active >= 0) |
358 ioctl(vt_fd, VT_ACTIVATE, vt_active); | |
359 free(next_frame); | |
360 munmap(frame_buffer, fb_size); | |
361 } |