comparison libvo/vo_fbdev.c @ 10576:e4cdc9ca94c5

Changed all printf into mp_msg Removed extern int verbose Removed some unneeded includes Removed swscale, because this should be done by vf layer instead Removed weird video_out_png definition There is no more flip, zoom, or geometry support, so I removed those. Slices, stride support for all supported CSP. Replaced draw_frame with a stub. Removed: do { ... } while (0) Removed unused dstFourcc. Added DR support Removed USE_CONVERT2FB, since we have real DR now Simplified some color depth checks
author joey
date Tue, 12 Aug 2003 06:57:19 +0000
parents c3345a8fbc57
children b9d289fd8a57
comparison
equal deleted inserted replaced
10575:148f029ff426 10576:e4cdc9ca94c5
2 * Video driver for Framebuffer device 2 * Video driver for Framebuffer device
3 * by Szabolcs Berecz <szabi@inf.elte.hu> 3 * by Szabolcs Berecz <szabi@inf.elte.hu>
4 * (C) 2001 4 * (C) 2001
5 * 5 *
6 * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27 6 * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27
7 * Some fixes and small improvements by Joey Parrish <joey@nicewarrior.org>
7 */ 8 */
8
9 #define FBDEV "fbdev: "
10 9
11 #include <stdio.h> 10 #include <stdio.h>
12 #include <stdlib.h> 11 #include <stdlib.h>
13 #include <string.h> 12 #include <string.h>
14 #include <fcntl.h> 13 #include <fcntl.h>
15 #include <unistd.h> 14 #include <unistd.h>
16 #include <errno.h> 15 #include <errno.h>
17 #include <ctype.h>
18 #include <assert.h>
19 16
20 #include <sys/mman.h> 17 #include <sys/mman.h>
21 #include <sys/ioctl.h> 18 #include <sys/ioctl.h>
22 #include <sys/kd.h> 19 #include <sys/kd.h>
23 #include <linux/fb.h> 20 #include <linux/fb.h>
25 #include "config.h" 22 #include "config.h"
26 #include "video_out.h" 23 #include "video_out.h"
27 #include "video_out_internal.h" 24 #include "video_out_internal.h"
28 #include "fastmemcpy.h" 25 #include "fastmemcpy.h"
29 #include "sub.h" 26 #include "sub.h"
30 #include "../postproc/rgb2rgb.h"
31 #include "../libmpcodecs/vf_scale.h"
32 #ifdef CONFIG_VIDIX 27 #ifdef CONFIG_VIDIX
33 #include "vosub_vidix.h" 28 #include "vosub_vidix.h"
34 #endif 29 #endif
35 #include "aspect.h" 30 #include "aspect.h"
36 31 #include "mp_msg.h"
37 #ifdef HAVE_PNG
38 extern vo_functions_t video_out_png;
39 #endif
40 32
41 static vo_info_t info = { 33 static vo_info_t info = {
42 "Framebuffer Device", 34 "Framebuffer Device",
43 "fbdev", 35 "fbdev",
44 "Szabolcs Berecz <szabi@inf.elte.hu>", 36 "Szabolcs Berecz <szabi@inf.elte.hu>",
45 "" 37 ""
46 }; 38 };
47 39
48 LIBVO_EXTERN(fbdev) 40 LIBVO_EXTERN(fbdev)
49
50 extern int verbose;
51 41
52 #ifdef CONFIG_VIDIX 42 #ifdef CONFIG_VIDIX
53 /* Name of VIDIX driver */ 43 /* Name of VIDIX driver */
54 static const char *vidix_name = NULL; 44 static const char *vidix_name = NULL;
55 #endif 45 #endif
72 uint32_t pixclock, left, right, upper, lower, hslen, vslen; 62 uint32_t pixclock, left, right, upper, lower, hslen, vslen;
73 uint32_t sync; 63 uint32_t sync;
74 uint32_t vmode; 64 uint32_t vmode;
75 } fb_mode_t; 65 } fb_mode_t;
76 66
77 #define PRINT_LINENUM printf(" at line %d\n", line_num)
78
79 #define MAX_NR_TOKEN 16 67 #define MAX_NR_TOKEN 16
80 68
81 #define MAX_LINE_LEN 1000 69 #define MAX_LINE_LEN 1000
82 70
83 #define RET_EOF -1 71 #define RET_EOF -1
84 #define RET_EOL -2 72 #define RET_EOL -2
85 73
86 static int validate_mode(fb_mode_t *m) 74 static int validate_mode(fb_mode_t *m)
87 { 75 {
88 if (!m->xres) { 76 if (!m->xres) {
89 printf("needs geometry "); 77 mp_msg(MSGT_VO, MSGL_V, "needs geometry ");
90 return 0; 78 return 0;
91 } 79 }
92 if (!m->pixclock) { 80 if (!m->pixclock) {
93 printf("needs timings "); 81 mp_msg(MSGT_VO, MSGL_V, "needs timings ");
94 return 0; 82 return 0;
95 } 83 }
96 return 1; 84 return 1;
97 } 85 }
98 86
99 static FILE *fp; 87 static FILE *fp;
100 static int line_num = 0; 88 static int line_num = 0;
101 static char *line; 89 static char *line;
102 static char *token[MAX_NR_TOKEN]; 90 static char *token[MAX_NR_TOKEN];
103 static uint32_t dstFourcc;
104 91
105 static int get_token(int num) 92 static int get_token(int num)
106 { 93 {
107 static int read_nextline = 1; 94 static int read_nextline = 1;
108 static int line_pos; 95 static int line_pos;
109 int i; 96 int i;
110 char c; 97 char c;
111 98
112 if (num >= MAX_NR_TOKEN) { 99 if (num >= MAX_NR_TOKEN) {
113 printf("get_token(): max >= MAX_NR_TOKEN!"); 100 mp_msg(MSGT_VO, MSGL_V, "get_token(): max >= MAX_NR_TOKEN!\n");
114 goto out_eof; 101 goto out_eof;
115 } 102 }
116 103
117 if (read_nextline) { 104 if (read_nextline) {
118 if (!fgets(line, MAX_LINE_LEN, fp)) 105 if (!fgets(line, MAX_LINE_LEN, fp))
162 static int nr_modes = 0; 149 static int nr_modes = 0;
163 150
164 static int parse_fbmode_cfg(char *cfgfile) 151 static int parse_fbmode_cfg(char *cfgfile)
165 { 152 {
166 #define CHECK_IN_MODE_DEF\ 153 #define CHECK_IN_MODE_DEF\
167 do {\
168 if (!in_mode_def) {\ 154 if (!in_mode_def) {\
169 printf("'needs 'mode' first");\ 155 mp_msg(MSGT_VO, MSGL_V, "'needs 'mode' first");\
170 goto err_out_print_linenum;\ 156 goto err_out_print_linenum;\
171 }\ 157 }
172 } while (0)
173
174 fb_mode_t *mode = NULL; 158 fb_mode_t *mode = NULL;
175 char *endptr; // strtoul()... 159 char *endptr; // strtoul()...
176 int in_mode_def = 0; 160 int in_mode_def = 0;
177 int tmp, i; 161 int tmp, i;
178 162
179 if (verbose > 0) 163 mp_msg(MSGT_VO, MSGL_V, "Reading %s: ", cfgfile);
180 printf("Reading %s: ", cfgfile);
181 164
182 if ((fp = fopen(cfgfile, "r")) == NULL) { 165 if ((fp = fopen(cfgfile, "r")) == NULL) {
183 printf("can't open '%s': %s\n", cfgfile, strerror(errno)); 166 mp_msg(MSGT_VO, MSGL_V, "can't open '%s': %s\n", cfgfile, strerror(errno));
184 return -1; 167 return -1;
185 } 168 }
186 169
187 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) { 170 if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) {
188 printf("can't get memory for 'line': %s\n", strerror(errno)); 171 mp_msg(MSGT_VO, MSGL_V, "can't get memory for 'line': %s\n", strerror(errno));
189 return -2; 172 return -2;
190 } 173 }
191 174
192 /* 175 /*
193 * check if the cfgfile starts with 'mode' 176 * check if the cfgfile starts with 'mode'
203 while ((tmp = get_token(1)) != RET_EOF) { 186 while ((tmp = get_token(1)) != RET_EOF) {
204 if (tmp == RET_EOL) 187 if (tmp == RET_EOL)
205 continue; 188 continue;
206 if (!strcmp(token[0], "mode")) { 189 if (!strcmp(token[0], "mode")) {
207 if (in_mode_def) { 190 if (in_mode_def) {
208 printf("'endmode' required"); 191 mp_msg(MSGT_VO, MSGL_V, "'endmode' required");
209 goto err_out_print_linenum; 192 goto err_out_print_linenum;
210 } 193 }
211 if (!validate_mode(mode)) 194 if (!validate_mode(mode))
212 goto err_out_not_valid; 195 goto err_out_not_valid;
213 loop_enter: 196 loop_enter:
214 if (!(fb_modes = (fb_mode_t *) realloc(fb_modes, 197 if (!(fb_modes = (fb_mode_t *) realloc(fb_modes,
215 sizeof(fb_mode_t) * (nr_modes + 1)))) { 198 sizeof(fb_mode_t) * (nr_modes + 1)))) {
216 printf("can't realloc 'fb_modes' (nr_modes = %d):" 199 mp_msg(MSGT_VO, MSGL_V, "can't realloc 'fb_modes' (nr_modes = %d):"
217 " %s\n", nr_modes, strerror(errno)); 200 " %s\n", nr_modes, strerror(errno));
218 goto err_out; 201 goto err_out;
219 } 202 }
220 mode=fb_modes + nr_modes; 203 mode=fb_modes + nr_modes;
221 ++nr_modes; 204 ++nr_modes;
223 206
224 if (get_token(1) < 0) 207 if (get_token(1) < 0)
225 goto err_out_parse_error; 208 goto err_out_parse_error;
226 for (i = 0; i < nr_modes - 1; i++) { 209 for (i = 0; i < nr_modes - 1; i++) {
227 if (!strcmp(token[0], fb_modes[i].name)) { 210 if (!strcmp(token[0], fb_modes[i].name)) {
228 printf("mode name '%s' isn't unique", token[0]); 211 mp_msg(MSGT_VO, MSGL_V, "mode name '%s' isn't unique", token[0]);
229 goto err_out_print_linenum; 212 goto err_out_print_linenum;
230 } 213 }
231 } 214 }
232 if (!(mode->name = strdup(token[0]))) { 215 if (!(mode->name = strdup(token[0]))) {
233 printf("can't strdup -> 'name': %s\n", strerror(errno)); 216 mp_msg(MSGT_VO, MSGL_V, "can't strdup -> 'name': %s\n", strerror(errno));
234 goto err_out; 217 goto err_out;
235 } 218 }
236 in_mode_def = 1; 219 in_mode_def = 1;
237 } else if (!strcmp(token[0], "geometry")) { 220 } else if (!strcmp(token[0], "geometry")) {
238 CHECK_IN_MODE_DEF; 221 CHECK_IN_MODE_DEF;
353 goto err_out_parse_error; 336 goto err_out_parse_error;
354 } 337 }
355 if (!validate_mode(mode)) 338 if (!validate_mode(mode))
356 goto err_out_not_valid; 339 goto err_out_not_valid;
357 out: 340 out:
358 if (verbose > 0) 341 mp_msg(MSGT_VO, MSGL_V, "%d modes\n", nr_modes);
359 printf("%d modes\n", nr_modes);
360 free(line); 342 free(line);
361 fclose(fp); 343 fclose(fp);
362 return nr_modes; 344 return nr_modes;
363 err_out_parse_error: 345 err_out_parse_error:
364 printf("parse error"); 346 mp_msg(MSGT_VO, MSGL_V, "parse error");
365 err_out_print_linenum: 347 err_out_print_linenum:
366 PRINT_LINENUM; 348 mp_msg(MSGT_VO, MSGL_V, " at line %d\n", line_num);
367 err_out: 349 err_out:
368 if (fb_modes) { 350 if (fb_modes) {
369 free(fb_modes); 351 free(fb_modes);
370 fb_modes = NULL; 352 fb_modes = NULL;
371 } 353 }
372 nr_modes = 0; 354 nr_modes = 0;
373 free(line); 355 free(line);
374 free(fp); 356 free(fp);
375 return -2; 357 return -2;
376 err_out_not_valid: 358 err_out_not_valid:
377 printf("previous mode is not correct"); 359 mp_msg(MSGT_VO, MSGL_V, "previous mode is not correct");
378 goto err_out_print_linenum; 360 goto err_out_print_linenum;
379 } 361 }
380 362
381 static fb_mode_t *find_mode_by_name(char *name) 363 static fb_mode_t *find_mode_by_name(char *name)
382 { 364 {
412 float h = hsf(m); 394 float h = hsf(m);
413 float v = vsf(m); 395 float v = vsf(m);
414 float d = dcf(m); 396 float d = dcf(m);
415 int ret = 1; 397 int ret = 1;
416 398
417 if (verbose > 1) 399 mp_msg(MSGT_VO, MSGL_DBG2, "mode %dx%d:", m->xres, m->yres);
418 printf(FBDEV "mode %dx%d:", m->xres, m->yres);
419 if (!in_range(hfreq, h)) { 400 if (!in_range(hfreq, h)) {
420 ret = 0; 401 ret = 0;
421 if (verbose > 1) 402 mp_msg(MSGT_VO, MSGL_DBG2, " hsync out of range.");
422 printf(" hsync out of range.");
423 } 403 }
424 if (!in_range(vfreq, v)) { 404 if (!in_range(vfreq, v)) {
425 ret = 0; 405 ret = 0;
426 if (verbose > 1) 406 mp_msg(MSGT_VO, MSGL_DBG2, " vsync out of range.");
427 printf(" vsync out of range.");
428 } 407 }
429 if (!in_range(dotclock, d)) { 408 if (!in_range(dotclock, d)) {
430 ret = 0; 409 ret = 0;
431 if (verbose > 1) 410 mp_msg(MSGT_VO, MSGL_DBG2, " dotclock out of range.");
432 printf(" dotclock out of range."); 411 }
433 } 412 if (ret)
434 if (verbose > 1) { 413 mp_msg(MSGT_VO, MSGL_DBG2, " hsync, vsync, dotclock ok.\n");
435 if (ret) 414 else
436 printf(" hsync, vsync, dotclock ok.\n"); 415 mp_msg(MSGT_VO, MSGL_DBG2, "\n");
437 else
438 printf("\n");
439 }
440 416
441 return ret; 417 return ret;
442 } 418 }
443 419
444 static fb_mode_t *find_best_mode(int xres, int yres, range_t *hfreq, 420 static fb_mode_t *find_best_mode(int xres, int yres, range_t *hfreq,
446 { 422 {
447 int i; 423 int i;
448 fb_mode_t *best = fb_modes; 424 fb_mode_t *best = fb_modes;
449 fb_mode_t *curr; 425 fb_mode_t *curr;
450 426
451 if (verbose > 1) 427 mp_msg(MSGT_VO, MSGL_DBG2, "Searching for first working mode\n");
452 printf(FBDEV "Searching for first working mode\n");
453 428
454 for (i = 0; i < nr_modes; i++, best++) 429 for (i = 0; i < nr_modes; i++, best++)
455 if (mode_works(best, hfreq, vfreq, dotclock)) 430 if (mode_works(best, hfreq, vfreq, dotclock))
456 break; 431 break;
457 432
458 if (i == nr_modes) 433 if (i == nr_modes)
459 return NULL; 434 return NULL;
460 if (i == nr_modes - 1) 435 if (i == nr_modes - 1)
461 return best; 436 return best;
462 437
463 if (verbose > 1) { 438 mp_msg(MSGT_VO, MSGL_DBG2, "First working mode: %dx%d\n", best->xres, best->yres);
464 printf(FBDEV "First working mode: %dx%d\n", best->xres, best->yres); 439 mp_msg(MSGT_VO, MSGL_DBG2, "Searching for better modes\n");
465 printf(FBDEV "Searching for better modes\n");
466 }
467 440
468 for (curr = best + 1; i < nr_modes - 1; i++, curr++) { 441 for (curr = best + 1; i < nr_modes - 1; i++, curr++) {
469 if (!mode_works(curr, hfreq, vfreq, dotclock)) 442 if (!mode_works(curr, hfreq, vfreq, dotclock))
470 continue; 443 continue;
471 444
472 if (verbose > 1)
473 printf(FBDEV);
474
475 if (best->xres < xres || best->yres < yres) { 445 if (best->xres < xres || best->yres < yres) {
476 if (curr->xres > best->xres || curr->yres > best->yres) { 446 if (curr->xres > best->xres || curr->yres > best->yres) {
477 if (verbose > 1) 447 mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too small.\n",
478 printf("better than %dx%d, which is too small.\n",
479 best->xres, best->yres); 448 best->xres, best->yres);
480 best = curr; 449 best = curr;
481 } else if (verbose > 1) 450 } else
482 printf("too small.\n"); 451 mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");
483 } else if (curr->xres == best->xres && curr->yres == best->yres && 452 } else if (curr->xres == best->xres && curr->yres == best->yres &&
484 vsf(curr) > vsf(best)) { 453 vsf(curr) > vsf(best)) {
485 if (verbose > 1) 454 mp_msg(MSGT_VO, MSGL_DBG2, "faster screen refresh.\n");
486 printf("faster screen refresh.\n");
487 best = curr; 455 best = curr;
488 } else if ((curr->xres <= best->xres && curr->yres <= best->yres) && 456 } else if ((curr->xres <= best->xres && curr->yres <= best->yres) &&
489 (curr->xres >= xres && curr->yres >= yres)) { 457 (curr->xres >= xres && curr->yres >= yres)) {
490 if (verbose > 1) 458 mp_msg(MSGT_VO, MSGL_DBG2, "better than %dx%d, which is too large.\n",
491 printf("better than %dx%d, which is too large.\n",
492 best->xres, best->yres); 459 best->xres, best->yres);
493 best = curr; 460 best = curr;
494 } else if (verbose > 1) { 461 } else {
495 if (curr->xres < xres || curr->yres < yres) 462 if (curr->xres < xres || curr->yres < yres)
496 printf("too small.\n"); 463 mp_msg(MSGT_VO, MSGL_DBG2, "too small.\n");
497 else if (curr->xres > best->xres || curr->yres > best->yres) 464 else if (curr->xres > best->xres || curr->yres > best->yres)
498 printf("too large.\n"); 465 mp_msg(MSGT_VO, MSGL_DBG2, "too large.\n");
499 else printf("it's worse, don't know why.\n"); 466 else mp_msg(MSGT_VO, MSGL_DBG2, "it's worse, don't know why.\n");
500 } 467 }
501 } 468 }
502 469
503 return best; 470 return best;
504 } 471 }
566 char *fb_mode_name = NULL; 533 char *fb_mode_name = NULL;
567 534
568 static fb_mode_t *fb_mode = NULL; 535 static fb_mode_t *fb_mode = NULL;
569 536
570 /* vt related variables */ 537 /* vt related variables */
571 static int vt_fd; 538 static FILE *vt_fp = NULL;
572 static FILE *vt_fp;
573 static int vt_doit = 1; 539 static int vt_doit = 1;
574 540
575 /* vo_fbdev related variables */ 541 /* vo_fbdev related variables */
576 static int fb_dev_fd; 542 static int fb_dev_fd;
577 static int fb_tty_fd; 543 static int fb_tty_fd = -1;
578 static size_t fb_size; 544 static size_t fb_size;
579 static uint8_t *frame_buffer; 545 static uint8_t *frame_buffer;
580 static uint8_t *center; /* thx .so :) */ 546 static uint8_t *center; /* thx .so :) */
581 static struct fb_fix_screeninfo fb_finfo; 547 static struct fb_fix_screeninfo fb_finfo;
582 static struct fb_var_screeninfo fb_orig_vinfo; 548 static struct fb_var_screeninfo fb_orig_vinfo;
583 static struct fb_var_screeninfo fb_vinfo; 549 static struct fb_var_screeninfo fb_vinfo;
584 static struct fb_cmap fb_oldcmap; 550 static struct fb_cmap fb_oldcmap;
585 static int fb_cmap_changed = 0; 551 static int fb_cmap_changed = 0;
586 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2 552 static int fb_pixel_size; // 32: 4 24: 3 16: 2 15: 2
587 static int fb_real_bpp; // 32: 24 24: 24 16: 16 15: 15
588 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15 553 static int fb_bpp; // 32: 32 24: 24 16: 16 15: 15
589 static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15 554 static int fb_bpp_we_want; // 32: 32 24: 24 16: 16 15: 15
590 static int fb_line_len; 555 static int fb_line_len;
591 static int fb_xres; 556 static int fb_xres;
592 static int fb_yres; 557 static int fb_yres;
601 static int out_height; 566 static int out_height;
602 static int first_row; 567 static int first_row;
603 static int last_row; 568 static int last_row;
604 static uint32_t pixel_format; 569 static uint32_t pixel_format;
605 static int fs; 570 static int fs;
606 static int flip;
607 571
608 /* 572 /*
609 * Note: this function is completely cut'n'pasted from 573 * Note: this function is completely cut'n'pasted from
610 * Chris Lawrence's code. 574 * Chris Lawrence's code.
611 * (modified a bit to fit in my code...) 575 * (modified a bit to fit in my code...)
630 cols = (rcols > gcols ? rcols : gcols); 594 cols = (rcols > gcols ? rcols : gcols);
631 cols = (cols > bcols ? cols : bcols); 595 cols = (cols > bcols ? cols : bcols);
632 596
633 red = malloc(cols * sizeof(red[0])); 597 red = malloc(cols * sizeof(red[0]));
634 if(!red) { 598 if(!red) {
635 printf("Can't allocate red palette with %d entries.\n", cols); 599 mp_msg(MSGT_VO, MSGL_V, "Can't allocate red palette with %d entries.\n", cols);
636 return NULL; 600 return NULL;
637 } 601 }
638 for(i=0; i< rcols; i++) 602 for(i=0; i< rcols; i++)
639 red[i] = (65535/(rcols-1)) * i; 603 red[i] = (65535/(rcols-1)) * i;
640 604
641 green = malloc(cols * sizeof(green[0])); 605 green = malloc(cols * sizeof(green[0]));
642 if(!green) { 606 if(!green) {
643 printf("Can't allocate green palette with %d entries.\n", cols); 607 mp_msg(MSGT_VO, MSGL_V, "Can't allocate green palette with %d entries.\n", cols);
644 free(red); 608 free(red);
645 return NULL; 609 return NULL;
646 } 610 }
647 for(i=0; i< gcols; i++) 611 for(i=0; i< gcols; i++)
648 green[i] = (65535/(gcols-1)) * i; 612 green[i] = (65535/(gcols-1)) * i;
649 613
650 blue = malloc(cols * sizeof(blue[0])); 614 blue = malloc(cols * sizeof(blue[0]));
651 if(!blue) { 615 if(!blue) {
652 printf("Can't allocate blue palette with %d entries.\n", cols); 616 mp_msg(MSGT_VO, MSGL_V, "Can't allocate blue palette with %d entries.\n", cols);
653 free(red); 617 free(red);
654 free(green); 618 free(green);
655 return NULL; 619 return NULL;
656 } 620 }
657 for(i=0; i< bcols; i++) 621 for(i=0; i< bcols; i++)
658 blue[i] = (65535/(bcols-1)) * i; 622 blue[i] = (65535/(bcols-1)) * i;
659 623
660 cmap = malloc(sizeof(struct fb_cmap)); 624 cmap = malloc(sizeof(struct fb_cmap));
661 if(!cmap) { 625 if(!cmap) {
662 printf("Can't allocate color map\n"); 626 mp_msg(MSGT_VO, MSGL_V, "Can't allocate color map\n");
663 free(red); 627 free(red);
664 free(green); 628 free(green);
665 free(blue); 629 free(blue);
666 return NULL; 630 return NULL;
667 } 631 }
678 642
679 #ifdef CONFIG_VIDIX 643 #ifdef CONFIG_VIDIX
680 static uint32_t parseSubDevice(const char *sd) 644 static uint32_t parseSubDevice(const char *sd)
681 { 645 {
682 if(memcmp(sd,"vidix",5) == 0) vidix_name = &sd[5]; /* vidix_name will be valid within init() */ 646 if(memcmp(sd,"vidix",5) == 0) vidix_name = &sd[5]; /* vidix_name will be valid within init() */
683 else { printf(FBDEV "Unknown subdevice: '%s'\n", sd); return -1; } 647 else { mp_msg(MSGT_VO, MSGL_WARN, "Unknown subdevice: '%s'\n", sd); return -1; }
684 return 0; 648 return 0;
685 } 649 }
686 #endif 650 #endif
687 651
688 static int fb_preinit(int reset) 652 static int fb_preinit(int reset)
699 if (fb_preinit_done) 663 if (fb_preinit_done)
700 return fb_works; 664 return fb_works;
701 665
702 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER"))) 666 if (!fb_dev_name && !(fb_dev_name = getenv("FRAMEBUFFER")))
703 fb_dev_name = "/dev/fb0"; 667 fb_dev_name = "/dev/fb0";
704 if (verbose > 0) 668 mp_msg(MSGT_VO, MSGL_V, "using %s\n", fb_dev_name);
705 printf(FBDEV "using %s\n", fb_dev_name);
706 669
707 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { 670 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) {
708 printf(FBDEV "Can't open %s: %s\n", fb_dev_name, strerror(errno)); 671 mp_msg(MSGT_VO, MSGL_ERR, "Can't open %s: %s\n", fb_dev_name, strerror(errno));
709 goto err_out; 672 goto err_out;
710 } 673 }
711 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) { 674 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
712 printf(FBDEV "Can't get VSCREENINFO: %s\n", strerror(errno)); 675 mp_msg(MSGT_VO, MSGL_ERR, "Can't get VSCREENINFO: %s\n", strerror(errno));
713 goto err_out_fd; 676 goto err_out_fd;
714 } 677 }
715 fb_orig_vinfo = fb_vinfo; 678 fb_orig_vinfo = fb_vinfo;
716 679
717 if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) { 680 if ((fb_tty_fd = open("/dev/tty", O_RDWR)) < 0) {
718 if (verbose > 0) 681 mp_msg(MSGT_VO, MSGL_ERR, "notice: Can't open /dev/tty: %s\n", strerror(errno));
719 printf(FBDEV "notice: Can't open /dev/tty: %s\n", strerror(errno));
720 } 682 }
721 683
722 fb_bpp = fb_vinfo.bits_per_pixel; 684 fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
685 fb_vinfo.blue.length + fb_vinfo.transp.length;
723 686
724 if (fb_bpp == 8 && !vo_dbpp) { 687 if (fb_bpp == 8 && !vo_dbpp) {
725 printf(FBDEV "8 bpp output is not supported.\n"); 688 mp_msg(MSGT_VO, MSGL_ERR, "8 bpp output is not supported.\n");
726 goto err_out_tty_fd; 689 goto err_out_tty_fd;
727 } 690 }
728
729 /* 16 and 15 bpp is reported as 16 bpp */
730 if (fb_bpp == 16)
731 fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
732 fb_vinfo.blue.length;
733 691
734 if (vo_dbpp) { 692 if (vo_dbpp) {
735 if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 && 693 if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 &&
736 vo_dbpp != 32) { 694 vo_dbpp != 32) {
737 printf(FBDEV "can't switch to %d bpp\n", vo_dbpp); 695 mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp);
738 goto err_out_fd; 696 goto err_out_fd;
739 } 697 }
740 fb_bpp = vo_dbpp; 698 fb_bpp = vo_dbpp;
741 } 699 }
742 700
755 return 0; 713 return 0;
756 } 714 }
757 715
758 static void lots_of_printf(void) 716 static void lots_of_printf(void)
759 { 717 {
760 if (verbose > 0) { 718 mp_msg(MSGT_VO, MSGL_V, "var info:\n");
761 printf(FBDEV "var info:\n"); 719 mp_msg(MSGT_VO, MSGL_V, "xres: %u\n", fb_vinfo.xres);
762 printf(FBDEV "xres: %u\n", fb_vinfo.xres); 720 mp_msg(MSGT_VO, MSGL_V, "yres: %u\n", fb_vinfo.yres);
763 printf(FBDEV "yres: %u\n", fb_vinfo.yres); 721 mp_msg(MSGT_VO, MSGL_V, "xres_virtual: %u\n", fb_vinfo.xres_virtual);
764 printf(FBDEV "xres_virtual: %u\n", fb_vinfo.xres_virtual); 722 mp_msg(MSGT_VO, MSGL_V, "yres_virtual: %u\n", fb_vinfo.yres_virtual);
765 printf(FBDEV "yres_virtual: %u\n", fb_vinfo.yres_virtual); 723 mp_msg(MSGT_VO, MSGL_V, "xoffset: %u\n", fb_vinfo.xoffset);
766 printf(FBDEV "xoffset: %u\n", fb_vinfo.xoffset); 724 mp_msg(MSGT_VO, MSGL_V, "yoffset: %u\n", fb_vinfo.yoffset);
767 printf(FBDEV "yoffset: %u\n", fb_vinfo.yoffset); 725 mp_msg(MSGT_VO, MSGL_V, "bits_per_pixel: %u\n", fb_vinfo.bits_per_pixel);
768 printf(FBDEV "bits_per_pixel: %u\n", fb_vinfo.bits_per_pixel); 726 mp_msg(MSGT_VO, MSGL_V, "grayscale: %u\n", fb_vinfo.grayscale);
769 printf(FBDEV "grayscale: %u\n", fb_vinfo.grayscale); 727 mp_msg(MSGT_VO, MSGL_V, "red: %lu %lu %lu\n",
770 printf(FBDEV "red: %lu %lu %lu\n", 728 (unsigned long) fb_vinfo.red.offset,
771 (unsigned long) fb_vinfo.red.offset, 729 (unsigned long) fb_vinfo.red.length,
772 (unsigned long) fb_vinfo.red.length, 730 (unsigned long) fb_vinfo.red.msb_right);
773 (unsigned long) fb_vinfo.red.msb_right); 731 mp_msg(MSGT_VO, MSGL_V, "green: %lu %lu %lu\n",
774 printf(FBDEV "green: %lu %lu %lu\n", 732 (unsigned long) fb_vinfo.green.offset,
775 (unsigned long) fb_vinfo.green.offset, 733 (unsigned long) fb_vinfo.green.length,
776 (unsigned long) fb_vinfo.green.length, 734 (unsigned long) fb_vinfo.green.msb_right);
777 (unsigned long) fb_vinfo.green.msb_right); 735 mp_msg(MSGT_VO, MSGL_V, "blue: %lu %lu %lu\n",
778 printf(FBDEV "blue: %lu %lu %lu\n", 736 (unsigned long) fb_vinfo.blue.offset,
779 (unsigned long) fb_vinfo.blue.offset, 737 (unsigned long) fb_vinfo.blue.length,
780 (unsigned long) fb_vinfo.blue.length, 738 (unsigned long) fb_vinfo.blue.msb_right);
781 (unsigned long) fb_vinfo.blue.msb_right); 739 mp_msg(MSGT_VO, MSGL_V, "transp: %lu %lu %lu\n",
782 printf(FBDEV "transp: %lu %lu %lu\n", 740 (unsigned long) fb_vinfo.transp.offset,
783 (unsigned long) fb_vinfo.transp.offset, 741 (unsigned long) fb_vinfo.transp.length,
784 (unsigned long) fb_vinfo.transp.length, 742 (unsigned long) fb_vinfo.transp.msb_right);
785 (unsigned long) fb_vinfo.transp.msb_right); 743 mp_msg(MSGT_VO, MSGL_V, "nonstd: %u\n", fb_vinfo.nonstd);
786 printf(FBDEV "nonstd: %u\n", fb_vinfo.nonstd); 744 mp_msg(MSGT_VO, MSGL_DBG2, "activate: %u\n", fb_vinfo.activate);
787 if (verbose > 1) { 745 mp_msg(MSGT_VO, MSGL_DBG2, "height: %u\n", fb_vinfo.height);
788 printf(FBDEV "activate: %u\n", fb_vinfo.activate); 746 mp_msg(MSGT_VO, MSGL_DBG2, "width: %u\n", fb_vinfo.width);
789 printf(FBDEV "height: %u\n", fb_vinfo.height); 747 mp_msg(MSGT_VO, MSGL_DBG2, "accel_flags: %u\n", fb_vinfo.accel_flags);
790 printf(FBDEV "width: %u\n", fb_vinfo.width); 748 mp_msg(MSGT_VO, MSGL_DBG2, "timing:\n");
791 printf(FBDEV "accel_flags: %u\n", fb_vinfo.accel_flags); 749 mp_msg(MSGT_VO, MSGL_DBG2, "pixclock: %u\n", fb_vinfo.pixclock);
792 printf(FBDEV "timing:\n"); 750 mp_msg(MSGT_VO, MSGL_DBG2, "left_margin: %u\n", fb_vinfo.left_margin);
793 printf(FBDEV "pixclock: %u\n", fb_vinfo.pixclock); 751 mp_msg(MSGT_VO, MSGL_DBG2, "right_margin: %u\n", fb_vinfo.right_margin);
794 printf(FBDEV "left_margin: %u\n", fb_vinfo.left_margin); 752 mp_msg(MSGT_VO, MSGL_DBG2, "upper_margin: %u\n", fb_vinfo.upper_margin);
795 printf(FBDEV "right_margin: %u\n", fb_vinfo.right_margin); 753 mp_msg(MSGT_VO, MSGL_DBG2, "lower_margin: %u\n", fb_vinfo.lower_margin);
796 printf(FBDEV "upper_margin: %u\n", fb_vinfo.upper_margin); 754 mp_msg(MSGT_VO, MSGL_DBG2, "hsync_len: %u\n", fb_vinfo.hsync_len);
797 printf(FBDEV "lower_margin: %u\n", fb_vinfo.lower_margin); 755 mp_msg(MSGT_VO, MSGL_DBG2, "vsync_len: %u\n", fb_vinfo.vsync_len);
798 printf(FBDEV "hsync_len: %u\n", fb_vinfo.hsync_len); 756 mp_msg(MSGT_VO, MSGL_DBG2, "sync: %u\n", fb_vinfo.sync);
799 printf(FBDEV "vsync_len: %u\n", fb_vinfo.vsync_len); 757 mp_msg(MSGT_VO, MSGL_DBG2, "vmode: %u\n", fb_vinfo.vmode);
800 printf(FBDEV "sync: %u\n", fb_vinfo.sync); 758 mp_msg(MSGT_VO, MSGL_V, "fix info:\n");
801 printf(FBDEV "vmode: %u\n", fb_vinfo.vmode); 759 mp_msg(MSGT_VO, MSGL_V, "framebuffer size: %d bytes\n", fb_finfo.smem_len);
802 } 760 mp_msg(MSGT_VO, MSGL_V, "type: %lu\n", (unsigned long) fb_finfo.type);
803 printf(FBDEV "fix info:\n"); 761 mp_msg(MSGT_VO, MSGL_V, "type_aux: %lu\n", (unsigned long) fb_finfo.type_aux);
804 printf(FBDEV "framebuffer size: %d bytes\n", fb_finfo.smem_len); 762 mp_msg(MSGT_VO, MSGL_V, "visual: %lu\n", (unsigned long) fb_finfo.visual);
805 printf(FBDEV "type: %lu\n", (unsigned long) fb_finfo.type); 763 mp_msg(MSGT_VO, MSGL_V, "line_length: %lu bytes\n", (unsigned long) fb_finfo.line_length);
806 printf(FBDEV "type_aux: %lu\n", (unsigned long) fb_finfo.type_aux); 764 mp_msg(MSGT_VO, MSGL_DBG2, "id: %.16s\n", fb_finfo.id);
807 printf(FBDEV "visual: %lu\n", (unsigned long) fb_finfo.visual); 765 mp_msg(MSGT_VO, MSGL_DBG2, "smem_start: %p\n", (void *) fb_finfo.smem_start);
808 printf(FBDEV "line_length: %lu bytes\n", (unsigned long) fb_finfo.line_length); 766 mp_msg(MSGT_VO, MSGL_DBG2, "xpanstep: %u\n", fb_finfo.xpanstep);
809 if (verbose > 1) { 767 mp_msg(MSGT_VO, MSGL_DBG2, "ypanstep: %u\n", fb_finfo.ypanstep);
810 printf(FBDEV "id: %.16s\n", fb_finfo.id); 768 mp_msg(MSGT_VO, MSGL_DBG2, "ywrapstep: %u\n", fb_finfo.ywrapstep);
811 printf(FBDEV "smem_start: %p\n", (void *) fb_finfo.smem_start); 769 mp_msg(MSGT_VO, MSGL_DBG2, "mmio_start: %p\n", (void *) fb_finfo.mmio_start);
812 printf(FBDEV "xpanstep: %u\n", fb_finfo.xpanstep); 770 mp_msg(MSGT_VO, MSGL_DBG2, "mmio_len: %u bytes\n", fb_finfo.mmio_len);
813 printf(FBDEV "ypanstep: %u\n", fb_finfo.ypanstep); 771 mp_msg(MSGT_VO, MSGL_DBG2, "accel: %u\n", fb_finfo.accel);
814 printf(FBDEV "ywrapstep: %u\n", fb_finfo.ywrapstep); 772 mp_msg(MSGT_VO, MSGL_V, "fb_bpp: %d\n", fb_bpp);
815 printf(FBDEV "mmio_start: %p\n", (void *) fb_finfo.mmio_start); 773 mp_msg(MSGT_VO, MSGL_V, "fb_pixel_size: %d bytes\n", fb_pixel_size);
816 printf(FBDEV "mmio_len: %u bytes\n", fb_finfo.mmio_len); 774 mp_msg(MSGT_VO, MSGL_V, "other:\n");
817 printf(FBDEV "accel: %u\n", fb_finfo.accel); 775 mp_msg(MSGT_VO, MSGL_V, "in_width: %d\n", in_width);
818 } 776 mp_msg(MSGT_VO, MSGL_V, "in_height: %d\n", in_height);
819 printf(FBDEV "fb_bpp: %d\n", fb_bpp); 777 mp_msg(MSGT_VO, MSGL_V, "out_width: %d\n", out_width);
820 printf(FBDEV "fb_real_bpp: %d\n", fb_real_bpp); 778 mp_msg(MSGT_VO, MSGL_V, "out_height: %d\n", out_height);
821 printf(FBDEV "fb_pixel_size: %d bytes\n", fb_pixel_size); 779 mp_msg(MSGT_VO, MSGL_V, "first_row: %d\n", first_row);
822 printf(FBDEV "other:\n"); 780 mp_msg(MSGT_VO, MSGL_V, "last_row: %d\n", last_row);
823 printf(FBDEV "in_width: %d\n", in_width); 781 mp_msg(MSGT_VO, MSGL_DBG2, "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p);
824 printf(FBDEV "in_height: %d\n", in_height);
825 printf(FBDEV "out_width: %d\n", out_width);
826 printf(FBDEV "out_height: %d\n", out_height);
827 printf(FBDEV "first_row: %d\n", first_row);
828 printf(FBDEV "last_row: %d\n", last_row);
829 if (verbose > 1)
830 printf(FBDEV "draw_alpha_p:%dbpp = %p\n", fb_bpp, draw_alpha_p);
831 }
832 } 782 }
833 783
834 static void vt_set_textarea(int u, int l) 784 static void vt_set_textarea(int u, int l)
835 { 785 {
836 /* how can I determine the font height? 786 /* how can I determine the font height?
837 * just use 16 for now 787 * just use 16 for now
838 */ 788 */
839 int urow = ((u + 15) / 16) + 1; 789 int urow = ((u + 15) / 16) + 1;
840 int lrow = l / 16; 790 int lrow = l / 16;
841 791
842 if (verbose > 1) 792 mp_msg(MSGT_VO, MSGL_DBG2, "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow);
843 printf(FBDEV "vt_set_textarea(%d,%d): %d,%d\n", u, l, urow, lrow);
844 if(vt_fp) { 793 if(vt_fp) {
845 fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0); 794 fprintf(vt_fp, "\33[%d;%dr\33[%d;%dH", urow, lrow, lrow, 0);
846 fflush(vt_fp); 795 fflush(vt_fp);
847 } 796 }
848 } 797 }
852 uint32_t format) 801 uint32_t format)
853 { 802 {
854 struct fb_cmap *cmap; 803 struct fb_cmap *cmap;
855 int vm = flags & 0x02; 804 int vm = flags & 0x02;
856 int zoom = flags & 0x04; 805 int zoom = flags & 0x04;
806 int vt_fd;
857 807
858 fs = flags & 0x01; 808 fs = flags & 0x01;
859 flip = flags & 0x08;
860 809
861 if(pre_init_err == -2) 810 if(pre_init_err == -2)
862 { 811 {
863 printf(FBDEV "Internal fatal error: init() was called before preinit()\n"); 812 mp_msg(MSGT_VO, MSGL_ERR, "Internal fatal error: config() was called before preinit()\n");
864 return -1; 813 return -1;
865 } 814 }
866 815
867 if (pre_init_err) return 1; 816 if (pre_init_err) return 1;
868 817
869 #if 0
870 if (zoom
871 #ifdef CONFIG_VIDIX
872 && !vidix_name
873 #endif
874 ) {
875 printf(FBDEV "-zoom is not supported\n");
876 return 1;
877 }
878 #endif
879 if (fb_mode_name && !vm) { 818 if (fb_mode_name && !vm) {
880 printf(FBDEV "-fbmode can only be used with -vm\n"); 819 mp_msg(MSGT_VO, MSGL_ERR, "-fbmode can only be used with -vm\n");
881 return 1; 820 return 1;
882 } 821 }
883 if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0)) 822 if (vm && (parse_fbmode_cfg(fb_mode_cfgfile) < 0))
884 return 1; 823 return 1;
885 if (d_width && (fs || vm)) { 824 if (d_width && (fs || vm)) {
893 in_height = height; 832 in_height = height;
894 pixel_format = format; 833 pixel_format = format;
895 834
896 if (fb_mode_name) { 835 if (fb_mode_name) {
897 if (!(fb_mode = find_mode_by_name(fb_mode_name))) { 836 if (!(fb_mode = find_mode_by_name(fb_mode_name))) {
898 printf(FBDEV "can't find requested video mode\n"); 837 mp_msg(MSGT_VO, MSGL_ERR, "can't find requested video mode\n");
899 return 1; 838 return 1;
900 } 839 }
901 fb_mode2fb_vinfo(fb_mode, &fb_vinfo); 840 fb_mode2fb_vinfo(fb_mode, &fb_vinfo);
902 } else if (vm) { 841 } else if (vm) {
903 monitor_hfreq = str2range(monitor_hfreq_str); 842 monitor_hfreq = str2range(monitor_hfreq_str);
904 monitor_vfreq = str2range(monitor_vfreq_str); 843 monitor_vfreq = str2range(monitor_vfreq_str);
905 monitor_dotclock = str2range(monitor_dotclock_str); 844 monitor_dotclock = str2range(monitor_dotclock_str);
906 if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) { 845 if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) {
907 printf(FBDEV "you have to specify the capabilities of" 846 mp_msg(MSGT_VO, MSGL_ERR, "you have to specify the capabilities of"
908 " the monitor.\n"); 847 " the monitor.\n");
909 return 1; 848 return 1;
910 } 849 }
911 if (!(fb_mode = find_best_mode(out_width, out_height, 850 if (!(fb_mode = find_best_mode(out_width, out_height,
912 monitor_hfreq, monitor_vfreq, 851 monitor_hfreq, monitor_vfreq,
913 monitor_dotclock))) { 852 monitor_dotclock))) {
914 printf(FBDEV "can't find best video mode\n"); 853 mp_msg(MSGT_VO, MSGL_ERR, "can't find best video mode\n");
915 return 1; 854 return 1;
916 } 855 }
917 printf(FBDEV "using mode %dx%d @ %.1fHz\n", fb_mode->xres, 856 mp_msg(MSGT_VO, MSGL_V, "using mode %dx%d @ %.1fHz\n", fb_mode->xres,
918 fb_mode->yres, vsf(fb_mode)); 857 fb_mode->yres, vsf(fb_mode));
919 fb_mode2fb_vinfo(fb_mode, &fb_vinfo); 858 fb_mode2fb_vinfo(fb_mode, &fb_vinfo);
920 } 859 }
921 fb_bpp_we_want = fb_bpp; 860 fb_bpp_we_want = fb_bpp;
922 set_bpp(&fb_vinfo, fb_bpp); 861 set_bpp(&fb_vinfo, fb_bpp);
923 fb_vinfo.xres_virtual = fb_vinfo.xres; 862 fb_vinfo.xres_virtual = fb_vinfo.xres;
924 fb_vinfo.yres_virtual = fb_vinfo.yres; 863 fb_vinfo.yres_virtual = fb_vinfo.yres;
925 864
926 if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) { 865 if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_GRAPHICS) < 0) {
927 if (verbose > 0) 866 mp_msg(MSGT_VO, MSGL_V, "Can't set graphics mode: %s\n", strerror(errno));
928 printf(FBDEV "Can't set graphics mode: %s\n", strerror(errno));
929 close(fb_tty_fd); 867 close(fb_tty_fd);
930 fb_tty_fd = -1; 868 fb_tty_fd = -1;
931 } 869 }
932 870
933 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) { 871 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
934 printf(FBDEV "Can't put VSCREENINFO: %s\n", strerror(errno)); 872 mp_msg(MSGT_VO, MSGL_ERR, "Can't put VSCREENINFO: %s\n", strerror(errno));
935 if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) { 873 if (fb_tty_fd >= 0 && ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) {
936 printf(FBDEV "Can't restore text mode: %s\n", strerror(errno)); 874 mp_msg(MSGT_VO, MSGL_ERR, "Can't restore text mode: %s\n", strerror(errno));
937 } 875 }
938 return 1; 876 return 1;
939 } 877 }
940 878
941 fb_pixel_size = fb_vinfo.bits_per_pixel / 8; 879 fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
942 fb_real_bpp = fb_vinfo.red.length + fb_vinfo.green.length + 880 fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
943 fb_vinfo.blue.length; 881 fb_vinfo.blue.length + fb_vinfo.transp.length;
944 fb_bpp = (fb_pixel_size == 4) ? 32 : fb_real_bpp;
945 if (fb_bpp_we_want != fb_bpp) 882 if (fb_bpp_we_want != fb_bpp)
946 printf(FBDEV "requested %d bpp, got %d bpp!!!\n", 883 mp_msg(MSGT_VO, MSGL_WARN, "requested %d bpp, got %d bpp!!!\n",
947 fb_bpp_we_want, fb_bpp); 884 fb_bpp_we_want, fb_bpp);
948 885
949 switch (fb_bpp) { 886 switch (fb_bpp) {
950 case 32: 887 case 32: draw_alpha_p = vo_draw_alpha_rgb32; break;
951 draw_alpha_p = vo_draw_alpha_rgb32; 888 case 24: draw_alpha_p = vo_draw_alpha_rgb24; break;
952 dstFourcc = IMGFMT_BGR32; 889 case 16: draw_alpha_p = vo_draw_alpha_rgb16; break;
953 break; 890 case 15: draw_alpha_p = vo_draw_alpha_rgb15; break;
954 case 24: 891 default: return 1;
955 draw_alpha_p = vo_draw_alpha_rgb24;
956 dstFourcc = IMGFMT_BGR24;
957 break;
958 default:
959 case 16:
960 draw_alpha_p = vo_draw_alpha_rgb16;
961 dstFourcc = IMGFMT_BGR16;
962 break;
963 case 15:
964 draw_alpha_p = vo_draw_alpha_rgb15;
965 dstFourcc = IMGFMT_BGR15;
966 break;
967 }
968
969 if (flip & ((((pixel_format & 0xff) + 7) / 8) != fb_pixel_size)) {
970 printf(FBDEV "Flipped output with depth conversion is not "
971 "supported\n");
972 return 1;
973 } 892 }
974 893
975 fb_xres = fb_vinfo.xres; 894 fb_xres = fb_vinfo.xres;
976 fb_yres = fb_vinfo.yres; 895 fb_yres = fb_vinfo.yres;
977 896
978 if (vm || fs) { 897 if (vm || fs) {
979 out_width = fb_xres; 898 out_width = fb_xres;
980 out_height = fb_yres; 899 out_height = fb_yres;
981 } 900 }
982 if (out_width < in_width || out_height < in_height) { 901 if (out_width < in_width || out_height < in_height) {
983 printf(FBDEV "screensize is smaller than video size\n"); 902 mp_msg(MSGT_VO, MSGL_ERR, "screensize is smaller than video size\n");
984 return 1; 903 return 1;
985 } 904 }
986 905
987 first_row = (out_height - in_height) / 2; 906 first_row = (out_height - in_height) / 2;
988 last_row = (out_height + in_height) / 2; 907 last_row = (out_height + in_height) / 2;
989 908
990 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) { 909 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
991 printf(FBDEV "Can't get FSCREENINFO: %s\n", strerror(errno)); 910 mp_msg(MSGT_VO, MSGL_ERR, "Can't get FSCREENINFO: %s\n", strerror(errno));
992 return 1; 911 return 1;
993 } 912 }
994 913
995 lots_of_printf(); 914 lots_of_printf();
996 915
997 if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) { 916 if (fb_finfo.type != FB_TYPE_PACKED_PIXELS) {
998 printf(FBDEV "type %d not supported\n", fb_finfo.type); 917 mp_msg(MSGT_VO, MSGL_ERR, "type %d not supported\n", fb_finfo.type);
999 return 1; 918 return 1;
1000 } 919 }
1001 920
1002 switch (fb_finfo.visual) { 921 switch (fb_finfo.visual) {
1003 case FB_VISUAL_TRUECOLOR: 922 case FB_VISUAL_TRUECOLOR:
1004 break; 923 break;
1005 case FB_VISUAL_DIRECTCOLOR: 924 case FB_VISUAL_DIRECTCOLOR:
1006 if (verbose > 0) 925 mp_msg(MSGT_VO, MSGL_V, "creating cmap for directcolor\n");
1007 printf(FBDEV "creating cmap for directcolor\n");
1008 if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) { 926 if (ioctl(fb_dev_fd, FBIOGETCMAP, &fb_oldcmap)) {
1009 printf(FBDEV "can't get cmap: %s\n", 927 mp_msg(MSGT_VO, MSGL_ERR, "can't get cmap: %s\n",
1010 strerror(errno)); 928 strerror(errno));
1011 return 1; 929 return 1;
1012 } 930 }
1013 if (!(cmap = make_directcolor_cmap(&fb_vinfo))) 931 if (!(cmap = make_directcolor_cmap(&fb_vinfo)))
1014 return 1; 932 return 1;
1015 if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { 933 if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) {
1016 printf(FBDEV "can't put cmap: %s\n", 934 mp_msg(MSGT_VO, MSGL_ERR, "can't put cmap: %s\n",
1017 strerror(errno)); 935 strerror(errno));
1018 return 1; 936 return 1;
1019 } 937 }
1020 fb_cmap_changed = 1; 938 fb_cmap_changed = 1;
1021 free(cmap->red); 939 free(cmap->red);
1022 free(cmap->green); 940 free(cmap->green);
1023 free(cmap->blue); 941 free(cmap->blue);
1024 free(cmap); 942 free(cmap);
1025 break; 943 break;
1026 default: 944 default:
1027 printf(FBDEV "visual: %d not yet supported\n", 945 mp_msg(MSGT_VO, MSGL_ERR, "visual: %d not yet supported\n",
1028 fb_finfo.visual); 946 fb_finfo.visual);
1029 return 1; 947 return 1;
1030 } 948 }
1031 949
1032 fb_line_len = fb_finfo.line_length; 950 fb_line_len = fb_finfo.line_length;
1052 else x_offset = 0; 970 else x_offset = 0;
1053 if(fb_yres > image_height) 971 if(fb_yres > image_height)
1054 y_offset = (fb_yres - image_height) / 2; 972 y_offset = (fb_yres - image_height) / 2;
1055 else y_offset = 0; 973 else y_offset = 0;
1056 974
1057 //FIXME: update geometry code
1058 //geometry(&x_offset,&y_offset,fb_xres,fb_yres,image_width,image_height);
1059
1060 if(vidix_init(width,height,x_offset,y_offset,image_width, 975 if(vidix_init(width,height,x_offset,y_offset,image_width,
1061 image_height,format,fb_bpp, 976 image_height,format,fb_bpp,
1062 fb_xres,fb_yres) != 0) 977 fb_xres,fb_yres) != 0)
1063 { 978 {
1064 printf(FBDEV "Can't initialize VIDIX driver\n"); 979 mp_msg(MSGT_VO, MSGL_ERR, "Can't initialize VIDIX driver\n");
1065 vidix_name = NULL; 980 vidix_name = NULL;
1066 vidix_term(); 981 vidix_term();
1067 return -1; 982 return -1;
1068 } 983 }
1069 else printf(FBDEV "Using VIDIX\n"); 984 else mp_msg(MSGT_VO, MSGL_V, "Using VIDIX\n");
1070 vidix_start(); 985 vidix_start();
1071 } 986 }
1072 else 987 else
1073 #endif 988 #endif
1074 { 989 {
1075 int x_offset=0,y_offset=0; 990 int x_offset=0,y_offset=0;
1076 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, 991 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE,
1077 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { 992 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) {
1078 printf(FBDEV "Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); 993 mp_msg(MSGT_VO, MSGL_ERR, "Can't mmap %s: %s\n", fb_dev_name, strerror(errno));
1079 return 1; 994 return 1;
1080 } 995 }
1081
1082 //FIXME: update geometry code
1083 //geometry(&x_offset,&y_offset,fb_xres,fb_yres,out_width,out_height);
1084 996
1085 center = frame_buffer + (out_width - in_width) * fb_pixel_size / 997 center = frame_buffer + (out_width - in_width) * fb_pixel_size /
1086 2 + ( (out_height - in_height) / 2 ) * fb_line_len + 998 2 + ( (out_height - in_height) / 2 ) * fb_line_len +
1087 x_offset * fb_pixel_size + y_offset * fb_line_len; 999 x_offset * fb_pixel_size + y_offset * fb_line_len;
1088 1000
1089 if (verbose > 0) { 1001 mp_msg(MSGT_VO, MSGL_DBG2, "frame_buffer @ %p\n", frame_buffer);
1090 if (verbose > 1) { 1002 mp_msg(MSGT_VO, MSGL_DBG2, "center @ %p\n", center);
1091 printf(FBDEV "frame_buffer @ %p\n", frame_buffer); 1003 mp_msg(MSGT_VO, MSGL_V, "pixel per line: %d\n", fb_line_len / fb_pixel_size);
1092 printf(FBDEV "center @ %p\n", center);
1093 }
1094 printf(FBDEV "pixel per line: %d\n", fb_line_len / fb_pixel_size);
1095 }
1096 1004
1097 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) { 1005 if (!(next_frame = (uint8_t *) malloc(in_width * in_height * fb_pixel_size))) {
1098 printf(FBDEV "Can't malloc next_frame: %s\n", strerror(errno)); 1006 mp_msg(MSGT_VO, MSGL_ERR, "Can't malloc next_frame: %s\n", strerror(errno));
1099 return 1; 1007 return 1;
1100 } 1008 }
1101 if (fs || vm) 1009 if (fs || vm)
1102 memset(frame_buffer, '\0', fb_line_len * fb_yres); 1010 memset(frame_buffer, '\0', fb_line_len * fb_yres);
1103 } 1011 }
1104 if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) { 1012 if (vt_doit && (vt_fd = open("/dev/tty", O_WRONLY)) == -1) {
1105 printf(FBDEV "can't open /dev/tty: %s\n", strerror(errno)); 1013 mp_msg(MSGT_VO, MSGL_ERR, "can't open /dev/tty: %s\n", strerror(errno));
1106 vt_doit = 0; 1014 vt_doit = 0;
1107 } 1015 }
1108 if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) { 1016 if (vt_doit && !(vt_fp = fdopen(vt_fd, "w"))) {
1109 printf(FBDEV "can't fdopen /dev/tty: %s\n", strerror(errno)); 1017 mp_msg(MSGT_VO, MSGL_ERR, "can't fdopen /dev/tty: %s\n", strerror(errno));
1110 vt_doit = 0; 1018 vt_doit = 0;
1111 } 1019 }
1112 1020
1113 if (vt_doit) 1021 if (vt_doit)
1114 vt_set_textarea(last_row, fb_yres); 1022 vt_set_textarea(last_row, fb_yres);
1115 1023
1116 sws_rgb2rgb_init(get_sws_cpuflags());
1117
1118 return 0; 1024 return 0;
1119 } 1025 }
1120 1026
1121 static uint32_t query_format(uint32_t format) 1027 static uint32_t query_format(uint32_t format)
1122 { 1028 {
1123 int ret = VFCAP_OSD|VFCAP_CSP_SUPPORTED; /* osd/sub is supported on every bpp */
1124
1125 if (!fb_preinit(0)) 1029 if (!fb_preinit(0))
1126 return 0; 1030 return 0;
1127 #ifdef CONFIG_VIDIX 1031 #ifdef CONFIG_VIDIX
1128 if(vidix_name) 1032 if(vidix_name)
1129 return (vidix_query_fourcc(format)); 1033 return (vidix_query_fourcc(format));
1130 #endif 1034 #endif
1131 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) { 1035 if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
1132 int bpp = format & 0xff; 1036 int bpp = format & 0xff;
1133 1037
1134 if (bpp == fb_bpp) 1038 if (bpp == fb_bpp)
1135 return ret|VFCAP_CSP_SUPPORTED_BY_HW; 1039 return VFCAP_ACCEPT_STRIDE | VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
1136 else if (bpp == 15 && fb_bpp == 16)
1137 return ret;
1138 else if (bpp == 24 && fb_bpp == 32)
1139 return ret;
1140 } 1040 }
1141 return 0; 1041 return 0;
1142 } 1042 }
1143 1043
1144 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, 1044 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
1145 unsigned char *srca, int stride) 1045 unsigned char *srca, int stride)
1146 { 1046 {
1147 unsigned char *dst; 1047 unsigned char *dst;
1148 int dstride; 1048 int dstride;
1149 1049
1150 dst = next_frame + (in_width * y0 + x0) * fb_pixel_size; 1050 dst = next_frame + (in_width * y0 + x0) * fb_pixel_size;
1151 dstride = in_width * fb_pixel_size; 1051 dstride = in_width * fb_pixel_size;
1152 1052
1153 (*draw_alpha_p)(w, h, src, srca, stride, dst, dstride); 1053 (*draw_alpha_p)(w, h, src, srca, stride, dst, dstride);
1154 } 1054 }
1155 1055
1156 static uint32_t draw_frame(uint8_t *src[]) 1056 static uint32_t draw_frame(uint8_t *src[]) { return 1; }
1157 {
1158 if (flip) {
1159 int h = in_height;
1160 int len = in_width * fb_pixel_size;
1161 char *d = next_frame + (in_height - 1) * len;
1162 char *s = src[0];
1163 while (h--) {
1164 memcpy(d, s, len);
1165 s += len;
1166 d -= len;
1167 }
1168 } else {
1169 int sbpp = ((pixel_format & 0xff) + 7) / 8;
1170 char *d = next_frame;
1171 char *s = src[0];
1172 if (sbpp == fb_pixel_size) {
1173 if (fb_real_bpp == 16 && pixel_format == (IMGFMT_BGR|15))
1174 rgb15to16(s, d, 2 * in_width * in_height);
1175 else
1176 memcpy(d, s, sbpp * in_width * in_height);
1177 }
1178 }
1179 return 0;
1180 }
1181 1057
1182 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x, 1058 static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, int x,
1183 int y) 1059 int y)
1184 { 1060 {
1061 uint8_t *d;
1062 uint8_t *s;
1063 int next;
1064
1065 d = next_frame + (in_width * y + x) * fb_pixel_size;
1066 next = in_width * fb_pixel_size;
1067
1068 s = src[0];
1069 while (h) {
1070 memcpy(d, s, w * fb_pixel_size);
1071 d += next;
1072 s += stride[0];
1073 h--;
1074 }
1075
1185 return 0; 1076 return 0;
1186 } 1077 }
1187 1078
1188 static void check_events(void) 1079 static void check_events(void)
1189 { 1080 {
1190 }
1191
1192 static void draw_osd(void)
1193 {
1194 vo_draw_text(in_width, in_height, draw_alpha);
1195 } 1081 }
1196 1082
1197 static void flip_page(void) 1083 static void flip_page(void)
1198 { 1084 {
1199 int i, out_offset = 0, in_offset = 0; 1085 int i, out_offset = 0, in_offset = 0;
1204 out_offset += fb_line_len; 1090 out_offset += fb_line_len;
1205 in_offset += in_width * fb_pixel_size; 1091 in_offset += in_width * fb_pixel_size;
1206 } 1092 }
1207 } 1093 }
1208 1094
1095 static void draw_osd(void)
1096 {
1097 vo_draw_text(in_width, in_height, draw_alpha);
1098 }
1099
1209 static void uninit(void) 1100 static void uninit(void)
1210 { 1101 {
1211 if (verbose > 0)
1212 printf(FBDEV "uninit\n");
1213 fb_preinit(1);
1214 if (fb_cmap_changed) { 1102 if (fb_cmap_changed) {
1215 if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap)) 1103 if (ioctl(fb_dev_fd, FBIOPUTCMAP, &fb_oldcmap))
1216 printf(FBDEV "Can't restore original cmap\n"); 1104 mp_msg(MSGT_VO, MSGL_WARN, "Can't restore original cmap\n");
1217 fb_cmap_changed = 0; 1105 fb_cmap_changed = 0;
1218 } 1106 }
1219 if(next_frame) free(next_frame); 1107 if(next_frame) free(next_frame);
1220 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo)) 1108 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_vinfo))
1221 printf(FBDEV "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); 1109 mp_msg(MSGT_VO, MSGL_WARN, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
1222 fb_orig_vinfo.xoffset = fb_vinfo.xoffset; 1110 fb_orig_vinfo.xoffset = fb_vinfo.xoffset;
1223 fb_orig_vinfo.yoffset = fb_vinfo.yoffset; 1111 fb_orig_vinfo.yoffset = fb_vinfo.yoffset;
1224 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo)) 1112 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_orig_vinfo))
1225 printf(FBDEV "Can't reset original fb_var_screeninfo: %s\n", strerror(errno)); 1113 mp_msg(MSGT_VO, MSGL_WARN, "Can't reset original fb_var_screeninfo: %s\n", strerror(errno));
1226 if (fb_tty_fd >= 0) { 1114 if (fb_tty_fd >= 0) {
1227 if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0) 1115 if (ioctl(fb_tty_fd, KDSETMODE, KD_TEXT) < 0)
1228 printf(FBDEV "Can't restore text mode: %s\n", strerror(errno)); 1116 mp_msg(MSGT_VO, MSGL_WARN, "Can't restore text mode: %s\n", strerror(errno));
1229 } 1117 }
1230 if (vt_doit) 1118 if (vt_doit)
1231 vt_set_textarea(0, fb_orig_vinfo.yres); 1119 vt_set_textarea(0, fb_orig_vinfo.yres);
1232 close(fb_tty_fd); 1120 close(fb_tty_fd);
1233 close(fb_dev_fd); 1121 close(fb_dev_fd);
1234 if(frame_buffer) munmap(frame_buffer, fb_size); 1122 if(frame_buffer) munmap(frame_buffer, fb_size);
1123 frame_buffer = next_frame = NULL;
1235 #ifdef CONFIG_VIDIX 1124 #ifdef CONFIG_VIDIX
1236 if(vidix_name) vidix_term(); 1125 if(vidix_name) vidix_term();
1237 #endif 1126 #endif
1127 fb_preinit(1);
1238 } 1128 }
1239 1129
1240 static uint32_t preinit(const char *vo_subdevice) 1130 static uint32_t preinit(const char *vo_subdevice)
1241 { 1131 {
1242 pre_init_err = 0; 1132 pre_init_err = 0;
1243 #ifdef CONFIG_VIDIX 1133 #ifdef CONFIG_VIDIX
1244 if(vo_subdevice) parseSubDevice(vo_subdevice); 1134 if(vo_subdevice) parseSubDevice(vo_subdevice);
1245 if(vidix_name) pre_init_err = vidix_preinit(vidix_name,&video_out_fbdev); 1135 if(vidix_name) pre_init_err = vidix_preinit(vidix_name,&video_out_fbdev);
1246 if(verbose > 2) 1136 mp_msg(MSGT_VO, MSGL_DBG3, "vo_subdevice: initialization returns: %i\n",pre_init_err);
1247 printf("vo_subdevice: initialization returns: %i\n",pre_init_err);
1248 #endif 1137 #endif
1249 if(!pre_init_err) return (pre_init_err=(fb_preinit(0)?0:-1)); 1138 if(!pre_init_err) return (pre_init_err=(fb_preinit(0)?0:-1));
1250 return(-1); 1139 return(-1);
1251 } 1140 }
1252 1141
1142 static uint32_t get_image(mp_image_t *mpi)
1143 {
1144 if (
1145 !IMGFMT_IS_BGR(mpi->imgfmt) ||
1146 (IMGFMT_BGR_DEPTH(mpi->imgfmt) != fb_bpp) ||
1147 ((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) ||
1148 (mpi->flags & MP_IMGFLAG_PLANAR) ||
1149 (mpi->flags & MP_IMGFLAG_YUV) ||
1150 (mpi->width != in_width) ||
1151 (mpi->height != in_height)
1152 )
1153 return(VO_FALSE);
1154
1155 mpi->planes[0] = center;
1156 mpi->stride[0] = fb_line_len;
1157 mpi->flags |= MP_IMGFLAG_DIRECT;
1158 return(VO_TRUE);
1159 }
1160
1253 static uint32_t control(uint32_t request, void *data, ...) 1161 static uint32_t control(uint32_t request, void *data, ...)
1254 { 1162 {
1255 switch (request) { 1163 switch (request) {
1164 case VOCTRL_GET_IMAGE:
1165 return get_image(data);
1256 case VOCTRL_QUERY_FORMAT: 1166 case VOCTRL_QUERY_FORMAT:
1257 return query_format(*((uint32_t*)data)); 1167 return query_format(*((uint32_t*)data));
1258 } 1168 }
1259 return VO_NOTIMPL; 1169 return VO_NOTIMPL;
1260 } 1170 }