af_scaletempo: fix crash after channel reconfiguration
[mplayer.git] / libvo / vo_aa.c
blob4908e3c899003468471135efa0f88b0f58a509ca
1 /*
2 * video output driver for AAlib
4 * copyright (c) 2001 Folke Ashberg <folke@ashberg.de>
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <stdio.h>
24 #include <stdlib.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
29 #include <limits.h>
30 #include <math.h>
31 #include <stdarg.h>
32 #include <time.h>
33 #include <string.h>
34 #include <errno.h>
36 #include "config.h"
37 #include "video_out.h"
38 #include "video_out_internal.h"
39 #include "aspect.h"
40 #include "libswscale/swscale.h"
41 #include "libmpcodecs/vf_scale.h"
42 #include "sub/font_load.h"
43 #include "sub/sub.h"
45 #include "input/keycodes.h"
46 #include <aalib.h>
47 #include "subopt-helper.h"
48 #include "mp_msg.h"
49 #include "mp_fifo.h"
52 #define MESSAGE_DURATION 3
53 #define MESSAGE_SIZE 512
54 #define MESSAGE_DEKO " +++ %s +++ "
56 static const vo_info_t info = {
57 "AAlib",
58 "aa",
59 "Alban Bedel <albeu@free.fr> and Folke Ashberg <folke@ashberg.de>",
63 const LIBVO_EXTERN(aa)
65 /* aa's main context we use */
66 aa_context *c;
67 aa_renderparams *p;
68 static int fast =0;
69 /* used for the sws */
70 static uint8_t * image[MP_MAX_PLANES];
71 static int image_stride[MP_MAX_PLANES];
73 /* image infos */
74 static int image_format;
75 static int image_width;
76 static int image_height;
77 static int image_x, image_y;
78 static int screen_x, screen_y;
79 static int screen_w, screen_h;
80 static int src_width;
81 static int src_height;
83 /* osd stuff */
84 time_t stoposd = 0;
85 static int showosdmessage = 0;
86 char osdmessagetext[MESSAGE_SIZE];
87 char posbar[MESSAGE_SIZE];
88 static int osdx, osdy;
89 static int osd_text_length = 0;
90 int aaconfigmode=1;
91 font_desc_t* vo_font_save = NULL;
92 static struct SwsContext *sws=NULL;
94 /* configuration */
95 int aaopt_osdcolor = AA_SPECIAL;
96 int aaopt_subcolor = AA_SPECIAL;
98 static unsigned char vo_osd_text[64];
100 static void
101 resize(void){
103 * this function is called by aa lib if windows resizes
104 * further during init, because here we have to calculate
105 * a little bit
108 aa_resize(c);
110 aspect_save_screenres(aa_imgwidth(c),aa_imgheight(c));
111 image_height = aa_imgheight(c); //src_height;
112 image_width = aa_imgwidth(c); //src_width;
114 aspect(&image_width,&image_height,A_ZOOM);
116 image_x = (aa_imgwidth(c) - image_width) / 2;
117 image_y = (aa_imgheight(c) - image_height) / 2;
118 screen_w = image_width * aa_scrwidth(c) / aa_imgwidth(c);
119 screen_h = image_height * aa_scrheight(c) / aa_imgheight(c);
120 screen_x = (aa_scrwidth(c) - screen_w) / 2;
121 screen_y = (aa_scrheight(c) - screen_h) / 2;
123 if(sws) sws_freeContext(sws);
124 sws = sws_getContextFromCmdLine(src_width,src_height,image_format,
125 image_width,image_height,IMGFMT_Y8);
127 memset(image, 0, sizeof(image));
128 image[0] = aa_image(c) + image_y * aa_imgwidth(c) + image_x;
130 memset(image_stride, 0, sizeof(image_stride));
131 image_stride[0] = aa_imgwidth(c);
133 showosdmessage=0;
137 static void
138 osdmessage(int duration, int deko, const char *fmt, ...)
141 * for outputting a centered string at the bottom
142 * of our window for a while
144 va_list ar;
145 char m[MESSAGE_SIZE];
146 unsigned int old_len = strlen(osdmessagetext);
148 va_start(ar, fmt);
149 vsprintf(m, fmt, ar);
150 va_end(ar);
151 if (deko==1) sprintf(osdmessagetext, MESSAGE_DEKO , m);
152 else strcpy(osdmessagetext, m);
154 if(old_len > strlen(osdmessagetext)) {
155 memset(c->textbuffer + osdy * aa_scrwidth(c) + osdx,' ',old_len);
156 memset(c->attrbuffer + osdy * aa_scrwidth(c) + osdx,0,old_len);
158 showosdmessage=1;
159 stoposd = time(NULL) + duration;
160 osdx=(aa_scrwidth(c) / 2) - (strlen(osdmessagetext) / 2 ) ;
161 posbar[0]='\0';
164 static void
165 osdpercent(int duration, int deko, int min, int max, int val, const char * desc, const char * unit)
168 * prints a bar for setting values
170 float step;
171 int where;
172 int i;
175 step=(float)aa_scrwidth(c) /(float)(max-min);
176 where=(val-min)*step;
177 osdmessage(duration,deko,"%s: %i%s",desc, val, unit);
178 posbar[0]='|';
179 posbar[aa_scrwidth(c)-1]='|';
180 for (i=0;i<aa_scrwidth(c);i++){
181 if (i==where) posbar[i]='#';
182 else posbar[i]='-';
184 if (where!=0) posbar[0]='|';
185 if (where!=(aa_scrwidth(c)-1) ) posbar[aa_scrwidth(c)-1]='|';
187 posbar[aa_scrwidth(c)]='\0';
191 static void
192 printosdtext(void)
195 * places the mplayer status osd
197 if (vo_osd_text[0] != 0) {
198 int len;
199 if(vo_osd_text[0] < 32) {
200 len = strlen(sub_osd_names_short[vo_osd_text[0]]) + strlen(vo_osd_text+1) + 2;
201 aa_printf(c, 0, 0 , aaopt_osdcolor, "%s %s ", sub_osd_names_short[vo_osd_text[0]], vo_osd_text+1);
202 } else {
203 len = strlen(vo_osd_text) + 1;
204 aa_printf(c, 0, 0 , aaopt_osdcolor, "%s ",vo_osd_text);
207 if(len < osd_text_length) {
208 memset(c->textbuffer + len,' ',osd_text_length - len);
209 memset(c->attrbuffer + len,0,osd_text_length - len);
211 osd_text_length = len;
216 static void
217 printosdprogbar(void){
218 /* print mplayer osd-progbar */
219 if (vo_osd_progbar_type!=-1){
220 osdpercent(1,1,0,255,vo_osd_progbar_value, sub_osd_names[vo_osd_progbar_type], "");
223 static int
224 config(uint32_t width, uint32_t height, uint32_t d_width,
225 uint32_t d_height, uint32_t flags, char *title,
226 uint32_t format) {
228 * main init
229 * called by mplayer
232 int i;
234 aspect_save_orig(width,height);
235 aspect_save_prescale(d_width,d_height);
237 src_height = height;
238 src_width = width;
239 image_format = format;
241 /* nothing will change its size, be we need some values initialized */
242 resize();
244 /* now init our own 'font' */
245 if(!vo_font_save) vo_font_save = vo_font;
246 if(vo_font == vo_font_save) {
247 vo_font=malloc(sizeof(font_desc_t));//if(!desc) return NULL;
248 memset(vo_font,0,sizeof(font_desc_t));
249 vo_font->pic_a[0]=malloc(sizeof(raw_file));
250 memset(vo_font->pic_a[0],0,sizeof(raw_file));
251 vo_font->pic_b[0]=malloc(sizeof(raw_file));
252 memset(vo_font->pic_b[0],0,sizeof(raw_file));
254 #ifdef CONFIG_FREETYPE
255 vo_font->dynamic = 0;
256 #endif
258 vo_font->spacewidth=1;
259 vo_font->charspace=0;
260 vo_font->height=1;
261 vo_font->pic_a[0]->bmp=malloc(255);
262 vo_font->pic_a[0]->pal=NULL;
263 vo_font->pic_b[0]->bmp=malloc(255);
264 vo_font->pic_b[0]->pal=NULL;
265 vo_font->pic_a[0]->w=1;
266 vo_font->pic_a[0]->h=1;
267 for (i=0; i<255; i++){
268 vo_font->width[i]=1;
269 vo_font->font[i]=0;
270 vo_font->start[i]=i;
271 vo_font->pic_a[0]->bmp[i]=i;
272 vo_font->pic_b[0]->bmp[i]=i;
276 /* say hello */
277 osdmessage(5, 1, "Welcome to ASCII ART MPlayer");
279 mp_msg(MSGT_VO,MSGL_V,"VO: [aa] screendriver: %s\n", c->driver->name);
280 mp_msg(MSGT_VO,MSGL_V,"VO: [aa] keyboarddriver: %s\n", c->kbddriver->name);
282 mp_msg(MSGT_VO,MSGL_INFO,
283 "\n"
284 "Important suboptions\n"
285 "\textended use use all 256 characters\n"
286 "\teight use eight bit ascii\n"
287 "\tdriver set recommended aalib driver (X11,curses,linux)\n"
288 "\thelp to see all options provided by aalib\n"
289 "\n"
290 "AA-MPlayer Keys\n"
291 "\t1 : contrast -\n"
292 "\t2 : contrast +\n"
293 "\t3 : brightness -\n"
294 "\t4 : brightness +\n"
295 "\t5 : fast rendering\n"
296 "\t6 : dithering\n"
297 "\t7 : invert image\n"
298 "\ta : toggles between aa and mplayer control\n"
300 "\n"
301 "All other keys are MPlayer defaults.\n"
306 return 0;
309 static int
310 query_format(uint32_t format) {
312 * ...are we able to... ?
313 * called by mplayer
314 * All input format supported by the sws
316 switch(format){
317 case IMGFMT_YV12:
318 case IMGFMT_I420:
319 case IMGFMT_IYUV:
320 case IMGFMT_IYU2:
321 case IMGFMT_BGR32:
322 case IMGFMT_BGR24:
323 case IMGFMT_BGR16:
324 case IMGFMT_BGR15:
325 case IMGFMT_RGB32:
326 case IMGFMT_RGB24:
327 case IMGFMT_Y8:
328 case IMGFMT_Y800:
329 return VFCAP_CSP_SUPPORTED | VFCAP_SWSCALE | VFCAP_OSD;
331 return 0;
334 static int
335 draw_frame(uint8_t *src[]) {
336 int stride[MP_MAX_PLANES] = {0};
338 switch(image_format) {
339 case IMGFMT_BGR15:
340 case IMGFMT_BGR16:
341 stride[0] = src_width*2;
342 break;
343 case IMGFMT_IYU2:
344 case IMGFMT_BGR24:
345 stride[0] = src_width*3;
346 break;
347 case IMGFMT_BGR32:
348 stride[0] = src_width*4;
349 break;
352 sws_scale(sws,(const uint8_t **)src,stride,0,src_height,image,image_stride);
354 /* Now 'ASCIInate' the image */
355 if (fast)
356 aa_fastrender(c, screen_x, screen_y, screen_w + screen_x, screen_h + screen_y );
357 else
358 aa_render(c, p,screen_x, screen_y, screen_w + screen_x, screen_h + screen_y );
360 return 0;
363 static int
364 draw_slice(uint8_t *src[], int stride[],
365 int w, int h, int x, int y) {
367 int dx1 = screen_x + (x * screen_w / src_width);
368 int dy1 = screen_y + (y * screen_h / src_height);
369 int dx2 = screen_x + ((x+w) * screen_w / src_width);
370 int dy2 = screen_y + ((y+h) * screen_h / src_height);
372 sws_scale(sws,(const uint8_t **)src,stride,y,h,image,image_stride);
374 /* Now 'ASCIInate' the image */
375 if (fast)
376 aa_fastrender(c, dx1, dy1, dx2, dy2 );
377 else
378 aa_render(c, p,dx1, dy1, dx2, dy2 );
381 return 0;
384 static void
385 flip_page(void) {
387 /* do we have to put *our* (messages, progbar) osd to aa's txtbuf ? */
388 if (showosdmessage)
390 if (time(NULL)>=stoposd ) {
391 showosdmessage=0;
392 if(*osdmessagetext) {
393 memset(c->textbuffer + osdy * aa_scrwidth(c) + osdx,' ',strlen(osdmessagetext));
394 memset(c->attrbuffer + osdy * aa_scrwidth(c) + osdx ,0,strlen(osdmessagetext));
395 osdmessagetext[0] = '\0';
397 if(*posbar) {
398 memset(c->textbuffer + (osdy+1) * aa_scrwidth(c),' ',strlen(posbar));
399 memset(c->attrbuffer + (osdy+1) * aa_scrwidth(c),0,strlen(posbar));
401 } else {
402 /* update osd */
403 aa_puts(c, osdx, osdy, AA_SPECIAL, osdmessagetext);
404 /* posbar? */
405 if (posbar[0]!='\0')
406 aa_puts(c, 0, osdy + 1, AA_SPECIAL, posbar);
409 /* OSD time & playmode , subtitles */
410 printosdtext();
413 /* print out */
414 aa_flush(c);
417 static void
418 check_events(void) {
420 * any events?
421 * called by show_image and mplayer
423 int key;
424 while ((key=aa_getevent(c,0))!=AA_NONE ){
425 if (key>255){
426 /* some conversations */
427 switch (key) {
428 case AA_UP:
429 mplayer_put_key(KEY_UP);
430 break;
431 case AA_DOWN:
432 mplayer_put_key(KEY_DOWN);
433 break;
434 case AA_LEFT:
435 mplayer_put_key(KEY_LEFT);
436 break;
437 case AA_RIGHT:
438 mplayer_put_key(KEY_RIGHT);
439 break;
440 case AA_ESC:
441 mplayer_put_key(KEY_ESC);
442 break;
443 case 65765:
444 mplayer_put_key(KEY_PAGE_UP);
445 break;
446 case 65766:
447 mplayer_put_key(KEY_PAGE_DOWN);
448 break;
449 default:
450 continue; /* aa lib special key */
451 break;
454 if (key=='a' || key=='A'){
455 aaconfigmode=!aaconfigmode;
456 osdmessage(MESSAGE_DURATION, 1, "aa config mode is now %s",
457 aaconfigmode==1 ? "on. use keys 5-7" : "off");
459 if (aaconfigmode==1) {
460 switch (key) {
461 /* AA image controls */
462 case '5':
463 fast=!fast;
464 osdmessage(MESSAGE_DURATION, 1, "Fast mode is now %s", fast==1 ? "on" : "off");
465 break;
466 case '6':
467 if (p->dither==AA_FLOYD_S){
468 p->dither=AA_NONE;
469 osdmessage(MESSAGE_DURATION, 1, "Dithering: Off");
470 }else if (p->dither==AA_NONE){
471 p->dither=AA_ERRORDISTRIB;
472 osdmessage(MESSAGE_DURATION, 1, "Dithering: Error Distribution");
473 }else if (p->dither==AA_ERRORDISTRIB){
474 p->dither=AA_FLOYD_S;
475 osdmessage(MESSAGE_DURATION, 1, "Dithering: Floyd Steinberg");
477 break;
478 case '7':
479 p->inversion=!p->inversion;
480 osdmessage(MESSAGE_DURATION, 1, "Invert mode is now %s",
481 p->inversion==1 ? "on" : "off");
482 break;
484 default :
485 /* nothing if we're interested in?
486 * the mplayer should handle it!
488 mplayer_put_key(key);
489 break;
491 }// aaconfigmode
492 else mplayer_put_key(key);
496 static void
497 uninit(void) {
499 * THE END
502 if (strstr(c->driver->name,"Curses") || strstr(c->driver->name,"Linux")){
503 freopen("/dev/tty", "w", stderr);
505 if(vo_font_save) {
506 free(vo_font->pic_a[0]->bmp);
507 free(vo_font->pic_a[0]);
508 free(vo_font->pic_b[0]->bmp);
509 free(vo_font->pic_b[0]);
510 free(vo_font);
511 vo_font = vo_font_save;
512 vo_font_save = NULL;
514 aa_close(c);
517 static void draw_alpha(int x,int y, int w,int h, unsigned char* src, unsigned char *srca, int stride){
518 int i,j;
519 for (i = 0; i < h; i++) {
520 for (j = 0; j < w; j++) {
521 if (src[i*stride+j] > 0) {
522 c->textbuffer[x + j + (y+i)*aa_scrwidth(c)] = src[i*stride+j];
523 c->attrbuffer[x + j + (y+i)*aa_scrwidth(c)] = aaopt_subcolor;
529 static void clear_alpha(int x0,int y0, int w,int h) {
530 int l;
532 for(l = 0 ; l < h ; l++) {
533 memset(c->textbuffer + (y0 + l) * aa_scrwidth(c) + x0,' ',w);
534 memset(c->attrbuffer + (y0 + l) * aa_scrwidth(c) + x0,0,w);
539 static void
540 draw_osd(void){
541 char vo_osd_text_save;
542 int vo_osd_progbar_type_save;
544 printosdprogbar();
545 /* let vo_draw_text only write subtitle */
546 vo_osd_text_save = global_osd->osd_text[0];
547 global_osd->osd_text[0] = 0;
548 vo_osd_progbar_type_save=vo_osd_progbar_type;
549 vo_osd_progbar_type=-1;
550 vo_remove_text(aa_scrwidth(c), aa_scrheight(c),clear_alpha);
551 vo_draw_text(aa_scrwidth(c), aa_scrheight(c), draw_alpha);
552 global_osd->osd_text[0] = vo_osd_text_save;
553 vo_osd_progbar_type=vo_osd_progbar_type_save;
556 static int
557 getcolor(char * s){
558 int i;
559 char * rest;
560 if (s==NULL) return -1;
561 i=strtol(s, &rest, 10);
562 if ((rest==NULL || strlen(rest)==0) && i>=0 && i<=5) return i;
563 if (!strcasecmp(s, "normal")) return AA_NORMAL;
564 else if (!strcasecmp(s, "dim")) return AA_DIM;
565 else if (!strcasecmp(s, "bold")) return AA_BOLD;
566 else if (!strcasecmp(s, "boldfont")) return AA_BOLDFONT;
567 else if (!strcasecmp(s, "special")) return AA_SPECIAL;
568 else return -1;
571 static int parse_suboptions(const char *arg) {
572 char *pseudoargv[4], *osdcolor = NULL, *subcolor = NULL, **strings,
573 *helpmsg = NULL;
574 int pseudoargc, displayhelp = 0, *booleans;
575 const opt_t extra_opts[] = {
576 {"osdcolor", OPT_ARG_MSTRZ, &osdcolor, NULL},
577 {"subcolor", OPT_ARG_MSTRZ, &subcolor, NULL},
578 {"help", OPT_ARG_BOOL, &displayhelp, NULL} };
579 opt_t *subopts = NULL, *p;
580 char * const strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
581 "-width", "-height", "-minwidth", "-minheight", "-maxwidth",
582 "-maxheight", "-recwidth", "-recheight", "-bright", "-contrast",
583 "-gamma", "-dimmul", "-boldmul", "-random" };
584 char * const booleans_list[] = {"-dim", "-bold", "-reverse", "-normal",
585 "-boldfont", "-inverse", "-extended", "-eight", "-dither",
586 "-floyd_steinberg", "-error_distribution"};
587 char * const nobooleans_list[] = {"-nodim", "-nobold", "-noreverse", "-nonormal",
588 "-noboldfont", "-noinverse", "-noextended", "-noeight", "-nodither",
589 "-nofloyd_steinberg", "-noerror_distribution"};
590 const int nstrings = sizeof(strings_list) / sizeof(char*);
591 const int nbooleans = sizeof(booleans_list) / sizeof(char*);
592 const int nextra_opts = sizeof(extra_opts) / sizeof(opt_t);
593 const int nsubopts = nstrings + nbooleans + nextra_opts;
594 int i, retval = 0;
596 subopts = calloc(nsubopts + 1, sizeof(opt_t));
597 strings = calloc(nstrings, sizeof(char*));
598 booleans = calloc(nbooleans, sizeof(int));
600 p = subopts;
601 for (i=0; i<nstrings; i++, p++) {
602 p->name = strings_list[i] + 1; // skip '-'
603 p->type = OPT_ARG_MSTRZ;
604 p->valp = &strings[i];
606 for (i=0; i<nbooleans; i++, p++) {
607 p->name = booleans_list[i] + 1;
608 p->type = OPT_ARG_BOOL;
609 p->valp = &booleans[i];
611 memcpy(p, extra_opts, sizeof(extra_opts));
613 retval = subopt_parse(arg, subopts);
615 if (retval == 0 && displayhelp) {
616 helpmsg = strdup(aa_help);
617 for (i=0; i<(signed)strlen(helpmsg); i++)
618 if (helpmsg[i] == '-') helpmsg[i] = ' ';
619 mp_tmsg(MSGT_VO, MSGL_INFO, "\n\nHere are the aalib vo_aa suboptions:\n");
620 mp_msg(MSGT_VO, MSGL_INFO, "%s\n\n", helpmsg);
621 #define VO_AA_AdditionalOptions _("Additional options vo_aa provides:\n" \
622 " help print this help message\n" \
623 " osdcolor set OSD color\n subcolor set subtitle color\n" \
624 " the color parameters are:\n 0 : normal\n" \
625 " 1 : dim\n 2 : bold\n 3 : boldfont\n" \
626 " 4 : reverse\n 5 : special\n\n\n")
628 mp_tmsg(MSGT_VO, MSGL_INFO, VO_AA_AdditionalOptions);
629 retval = -1;
631 if (retval == 0) {
632 pseudoargv[3] = NULL;
633 for (i=0; i<nstrings; i++) {
634 pseudoargc = 3; // inside loop because aalib changes it
635 if (strings[i] != NULL) {
636 pseudoargv[1] = strings_list[i];
637 pseudoargv[2] = strings[i];
638 aa_parseoptions(&aa_defparams, &aa_defrenderparams,
639 &pseudoargc, pseudoargv);
642 pseudoargv[2] = NULL;
643 for (i=0; i<nbooleans; i++) {
644 pseudoargc = 2;
645 if (booleans[i]) pseudoargv[1] = booleans_list[i];
646 else pseudoargv[1] = nobooleans_list[i];
647 aa_parseoptions(&aa_defparams, &aa_defrenderparams,
648 &pseudoargc, pseudoargv);
650 if (osdcolor) aaopt_osdcolor = getcolor(osdcolor);
651 if (subcolor) aaopt_subcolor = getcolor(subcolor);
654 free(subopts);
655 free(booleans);
656 if (strings) {
657 for (i=0; i<nstrings; i++)
658 free(strings[i]);
659 free(strings);
661 free(osdcolor);
662 free(subcolor);
663 free(helpmsg);
664 return retval;
667 static int preinit(const char *arg)
669 char * hidis = NULL;
670 struct stat sbuf;
671 int fd, vt;
672 FILE * fp;
673 char fname[12];
675 if(arg)
677 if (parse_suboptions(arg) != 0)
678 return ENOSYS;
681 /* initializing of aalib */
683 hidis=aa_getfirst(&aa_displayrecommended);
684 if ( hidis==NULL ){
685 /* check /dev/vcsa<vt> */
686 /* check only, if no driver is explicit set */
687 fd = dup (fileno (stderr));
688 fstat (fd, &sbuf);
689 vt = sbuf.st_rdev & 0xff; // hi: major, low: minor
690 close (fd);
691 sprintf (fname, "/dev/vcsa%2.2i", vt);
692 fp = fopen (fname, "w+");
693 if (fp==NULL){
694 fprintf(stderr,"VO: [aa] cannot open %s for writing,"
695 "so we'll not use linux driver\n", fname);
696 aa_recommendlowdisplay("linux");
697 aa_recommendhidisplay("curses");
698 aa_recommendhidisplay("X11");
699 }else fclose(fp);
700 } else aa_recommendhidisplay(hidis);
701 c = aa_autoinit(&aa_defparams);
703 if (c == NULL) {
704 mp_msg(MSGT_VO,MSGL_ERR,"Cannot initialize aalib\n");
705 return VO_ERROR;
707 if (!aa_autoinitkbd(c,0)) {
708 mp_msg(MSGT_VO,MSGL_ERR,"Cannot initialize keyboard\n");
709 aa_close(c);
710 return VO_ERROR;
713 aa_resizehandler(c, (void *)resize);
714 aa_hidecursor(c);
715 p = aa_getrenderparams();
717 if ((strstr(c->driver->name,"Curses")) || (strstr(c->driver->name,"Linux"))){
718 freopen("/dev/null", "w", stderr);
719 /* disable console blanking */
720 printf("\033[9;0]");
723 memset(image,0,3*sizeof(uint8_t));
724 osdmessagetext[0] = '\0';
725 osdx = osdy = 0;
727 return 0;
730 static int control(uint32_t request, void *data)
732 switch (request) {
733 case VOCTRL_QUERY_FORMAT:
734 return query_format(*((uint32_t*)data));
735 case VOCTRL_SET_EQUALIZER: {
736 struct voctrl_set_equalizer_args *args = data;
737 if (strcmp(args->name, "contrast") == 0)
738 p->contrast = (args->value + 100) * 64 / 100;
739 else if (strcmp(args->name, "brightness") == 0)
740 p->bright = (args->value + 100) * 128 / 100;
741 return VO_TRUE;
743 case VOCTRL_GET_EQUALIZER: {
744 struct voctrl_get_equalizer_args *args = data;
746 if (strcmp(args->name, "contrast") == 0)
747 *args->valueptr = (p->contrast - 64) * 100 / 64;
748 else if (strcmp(args->name, "brightness") == 0)
749 *args->valueptr = (p->bright - 128) * 100 / 128;
751 return VO_TRUE;
754 return VO_NOTIMPL;