diff options
author | atmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-08-14 12:30:56 +0000 |
---|---|---|
committer | atmos4 <atmos4@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2001-08-14 12:30:56 +0000 |
commit | 76eadb38e027f545715c1b755b7ea35110ac71b4 (patch) | |
tree | 509a2b4872b6befdfccb900b7d7aaf78e990f36d /libvo/vo_aa.c | |
parent | 1ef79e9f0007c34373df62e73ff3825ca9e91e5d (diff) | |
download | mpv-76eadb38e027f545715c1b755b7ea35110ac71b4.tar.bz2 mpv-76eadb38e027f545715c1b755b7ea35110ac71b4.tar.xz |
Added cool aalib vo driver.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1512 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo/vo_aa.c')
-rw-r--r-- | libvo/vo_aa.c | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/libvo/vo_aa.c b/libvo/vo_aa.c new file mode 100644 index 0000000000..ed9c0092c7 --- /dev/null +++ b/libvo/vo_aa.c @@ -0,0 +1,514 @@ +/* + * MPlayer + * + * Video driver for AAlib - alpha version + * + * by Folke Ashberg <folke@ashberg.de> + * + * Code started: Sun Aug 12 2001 + * + */ + +#include <stdio.h> +#include <stdlib.h> + + +#include <limits.h> +#include <math.h> +#include <stdarg.h> +#include <time.h> +#include <string.h> + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" +#include "yuv2rgb.h" +#include "sub.h" + +#include "linux/keycodes.h" +#include <aalib.h> + +#define RGB 0 +#define BGR 1 + +#define DO_INC(val,max,step) if (val + step <=max) val+=step; else val=max; +#define DO_DEC(val,min,step) if (val - step >=min) val-=step; else val=min; + +#define MESSAGE_DURATION 3 +#define MESSAGE_SIZE 512 +#define MESSAGE_DEKO " +++ %s +++ " + + + +LIBVO_EXTERN(aa) + + static vo_info_t vo_info = { + "AAlib", + "aa", + "Folke Ashberg <folke@ashberg.de>", + "" + }; + +/* aa's main context we use */ +aa_context *c; +aa_renderparams *p; +static int fast =0; +/* used for YV12 streams for the converted RGB image */ +uint8_t * convertbuf=NULL; + +/* image infos */ +static int image_format, bpp=24; +static int image_width; +static int image_height; +static int bppmul; + +/* osd stuff */ +time_t stoposd = 0; +static int showosd = 0; +char osdtext[MESSAGE_SIZE]; +char posbar[MESSAGE_SIZE]; +static int osdx, osdy; + +/* for resizing/scaling */ +static int *stx; +static int *sty; +double accum; + +/* our version of the playmodes :) */ +static char * osdmodes[] ={ ">", "\"", "#", "-" , "+" }; + +extern void mplayer_put_key(int code); + + +void +resize(void){ + /* + * this function is called by aa lib if windows resizes + * further during init, because here we have to calculate + * a little bit + */ + + int i; + aa_resize(c); + + showosd=0; + osdy=aa_scrheight(c) - ( aa_scrheight(c)/10 ); + + /* now calculating the needed values for resizing */ + + /* We only need to use floating point to determine the correct + stretch vector for one line's worth. */ + stx = (int *) malloc(sizeof(int) * image_width); + sty = (int *) malloc(sizeof(int) * image_height); + accum = 0; + for (i=0; (i < image_width); i++) { + int got; + accum += (double)aa_imgwidth(c)/(double)image_width; + got = (int) floor(accum); + stx[i] = got; + accum -= got; + } + accum = 0; + for (i=0; (i < image_height); i++) { + int got; + accum += (double)aa_imgheight(c)/(double)image_height; + got = (int) floor(accum); + sty[i] = got; + accum -= got; + } +} + +void +osdmessage(int duration, int deko, char *fmt, ...) +{ + /* + * for outputting a centered string at the bottom + * of our window for a while + */ + va_list ar; + char m[MESSAGE_SIZE]; + va_start(ar, fmt); + vsprintf(m, fmt, ar); + va_end(ar); + if (deko==1) sprintf(osdtext, MESSAGE_DEKO , m); + else strcpy(osdtext, m); + showosd=1; + stoposd = time(NULL) + duration; + osdx=(aa_scrwidth(c) / 2) - (strlen(osdtext) / 2 ) ; + posbar[0]='\0'; +} + +void +osdpercent(int duration, int deko, int min, int max, int val, char * desc, char * unit) +{ + /* + * prints a bar for setting values + */ + float step; + int where; + char m[MESSAGE_SIZE]; + int i; + step=(float)aa_scrwidth(c) /(float)(max-min); + where=(val-min)*step; + sprintf(m,"%s: %i%s",desc, val, unit); + if (deko==1) sprintf(osdtext, MESSAGE_DEKO , m); + else strcpy(osdtext, m); + posbar[0]='|'; + posbar[aa_scrwidth(c)-1]='|'; + for (i=0;i<aa_scrwidth(c);i++){ + if (i==where) posbar[i]='#'; + else posbar[i]='-'; + } + if (where!=0) posbar[0]='|'; + if (where!=(aa_scrwidth(c)-1) ) posbar[aa_scrwidth(c)-1]='|'; + /* snipp */ + posbar[aa_scrwidth(c)]='\0'; + showosd=1; + stoposd = time(NULL) + duration; + osdx=(aa_scrwidth(c) / 2) - (strlen(osdtext) / 2 ) ; +} + +static uint32_t +init(uint32_t width, uint32_t height, uint32_t d_width, + uint32_t d_height, uint32_t fullscreen, char *title, + uint32_t format) { + /* + * main init + * called by mplayer + */ + + switch(format) { + case IMGFMT_BGR24: + bpp = 24; + break; + case IMGFMT_RGB24: + bpp = 24; + break; + case IMGFMT_YV12: + bpp = 24; + /* YUV ? then initialize what we will need */ + convertbuf=malloc(width*height*3); + yuv2rgb_init(24,MODE_BGR); + break; + default: + return 1; + } + bppmul=bpp/8; + + /* initializing of aalib */ + aa_recommendhidisplay("curses"); + aa_recommendhidisplay("X11"); + aa_recommendlowdisplay("linux"); + + + c = aa_autoinit(&aa_defparams); + aa_resizehandler(c, (void *)resize); + + if (c == NULL) { + printf("Can not intialize aalib\n"); + return 0; + } + if (!aa_autoinitkbd(c,0)) { + printf("Can not intialize keyboard\n"); + aa_close(c); + return 0; + } + /* + if (!aa_autoinitmouse(c,0)) { + printf("Can not intialize mouse\n"); + aa_close(c); + return 0; + } + */ + aa_hidecursor(c); + p = aa_getrenderparams(); + + if ((strstr(c->driver->name,"curses")) || (strstr(c->driver->name,"libux"))) + freopen("/dev/null", "w", stderr); + + image_height = height; + image_width = width; + image_format = format; + + /* needed by prepare_image */ + stx = (int *) malloc(sizeof(int) * image_width); + sty = (int *) malloc(sizeof(int) * image_height); + + /* nothing will change its size, be we need some values initialized */ + resize(); + + /* say hello */ + osdmessage(5, 1, "Welcome to ASCII ARTS MPlayer"); + + printf("VO: screendriver: %s\n", c->driver->name); + printf("VO: keyboarddriver: %s\n", c->kbddriver->name); + //printf("VO: mousedriver: %s\n", c->mousedriver->name); + + printf( + "\n" + "\tAA-MPlayer Keys:\n" + "\t1 : fast rendering\n" + "\t2 : dithering\n" + "\t3 : invert image\n" + "\t4 : contrast -\n" + "\t5 : contrast +\n" + "\t6 : brightness -\n" + "\t7 : brightness +\n" + "\n" + "All other keys are MPlayer standart\n" + + + ); + + return 0; +} + +static uint32_t +query_format(uint32_t format) { + /* + * ...are we able to... ? + * called by mplayer + */ + switch(format){ + case IMGFMT_YV12: + case IMGFMT_RGB|24: + case IMGFMT_BGR|24: + return 1; + } + return 0; +} + +static const vo_info_t* +get_info(void) { + /* who i am? */ + return (&vo_info); +} + +int +prepare_image(uint8_t *data, int inx, int iny, int outx, int outy){ + /* + * copies an RGB-Image to the aalib imagebuffer + * also scaling an grayscaling is done here + * show_image calls us + */ + + int value; + int x, y; + int tox, toy; + int ydest; + int i; + int pos; + + toy = 0; + for (y=0; (y < (0 + iny)); y++) { + for (ydest=0; (ydest < sty[y-0]); ydest++) { + tox = 0; + for (x=0; (x < (0 + inx)); x++) { + if (!stx[x - 0]) { + continue; + } + pos=3*(inx*y)+(3*x); + value=(data[pos]+data[pos+1]+data[pos+2])/3; + for (i=0; (i < stx[x - 0]); i++) { + //printf("ToX: %i, ToY %i, i=%i, stx=%i, x=%i\n", tox, toy, i, stx[x], x); + c->imagebuffer[(toy*outx) +tox]=value; + tox++; + } + } + toy++; + } + } + return 0; +} + +void +printosd() +{ + /* + * places the mplayer status osd + */ + if (vo_osd_text){ + if (vo_osd_text[0]-1<=5) + aa_puts(c, 0,0, AA_BOLDFONT, osdmodes[vo_osd_text[0]-1]); + else aa_puts(c, 0,0, AA_BOLDFONT, "?"); + aa_puts(c,1,0, AA_BOLDFONT, vo_osd_text+1); + aa_puts(c,strlen(vo_osd_text),0, AA_BOLDFONT, " "); + } +} + +void +show_image(uint8_t * src){ + /* + * every frame (flip_page/draw_frame) we will be called + */ + + /* events? */ + check_events(); + + /* RGB->gray , scaling/resizing, stores data in aalib imgbuf */ + prepare_image( src, image_width, image_height, + aa_imgwidth(c), aa_imgheight(c) ); + + /* Now 'ASCIInate' the image */ + if (fast) + aa_fastrender(c, 0, 0, aa_scrwidth(c), aa_scrheight(c) ); + else + aa_render(c, p, 0, 0, aa_scrwidth(c), aa_scrheight(c)); + + /* do we have to put our osd to aa's txtbuf ? */ + if (showosd) + { + if (time(NULL)>=stoposd ) showosd=0; + /* update osd */ + aa_puts(c, osdx, osdy, AA_SPECIAL, osdtext); + /* posbar? */ + if (posbar[0]!='\0') + aa_puts(c, 0, osdy + 1, AA_SPECIAL, posbar); + } + /* and the real OSD, but only the time & playmode */ + printosd(); + + /* print out */ + aa_flush(c); +} + +static uint32_t +draw_frame(uint8_t *src[]) { + /* + * RGB-Video's Only + * src[0] is handled bu prepare_image + */ + show_image(src[0]); + return 0; +} + +static uint32_t +draw_slice(uint8_t *src[], int stride[], + int w, int h, int x, int y) { + /* + * for MPGEGS YV12 + * draw a rectangle converted to RGB to a + * temporary RGB Buffer + */ + uint8_t *dst; + + dst = convertbuf+(image_width * y + x) * 3; + yuv2rgb(dst,src[0],src[1],src[2],w,h,image_width*3,stride[0],stride[1]); + + return 0; +} + +static void +flip_page(void) { + /* + * wow! another ready Image, so draw it ! + */ + if(image_format == IMGFMT_YV12) + show_image(convertbuf); +} + +static void +check_events(void) { + /* + * any events? + * called by show_image and mplayer + */ + int key; + while ((key=aa_getevent(c,0))!=AA_NONE ){ + if (key>255){ + /* some conversations */ + switch (key) { + case AA_UP: + mplayer_put_key(KEY_UP); + break; + case AA_DOWN: + mplayer_put_key(KEY_DOWN); + break; + case AA_LEFT: + mplayer_put_key(KEY_LEFT); + break; + case AA_RIGHT: + mplayer_put_key(KEY_RIGHT); + break; + case AA_ESC: + mplayer_put_key(KEY_ESC); + break; + case 65765: + mplayer_put_key(KEY_PAGE_UP); + break; + case 65766: + mplayer_put_key(KEY_PAGE_DOWN); + break; + default: + continue; /* aa lib special key */ + break; + } + } + switch (key) { + /* AA image controls */ + case '1': + fast=!fast; + osdmessage(MESSAGE_DURATION, 1, "Fast mode is now %s", fast==1 ? "on" : "off"); + break; + case '2': + if (p->dither==AA_FLOYD_S){ + p->dither=AA_NONE; + osdmessage(MESSAGE_DURATION, 1, "Dithering: Off"); + }else if (p->dither==AA_NONE){ + p->dither=AA_ERRORDISTRIB; + osdmessage(MESSAGE_DURATION, 1, "Dithering: Error Distribution"); + }else if (p->dither==AA_ERRORDISTRIB){ + p->dither=AA_FLOYD_S; + osdmessage(MESSAGE_DURATION, 1, "Dithering: Floyd Steinberg"); + } + break; + case '3': + p->inversion=!p->inversion; + osdmessage(MESSAGE_DURATION, 1, "Invert mode is now %s", + p->inversion==1 ? "on" : "off"); + break; + + case '4': /* contrast */ + DO_DEC(p->contrast,0,1); + osdpercent(MESSAGE_DURATION, 1, 0, 255, p->contrast, "AA-Contrast", ""); + + break; + case '5': /* contrast */ + DO_INC(p->contrast,255,1); + osdpercent(MESSAGE_DURATION, 1, 0, 255, p->contrast, "AA-Contrast", ""); + break; + case '6': /* brightness */ + DO_DEC(p->bright,0,1); + osdpercent(MESSAGE_DURATION, 1, 0, 255, p->bright, "AA-Brightnes", ""); + break; + case '7': /* brightness */ + DO_INC(p->bright,255,1); + osdpercent(MESSAGE_DURATION, 1, 0, 255, p->bright, "AA-Brightnes", ""); + break; + + default : + /* nothing if we're interested in? + * the mplayer should handle it! + */ + mplayer_put_key(key); + break; + } + } +} + +static void +uninit(void) { + /* + * THE END + */ + aa_close(c); + free(stx); + free(sty); + if (convertbuf!=NULL) free(convertbuf); + if (strstr(c->driver->name,"curses") || strstr(c->driver->name,"libux")) + freopen("/dev/tty", "w", stderr); +} + +static void +draw_osd(void){ +} |