mirror of https://github.com/mpv-player/mpv
Added cool aalib vo driver.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1512 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
1ef79e9f00
commit
76eadb38e0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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){
|
||||
}
|
Loading…
Reference in New Issue