Remove special error message for -ao alsa1x and alsa9
[mplayer.git] / libvo / vo_aa.c
blob3b3d5f8f50156a8e112a5a84e1dbd410f07903d3
1 /*
2 * MPlayer
3 *
4 * Video driver for AAlib - 1.0
5 *
6 * by Folke Ashberg <folke@ashberg.de>
7 *
8 * Code started: Sun Aug 12 2001
9 * Version 1.0 : Thu Aug 16 2001
13 #include <stdio.h>
14 #include <stdlib.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
19 #include <limits.h>
20 #include <math.h>
21 #include <stdarg.h>
22 #include <time.h>
23 #include <string.h>
24 #include <errno.h>
26 #include "config.h"
27 #include "video_out.h"
28 #include "video_out_internal.h"
29 #include "aspect.h"
30 #include "libswscale/swscale.h"
31 #include "libmpcodecs/vf_scale.h"
32 #include "font_load.h"
33 #include "sub.h"
35 #include "osdep/keycodes.h"
36 #include <aalib.h>
37 #include "subopt-helper.h"
38 #include "help_mp.h"
39 #include "mp_msg.h"
40 #include "mp_fifo.h"
43 #define MESSAGE_DURATION 3
44 #define MESSAGE_SIZE 512
45 #define MESSAGE_DEKO " +++ %s +++ "
47 static const vo_info_t info = {
48 "AAlib",
49 "aa",
50 "Alban Bedel <albeu@free.fr> and Folke Ashberg <folke@ashberg.de>",
54 const LIBVO_EXTERN(aa)
56 /* aa's main context we use */
57 aa_context *c;
58 aa_renderparams *p;
59 static int fast =0;
60 /* used for the sws */
61 static uint8_t * image[3];
62 static int image_stride[3];
64 /* image infos */
65 static int image_format;
66 static int image_width;
67 static int image_height;
68 static int image_x, image_y;
69 static int screen_x, screen_y;
70 static int screen_w, screen_h;
71 static int src_width;
72 static int src_height;
74 /* osd stuff */
75 time_t stoposd = 0;
76 static int showosdmessage = 0;
77 char osdmessagetext[MESSAGE_SIZE];
78 char posbar[MESSAGE_SIZE];
79 static int osdx, osdy;
80 static int osd_text_length = 0;
81 int aaconfigmode=1;
82 font_desc_t* vo_font_save = NULL;
83 static struct SwsContext *sws=NULL;
85 /* configuration */
86 int aaopt_osdcolor = AA_SPECIAL;
87 int aaopt_subcolor = AA_SPECIAL;
89 static unsigned char vo_osd_text[64];
91 static void
92 resize(void){
93 /*
94 * this function is called by aa lib if windows resizes
95 * further during init, because here we have to calculate
96 * a little bit
99 aa_resize(c);
101 aspect_save_screenres(aa_imgwidth(c),aa_imgheight(c));
102 image_height = aa_imgheight(c); //src_height;
103 image_width = aa_imgwidth(c); //src_width;
105 aspect(&image_width,&image_height,A_ZOOM);
107 image_x = (aa_imgwidth(c) - image_width) / 2;
108 image_y = (aa_imgheight(c) - image_height) / 2;
109 screen_w = image_width * aa_scrwidth(c) / aa_imgwidth(c);
110 screen_h = image_height * aa_scrheight(c) / aa_imgheight(c);
111 screen_x = (aa_scrwidth(c) - screen_w) / 2;
112 screen_y = (aa_scrheight(c) - screen_h) / 2;
114 if(sws) sws_freeContext(sws);
115 sws = sws_getContextFromCmdLine(src_width,src_height,image_format,
116 image_width,image_height,IMGFMT_Y8);
118 image[0] = aa_image(c) + image_y * aa_imgwidth(c) + image_x;
119 image[1] = NULL;
120 image[2] = NULL;
122 image_stride[0] = aa_imgwidth(c);
123 image_stride[1] = 0;
124 image_stride[2] = 0;
126 showosdmessage=0;
130 static void
131 osdmessage(int duration, int deko, const char *fmt, ...)
134 * for outputting a centered string at the bottom
135 * of our window for a while
137 va_list ar;
138 char m[MESSAGE_SIZE];
139 unsigned int old_len = strlen(osdmessagetext);
141 va_start(ar, fmt);
142 vsprintf(m, fmt, ar);
143 va_end(ar);
144 if (deko==1) sprintf(osdmessagetext, MESSAGE_DEKO , m);
145 else strcpy(osdmessagetext, m);
147 if(old_len > strlen(osdmessagetext)) {
148 memset(c->textbuffer + osdy * aa_scrwidth(c) + osdx,' ',old_len);
149 memset(c->attrbuffer + osdy * aa_scrwidth(c) + osdx,0,old_len);
151 showosdmessage=1;
152 stoposd = time(NULL) + duration;
153 osdx=(aa_scrwidth(c) / 2) - (strlen(osdmessagetext) / 2 ) ;
154 posbar[0]='\0';
157 static void
158 osdpercent(int duration, int deko, int min, int max, int val, const char * desc, const char * unit)
161 * prints a bar for setting values
163 float step;
164 int where;
165 int i;
168 step=(float)aa_scrwidth(c) /(float)(max-min);
169 where=(val-min)*step;
170 osdmessage(duration,deko,"%s: %i%s",desc, val, unit);
171 posbar[0]='|';
172 posbar[aa_scrwidth(c)-1]='|';
173 for (i=0;i<aa_scrwidth(c);i++){
174 if (i==where) posbar[i]='#';
175 else posbar[i]='-';
177 if (where!=0) posbar[0]='|';
178 if (where!=(aa_scrwidth(c)-1) ) posbar[aa_scrwidth(c)-1]='|';
180 posbar[aa_scrwidth(c)]='\0';
184 static void
185 printosdtext(void)
188 * places the mplayer status osd
190 if (vo_osd_text[0] != 0) {
191 int len;
192 if(vo_osd_text[0] < 32) {
193 len = strlen(sub_osd_names_short[vo_osd_text[0]]) + strlen(vo_osd_text+1) + 2;
194 aa_printf(c, 0, 0 , aaopt_osdcolor, "%s %s ", sub_osd_names_short[vo_osd_text[0]], vo_osd_text+1);
195 } else {
196 len = strlen(vo_osd_text) + 1;
197 aa_printf(c, 0, 0 , aaopt_osdcolor, "%s ",vo_osd_text);
200 if(len < osd_text_length) {
201 memset(c->textbuffer + len,' ',osd_text_length - len);
202 memset(c->attrbuffer + len,0,osd_text_length - len);
204 osd_text_length = len;
209 static void
210 printosdprogbar(void){
211 /* print mplayer osd-progbar */
212 if (vo_osd_progbar_type!=-1){
213 osdpercent(1,1,0,255,vo_osd_progbar_value, sub_osd_names[vo_osd_progbar_type], "");
216 static int
217 config(uint32_t width, uint32_t height, uint32_t d_width,
218 uint32_t d_height, uint32_t flags, char *title,
219 uint32_t format) {
221 * main init
222 * called by mplayer
225 int i;
227 aspect_save_orig(width,height);
228 aspect_save_prescale(d_width,d_height);
230 src_height = height;
231 src_width = width;
232 image_format = format;
234 /* nothing will change its size, be we need some values initialized */
235 resize();
237 /* now init out own 'font' (to use vo_draw_text_sub without edit them) */
238 if(!vo_font_save) vo_font_save = vo_font;
239 if(vo_font == vo_font_save) {
240 vo_font=malloc(sizeof(font_desc_t));//if(!desc) return NULL;
241 memset(vo_font,0,sizeof(font_desc_t));
242 vo_font->pic_a[0]=malloc(sizeof(raw_file));
243 memset(vo_font->pic_a[0],0,sizeof(raw_file));
244 vo_font->pic_b[0]=malloc(sizeof(raw_file));
245 memset(vo_font->pic_b[0],0,sizeof(raw_file));
247 #ifdef CONFIG_FREETYPE
248 vo_font->dynamic = 0;
249 #endif
251 vo_font->spacewidth=1;
252 vo_font->charspace=0;
253 vo_font->height=1;
254 vo_font->pic_a[0]->bmp=malloc(255);
255 vo_font->pic_a[0]->pal=NULL;
256 vo_font->pic_b[0]->bmp=malloc(255);
257 vo_font->pic_b[0]->pal=NULL;
258 vo_font->pic_a[0]->w=1;
259 vo_font->pic_a[0]->h=1;
260 for (i=0; i<255; i++){
261 vo_font->width[i]=1;
262 vo_font->font[i]=0;
263 vo_font->start[i]=i;
264 vo_font->pic_a[0]->bmp[i]=i;
265 vo_font->pic_b[0]->bmp[i]=i;
269 /* say hello */
270 osdmessage(5, 1, "Welcome to ASCII ART MPlayer");
272 mp_msg(MSGT_VO,MSGL_V,"VO: [aa] screendriver: %s\n", c->driver->name);
273 mp_msg(MSGT_VO,MSGL_V,"VO: [aa] keyboarddriver: %s\n", c->kbddriver->name);
275 mp_msg(MSGT_VO,MSGL_INFO,
276 "\n"
277 "Important suboptions\n"
278 "\textended use use all 256 characters\n"
279 "\teight use eight bit ascii\n"
280 "\tdriver set recommended aalib driver (X11,curses,linux)\n"
281 "\thelp to see all options provided by aalib\n"
282 "\n"
283 "AA-MPlayer Keys\n"
284 "\t1 : contrast -\n"
285 "\t2 : contrast +\n"
286 "\t3 : brightness -\n"
287 "\t4 : brightness +\n"
288 "\t5 : fast rendering\n"
289 "\t6 : dithering\n"
290 "\t7 : invert image\n"
291 "\ta : toggles between aa and mplayer control\n"
293 "\n"
294 "All other keys are MPlayer defaults.\n"
299 return 0;
302 static int
303 query_format(uint32_t format) {
305 * ...are we able to... ?
306 * called by mplayer
307 * All input format supported by the sws
309 switch(format){
310 case IMGFMT_YV12:
311 case IMGFMT_I420:
312 case IMGFMT_IYUV:
313 case IMGFMT_IYU2:
314 case IMGFMT_BGR32:
315 case IMGFMT_BGR24:
316 case IMGFMT_BGR16:
317 case IMGFMT_BGR15:
318 case IMGFMT_RGB32:
319 case IMGFMT_RGB24:
320 case IMGFMT_Y8:
321 case IMGFMT_Y800:
322 return VFCAP_CSP_SUPPORTED | VFCAP_SWSCALE | VFCAP_OSD;
324 return 0;
327 static int
328 draw_frame(uint8_t *src[]) {
329 int stride[3] = { 0 , 0 , 0 };
331 switch(image_format) {
332 case IMGFMT_BGR15:
333 case IMGFMT_BGR16:
334 stride[0] = src_width*2;
335 break;
336 case IMGFMT_IYU2:
337 case IMGFMT_BGR24:
338 stride[0] = src_width*3;
339 break;
340 case IMGFMT_BGR32:
341 stride[0] = src_width*4;
342 break;
345 sws_scale_ordered(sws,src,stride,0,src_height,image,image_stride);
347 /* Now 'ASCIInate' the image */
348 if (fast)
349 aa_fastrender(c, screen_x, screen_y, screen_w + screen_x, screen_h + screen_y );
350 else
351 aa_render(c, p,screen_x, screen_y, screen_w + screen_x, screen_h + screen_y );
353 return 0;
356 static int
357 draw_slice(uint8_t *src[], int stride[],
358 int w, int h, int x, int y) {
360 int dx1 = screen_x + (x * screen_w / src_width);
361 int dy1 = screen_y + (y * screen_h / src_height);
362 int dx2 = screen_x + ((x+w) * screen_w / src_width);
363 int dy2 = screen_y + ((y+h) * screen_h / src_height);
365 sws_scale_ordered(sws,src,stride,y,h,image,image_stride);
367 /* Now 'ASCIInate' the image */
368 if (fast)
369 aa_fastrender(c, dx1, dy1, dx2, dy2 );
370 else
371 aa_render(c, p,dx1, dy1, dx2, dy2 );
374 return 0;
377 static void
378 flip_page(void) {
380 /* do we have to put *our* (messages, progbar) osd to aa's txtbuf ? */
381 if (showosdmessage)
383 if (time(NULL)>=stoposd ) {
384 showosdmessage=0;
385 if(*osdmessagetext) {
386 memset(c->textbuffer + osdy * aa_scrwidth(c) + osdx,' ',strlen(osdmessagetext));
387 memset(c->attrbuffer + osdy * aa_scrwidth(c) + osdx ,0,strlen(osdmessagetext));
388 osdmessagetext[0] = '\0';
390 if(*posbar) {
391 memset(c->textbuffer + (osdy+1) * aa_scrwidth(c),' ',strlen(posbar));
392 memset(c->attrbuffer + (osdy+1) * aa_scrwidth(c),0,strlen(posbar));
394 } else {
395 /* update osd */
396 aa_puts(c, osdx, osdy, AA_SPECIAL, osdmessagetext);
397 /* posbar? */
398 if (posbar[0]!='\0')
399 aa_puts(c, 0, osdy + 1, AA_SPECIAL, posbar);
402 /* OSD time & playmode , subtitles */
403 printosdtext();
406 /* print out */
407 aa_flush(c);
410 static void
411 check_events(void) {
413 * any events?
414 * called by show_image and mplayer
416 int key;
417 while ((key=aa_getevent(c,0))!=AA_NONE ){
418 if (key>255){
419 /* some conversations */
420 switch (key) {
421 case AA_UP:
422 mplayer_put_key(KEY_UP);
423 break;
424 case AA_DOWN:
425 mplayer_put_key(KEY_DOWN);
426 break;
427 case AA_LEFT:
428 mplayer_put_key(KEY_LEFT);
429 break;
430 case AA_RIGHT:
431 mplayer_put_key(KEY_RIGHT);
432 break;
433 case AA_ESC:
434 mplayer_put_key(KEY_ESC);
435 break;
436 case 65765:
437 mplayer_put_key(KEY_PAGE_UP);
438 break;
439 case 65766:
440 mplayer_put_key(KEY_PAGE_DOWN);
441 break;
442 default:
443 continue; /* aa lib special key */
444 break;
447 if (key=='a' || key=='A'){
448 aaconfigmode=!aaconfigmode;
449 osdmessage(MESSAGE_DURATION, 1, "aa config mode is now %s",
450 aaconfigmode==1 ? "on. use keys 5-7" : "off");
452 if (aaconfigmode==1) {
453 switch (key) {
454 /* AA image controls */
455 case '5':
456 fast=!fast;
457 osdmessage(MESSAGE_DURATION, 1, "Fast mode is now %s", fast==1 ? "on" : "off");
458 break;
459 case '6':
460 if (p->dither==AA_FLOYD_S){
461 p->dither=AA_NONE;
462 osdmessage(MESSAGE_DURATION, 1, "Dithering: Off");
463 }else if (p->dither==AA_NONE){
464 p->dither=AA_ERRORDISTRIB;
465 osdmessage(MESSAGE_DURATION, 1, "Dithering: Error Distribution");
466 }else if (p->dither==AA_ERRORDISTRIB){
467 p->dither=AA_FLOYD_S;
468 osdmessage(MESSAGE_DURATION, 1, "Dithering: Floyd Steinberg");
470 break;
471 case '7':
472 p->inversion=!p->inversion;
473 osdmessage(MESSAGE_DURATION, 1, "Invert mode is now %s",
474 p->inversion==1 ? "on" : "off");
475 break;
477 default :
478 /* nothing if we're interested in?
479 * the mplayer should handle it!
481 mplayer_put_key(key);
482 break;
484 }// aaconfigmode
485 else mplayer_put_key(key);
489 static void
490 uninit(void) {
492 * THE END
495 if (strstr(c->driver->name,"Curses") || strstr(c->driver->name,"Linux")){
496 freopen("/dev/tty", "w", stderr);
498 if(vo_font_save) {
499 free(vo_font->pic_a[0]->bmp);
500 free(vo_font->pic_a[0]);
501 free(vo_font->pic_b[0]->bmp);
502 free(vo_font->pic_b[0]);
503 free(vo_font);
504 vo_font = vo_font_save;
505 vo_font_save = NULL;
507 aa_close(c);
510 static void draw_alpha(int x,int y, int w,int h, unsigned char* src, unsigned char *srca, int stride){
511 int i,j;
512 for (i = 0; i < h; i++) {
513 for (j = 0; j < w; j++) {
514 if (src[i*stride+j] > 0) {
515 c->textbuffer[x + j + (y+i)*aa_scrwidth(c)] = src[i*stride+j];
516 c->attrbuffer[x + j + (y+i)*aa_scrwidth(c)] = aaopt_subcolor;
522 static void clear_alpha(int x0,int y0, int w,int h) {
523 int l;
525 for(l = 0 ; l < h ; l++) {
526 memset(c->textbuffer + (y0 + l) * aa_scrwidth(c) + x0,' ',w);
527 memset(c->attrbuffer + (y0 + l) * aa_scrwidth(c) + x0,0,w);
532 static void
533 draw_osd(void){
534 char vo_osd_text_save;
535 int vo_osd_progbar_type_save;
537 printosdprogbar();
538 /* let vo_draw_text only write subtitle */
539 vo_osd_text_save = global_osd->osd_text[0];
540 global_osd->osd_text[0] = 0;
541 vo_osd_progbar_type_save=vo_osd_progbar_type;
542 vo_osd_progbar_type=-1;
543 vo_remove_text(aa_scrwidth(c), aa_scrheight(c),clear_alpha);
544 vo_draw_text(aa_scrwidth(c), aa_scrheight(c), draw_alpha);
545 global_osd->osd_text[0] = vo_osd_text_save;
546 vo_osd_progbar_type=vo_osd_progbar_type_save;
549 static int
550 getcolor(char * s){
551 int i;
552 char * rest;
553 if (s==NULL) return -1;
554 i=strtol(s, &rest, 10);
555 if ((rest==NULL || strlen(rest)==0) && i>=0 && i<=5) return i;
556 if (!strcasecmp(s, "normal")) return AA_NORMAL;
557 else if (!strcasecmp(s, "dim")) return AA_DIM;
558 else if (!strcasecmp(s, "bold")) return AA_BOLD;
559 else if (!strcasecmp(s, "boldfont")) return AA_BOLDFONT;
560 else if (!strcasecmp(s, "special")) return AA_SPECIAL;
561 else return -1;
564 static int parse_suboptions(const char *arg) {
565 char *pseudoargv[4], *osdcolor = NULL, *subcolor = NULL, **strings,
566 *helpmsg = NULL;
567 int pseudoargc, displayhelp = 0, *booleans;
568 opt_t extra_opts[] = {
569 {"osdcolor", OPT_ARG_MSTRZ, &osdcolor, NULL, 0},
570 {"subcolor", OPT_ARG_MSTRZ, &subcolor, NULL, 0},
571 {"help", OPT_ARG_BOOL, &displayhelp, NULL, 0} };
572 opt_t *subopts = NULL, *p;
573 char *strings_list[] = {"-driver", "-kbddriver", "-mousedriver", "-font",
574 "-width", "-height", "-minwidth", "-minheight", "-maxwidth",
575 "-maxheight", "-recwidth", "-recheight", "-bright", "-contrast",
576 "-gamma", "-dimmul", "-boldmul", "-random" };
577 char *booleans_list[] = {"-dim", "-bold", "-reverse", "-normal",
578 "-boldfont", "-inverse", "-extended", "-eight", "-dither",
579 "-floyd_steinberg", "-error_distribution"};
580 char *nobooleans_list[] = {"-nodim", "-nobold", "-noreverse", "-nonormal",
581 "-noboldfont", "-noinverse", "-noextended", "-noeight", "-nodither",
582 "-nofloyd_steinberg", "-noerror_distribution"};
583 const int nstrings = sizeof(strings_list) / sizeof(char*);
584 const int nbooleans = sizeof(booleans_list) / sizeof(char*);
585 const int nextra_opts = sizeof(extra_opts) / sizeof(opt_t);
586 const int nsubopts = nstrings + nbooleans + nextra_opts;
587 int i, retval = 0;
589 subopts = calloc(nsubopts + 1, sizeof(opt_t));
590 strings = calloc(nstrings, sizeof(char*));
591 booleans = calloc(nbooleans, sizeof(int));
593 p = subopts;
594 for (i=0; i<nstrings; i++, p++) {
595 p->name = strings_list[i] + 1; // skip '-'
596 p->type = OPT_ARG_MSTRZ;
597 p->valp = &strings[i];
599 for (i=0; i<nbooleans; i++, p++) {
600 p->name = booleans_list[i] + 1;
601 p->type = OPT_ARG_BOOL;
602 p->valp = &booleans[i];
604 memcpy(p, extra_opts, sizeof(extra_opts));
606 retval = subopt_parse(arg, subopts);
608 if (retval == 0 && displayhelp) {
609 helpmsg = strdup(aa_help);
610 for (i=0; i<(signed)strlen(helpmsg); i++)
611 if (helpmsg[i] == '-') helpmsg[i] = ' ';
612 mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_HelpHeader);
613 mp_msg(MSGT_VO, MSGL_INFO, "%s\n\n", helpmsg);
614 mp_msg(MSGT_VO, MSGL_INFO, MSGTR_VO_AA_AdditionalOptions);
615 retval = -1;
617 if (retval == 0) {
618 pseudoargv[3] = NULL;
619 for (i=0; i<nstrings; i++) {
620 pseudoargc = 3; // inside loop because aalib changes it
621 if (strings[i] != NULL) {
622 pseudoargv[1] = strings_list[i];
623 pseudoargv[2] = strings[i];
624 aa_parseoptions(&aa_defparams, &aa_defrenderparams,
625 &pseudoargc, pseudoargv);
628 pseudoargv[2] = NULL;
629 for (i=0; i<nbooleans; i++) {
630 pseudoargc = 2;
631 if (booleans[i]) pseudoargv[1] = booleans_list[i];
632 else pseudoargv[1] = nobooleans_list[i];
633 aa_parseoptions(&aa_defparams, &aa_defrenderparams,
634 &pseudoargc, pseudoargv);
636 if (osdcolor) aaopt_osdcolor = getcolor(osdcolor);
637 if (subcolor) aaopt_subcolor = getcolor(subcolor);
640 if (subopts) free(subopts);
641 if (booleans) free(booleans);
642 if (strings) {
643 for (i=0; i<nstrings; i++)
644 if (strings[i])
645 free(strings[i]);
646 free(strings);
648 if (osdcolor) free(osdcolor);
649 if (subcolor) free(subcolor);
650 if (helpmsg) free(helpmsg);
651 return retval;
654 static int preinit(const char *arg)
656 char * hidis = NULL;
657 struct stat sbuf;
658 int fd, vt, major, minor;
659 FILE * fp;
660 char fname[12];
662 if(arg)
664 if (parse_suboptions(arg) != 0)
665 return ENOSYS;
668 /* initializing of aalib */
670 hidis=aa_getfirst(&aa_displayrecommended);
671 if ( hidis==NULL ){
672 /* check /dev/vcsa<vt> */
673 /* check only, if no driver is explicit set */
674 fd = dup (fileno (stderr));
675 fstat (fd, &sbuf);
676 major = sbuf.st_rdev >> 8;
677 vt = minor = sbuf.st_rdev & 0xff;
678 close (fd);
679 sprintf (fname, "/dev/vcsa%2.2i", vt);
680 fp = fopen (fname, "w+");
681 if (fp==NULL){
682 fprintf(stderr,"VO: [aa] cannot open %s for writing,"
683 "so we'll not use linux driver\n", fname);
684 aa_recommendlowdisplay("linux");
685 aa_recommendhidisplay("curses");
686 aa_recommendhidisplay("X11");
687 }else fclose(fp);
688 } else aa_recommendhidisplay(hidis);
689 c = aa_autoinit(&aa_defparams);
691 if (c == NULL) {
692 mp_msg(MSGT_VO,MSGL_ERR,"Cannot initialize aalib\n");
693 return VO_ERROR;
695 if (!aa_autoinitkbd(c,0)) {
696 mp_msg(MSGT_VO,MSGL_ERR,"Cannot initialize keyboard\n");
697 aa_close(c);
698 return VO_ERROR;
701 aa_resizehandler(c, (void *)resize);
702 aa_hidecursor(c);
703 p = aa_getrenderparams();
705 if ((strstr(c->driver->name,"Curses")) || (strstr(c->driver->name,"Linux"))){
706 freopen("/dev/null", "w", stderr);
707 /* disable console blanking */
708 printf("\033[9;0]");
711 memset(image,0,3*sizeof(uint8_t));
712 osdmessagetext[0] = '\0';
713 osdx = osdy = 0;
715 return 0;
718 static int control(uint32_t request, void *data)
720 switch (request) {
721 case VOCTRL_QUERY_FORMAT:
722 return query_format(*((uint32_t*)data));
723 case VOCTRL_SET_EQUALIZER: {
724 struct voctrl_set_equalizer_args *args = data;
725 if (strcmp(args->name, "contrast") == 0)
726 p->contrast = (args->value + 100) * 64 / 100;
727 else if (strcmp(args->name, "brightness") == 0)
728 p->bright = (args->value + 100) * 128 / 100;
729 return VO_TRUE;
731 case VOCTRL_GET_EQUALIZER: {
732 struct voctrl_get_equalizer_args *args = data;
734 if (strcmp(args->name, "contrast") == 0)
735 *args->valueptr = (p->contrast - 64) * 100 / 64;
736 else if (strcmp(args->name, "brightness") == 0)
737 *args->valueptr = (p->bright - 128) * 100 / 128;
739 return VO_TRUE;
742 return VO_NOTIMPL;