From 76eadb38e027f545715c1b755b7ea35110ac71b4 Mon Sep 17 00:00:00 2001 From: atmos4 Date: Tue, 14 Aug 2001 12:30:56 +0000 Subject: [PATCH] Added cool aalib vo driver. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1512 b3059339-0415-0410-9bf9-f77b7e298cf2 --- configure | 28 ++- libvo/video_out.c | 5 + libvo/vo_aa.c | 514 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+), 1 deletion(-) create mode 100644 libvo/vo_aa.c diff --git a/configure b/configure index 627eadb3c2..4eb7f0aa95 100755 --- a/configure +++ b/configure @@ -135,6 +135,7 @@ params: --enable-dga build with DGA support [autodetect] --enable-svga build with SVGAlib support [autodetect] --enable-sdl build with SDL render support [autodetect] + --enable-aa build with AAlib render support [autodetect] --enable-ggi build with GGI render support [autodetect] --enable-mga build with mga_vid support [autodetect, if /dev/mga_vid is available] @@ -439,6 +440,7 @@ _sse=no _mga=no _gl=no _sdl=no +_aa=no _ggi=no _xv=no _vm=no @@ -467,6 +469,7 @@ _y=1 _gllib= _sdllib= _sdlcflags= +_aalib= _ggilib= _xvlib= _x11lib= @@ -751,6 +754,12 @@ if $_cc `$_sdlconfig --cflags` $TMPC -o $TMPO `$_sdlconfig --libs` > /dev/null 2 fi fi + +_aa=no +if test -s "/usr/local/lib/libaa.a" || test -s "/usr/lib/libaa.a" ; then + _aa=yes +fi + # Atmosfear: added libcss autodetect _css=no if test -s "/usr/local/lib/libcss.so" ; then @@ -1021,6 +1030,9 @@ for ac_option do --enable-sdl) _sdl=yes ;; + --enable-aa) + _aa=yes + ;; --enable-ggi) _ggi=yes ;; @@ -1119,6 +1131,9 @@ for ac_option do --disable-sdl) _sdl=no ;; + --disable-sdl) + _aa=no + ;; --disable-ggi) _ggi=no ;; @@ -1378,6 +1393,7 @@ echo "Checking for X11 headers ... $_x11incdir" echo "Checking mga_vid device ... $_mga" echo "Checking for xmga ... $_xmga" echo "Checking for SDL ... $_sdl" +echo "Checking for AA ... $_aa" echo "Checking for GGI ... $_ggi" echo "Checking for OpenGL ... $_gl" echo "Checking for Xv ... $_xv" @@ -1662,6 +1678,15 @@ fi _vosrc='' #_aosrc='' +if [ $_aa = yes ]; then + _aa='#define HAVE_AA' + _vosrc=$_vosrc' vo_aa.c' + _aalib='-laa' +else + _aa='#undef HAVE_AA' + _aalib='' +fi + if [ $_png = yes ]; then _png='#define HAVE_PNG' _vosrc=$_vosrc' vo_png.c' @@ -1812,7 +1837,7 @@ WIN32_PATH=-DWIN32_PATH=\\"$_win32libdir\\" X11_INC=$_x11incdir X11DIR=$_x11libdir -X_LIBS=$_x11libdir $_extralibdir $_gllib $_ggilib $_sdllib $_dgalib $_x11lib $_xvlib $_vmlib $_svgalib $_libpng $_socklib +X_LIBS=$_x11libdir $_extralibdir $_gllib $_ggilib $_sdllib $_dgalib $_x11lib $_xvlib $_vmlib $_svgalib $_libpng $_socklib $_aalib TERMCAP_LIB=$_libtermcap XMM_LIBS = $_xmmplibs @@ -2015,6 +2040,7 @@ $_syncfb $_fbdev $_svga $_have_xdpms +$_aa #if defined(HAVE_GL)||defined(HAVE_X11)||defined(HAVE_XV) #define X11_FULLSCREEN diff --git a/libvo/video_out.c b/libvo/video_out.c index 939d3df8bf..bd9234b2fb 100644 --- a/libvo/video_out.c +++ b/libvo/video_out.c @@ -66,6 +66,7 @@ extern vo_functions_t video_out_fbdev; extern vo_functions_t video_out_svga; extern vo_functions_t video_out_png; extern vo_functions_t video_out_ggi; +extern vo_functions_t video_out_aa; vo_functions_t* video_out_drivers[] = { @@ -106,6 +107,10 @@ vo_functions_t* video_out_drivers[] = #ifdef HAVE_SVGALIB &video_out_svga, #endif +#ifdef HAVE_AA + &video_out_aa, +#endif + #ifdef HAVE_PNG &video_out_png, #endif 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 + * + * Code started: Sun Aug 12 2001 + * + */ + +#include +#include + + +#include +#include +#include +#include +#include + +#include "config.h" +#include "video_out.h" +#include "video_out_internal.h" +#include "yuv2rgb.h" +#include "sub.h" + +#include "linux/keycodes.h" +#include + +#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 ", + "" + }; + +/* 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;idriver->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){ +}