Mercurial > mplayer.hg
changeset 5679:30f196ff3bec
This patch replaces vo_svga.c with an improved version that does not use
vgagl library, supports direct rendering and page flipping, and is
generally a lot faster. - by Matan Ziv-Av <matan@svgalib.org>
author | arpi |
---|---|
date | Thu, 18 Apr 2002 15:41:33 +0000 |
parents | 8849904de1db |
children | 7bd2883ee0ec |
files | libvo/vo_svga.c |
diffstat | 1 files changed, 320 insertions(+), 232 deletions(-) [+] |
line wrap: on
line diff
--- a/libvo/vo_svga.c Thu Apr 18 15:32:30 2002 +0000 +++ b/libvo/vo_svga.c Thu Apr 18 15:41:33 2002 +0000 @@ -1,16 +1,15 @@ /* - Video driver for SVGAlib - alpha, slow + Video driver for SVGAlib by Zoltan Mark Vician <se7en@sch.bme.hu> Code started: Mon Apr 1 23:25:47 2001 - - Uses HW acceleration if your card is supported by SVGAlib. + + Some changes by Matan Ziv-Av <matan@svgalib.org> */ #include <stdio.h> #include <stdlib.h> #include <vga.h> -#include <vgagl.h> #include <limits.h> @@ -21,30 +20,32 @@ #include "sub.h" #include "../postproc/rgb2rgb.h" +#include "../mp_msg.h" +//#include "../mp_image.h" + +extern int vo_directrendering; extern int vo_dbpp; extern int verbose; -LIBVO_EXTERN(svga) - -static vo_info_t vo_info = { - "SVGAlib", - "svga", - "Zoltan Mark Vician <se7en@sch.bme.hu>", - "" -}; - -// SVGAlib definitions +static uint32_t query_format(uint32_t format); +static int checksupportedmodes(); +static void putbox(int x, int y, int w, int h, uint8_t *buf,int prog); +static void fillbox(int x, int y, int w, int h, uint32_t c); +static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, + unsigned char *srca, int stride); +static uint32_t get_image(mp_image_t *mpi); -GraphicsContext *screen; -GraphicsContext *virt; +static uint8_t *yuvbuf = NULL, *bppbuf = NULL; +static uint8_t *GRAPH_MEM; -static uint8_t *scalebuf = NULL, *yuvbuf = NULL, *bppbuf = NULL; +static int BYTESPERPIXEL, WIDTH, HEIGHT, LINEWIDTH; +static int frame, maxframes, oldmethod=0; +static uint32_t pformat; static uint32_t orig_w, orig_h, maxw, maxh; // Width, height -static float scaling = 1.0; -static uint32_t x_pos, y_pos; // Position +static uint8_t buf0[8192]; +static uint8_t *buffer; -// SVGAlib - list of detected modes typedef struct vga_modelist_s { uint16_t modenum; vga_modeinfo modeinfo; @@ -65,60 +66,43 @@ static uint8_t checked = 0; -static uint32_t add_mode(uint16_t mode, vga_modeinfo minfo) { - vga_modelist_t *list; +static uint32_t x_pos, y_pos; + +LIBVO_EXTERN(svga) - if (modelist == NULL) { - modelist = (vga_modelist_t *) malloc(sizeof(vga_modelist_t)); - if (modelist == NULL) { - printf("vo_svga: add_mode() failed. Not enough memory for modelist."); - return(1); // error - } - modelist->modenum = mode; - modelist->modeinfo = minfo; - modelist->next = NULL; +static vo_info_t vo_info = { + "SVGAlib", + "svga", + "Zoltan Mark Vician <se7en@sch.bme.hu>", + "" +}; + +static uint32_t preinit(const char *arg) +{ + int i; + + for(i=0;i<8192;i++) buf0[i]=0; + + if(vo_directrendering) { + maxframes=0; } else { - list = modelist; - while (list->next != NULL) - list = list->next; - list->next = (vga_modelist_t *) malloc(sizeof(vga_modelist_t)); - if (list->next == NULL) { - printf("vo_svga: add_mode() failed. Not enough memory for modelist."); - return(1); // error - } - list = list->next; - list->modenum = mode; - list->modeinfo = minfo; - list->next = NULL; - } - return (0); + maxframes=1; + } + +printf("vo_svga: preinit - maxframes=%i\n",maxframes); + + return 0; } -static int checksupportedmodes() { - uint16_t i, max; - vga_modeinfo *minfo; - - checked = 1; - vga_init(); - vga_disabledriverreport(); - max = vga_lastmodenumber(); - for (i = 1; i < max; i++) - if (vga_hasmode(i) > 0) { - minfo = vga_getmodeinfo(i); - switch (minfo->colors) { - case 32768: bpp_avail |= BPP_15; break; - case 65536: bpp_avail |= BPP_16; break; - } - switch (minfo->bytesperpixel) { - case 3: bpp_avail |= BPP_24; break; - case 4: bpp_avail |= BPP_32; break; - } - if (verbose >= 2) - printf("vo_svga: Mode found: %s\n",vga_getmodename(i)); - if (add_mode(i, *minfo)) - return(1); - } - return(0); +static uint32_t control(uint32_t request, void *data, ...) +{ + switch (request) { + case VOCTRL_QUERY_FORMAT: + return query_format(*((uint32_t*)data)); + case VOCTRL_GET_IMAGE: + return get_image(data); + } + return VO_NOTIMPL; } static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, @@ -130,7 +114,7 @@ uint8_t res_widescr, vid_widescr = (((req_w*1.0)/req_h) > (4.0/3)) ? 1 : 0; uint16_t buf_w = USHRT_MAX, buf_h = USHRT_MAX; vga_modelist_t *list = modelist; - + if (!checked) { if (checksupportedmodes()) // Looking for available video modes return(1); @@ -235,15 +219,19 @@ if ((list->modeinfo.width >= req_w) && (list->modeinfo.height >= req_h)) { if (verbose) { switch (list->modeinfo.colors) { - case 32768: printf("vo_svga: vid_mode: %d, %dx%d 15bpp\n",list->modenum,list->modeinfo.width,list->modeinfo.height); + case 32768: printf("vo_svga: vid_mode: %d, %dx%d 15bpp\n", + list->modenum,list->modeinfo.width,list->modeinfo.height); break; - case 65536: printf("vo_svga: vid_mode: %d, %dx%d 16bpp\n",list->modenum,list->modeinfo.width,list->modeinfo.height); + case 65536: printf("vo_svga: vid_mode: %d, %dx%d 16bpp\n", + list->modenum,list->modeinfo.width,list->modeinfo.height); break; } switch (list->modeinfo.bytesperpixel) { - case 3: printf("vo_svga: vid_mode: %d, %dx%d 24bpp\n",list->modenum,list->modeinfo.width,list->modeinfo.height); + case 3: printf("vo_svga: vid_mode: %d, %dx%d 24bpp\n", + list->modenum,list->modeinfo.width,list->modeinfo.height); break; - case 4: printf("vo_svga: vid_mode: %d, %dx%d 32bpp\n",list->modenum,list->modeinfo.width,list->modeinfo.height); + case 4: printf("vo_svga: vid_mode: %d, %dx%d 32bpp\n", + list->modenum,list->modeinfo.width,list->modeinfo.height); break; } } @@ -284,8 +272,16 @@ } list = list->next; } + + if((vo_subdevice) && (strlen(vo_subdevice)>2)) { + if(!strncmp(vo_subdevice,"old",3)) { + oldmethod=1; + vo_subdevice+=3; + if( *vo_subdevice == ',' ) vo_subdevice++; + } + } - if(vo_subdevice) { + if((vo_subdevice) && *vo_subdevice) { int vm; vm=vga_getmodenumber(vo_subdevice); list=modelist; @@ -326,24 +322,26 @@ uninit(); return(1); // error } + + WIDTH=vga_getxdim(); + HEIGHT=vga_getydim(); + BYTESPERPIXEL=(bpp+1)>>3; + LINEWIDTH=WIDTH*BYTESPERPIXEL; vga_setlinearaddressing(); - if (gl_setcontextvga(vid_mode)) { - printf("vo_svga: gl_setcontextvga(%d) failed.\n",vid_mode); - uninit(); - return(1); // error + if(oldmethod) { + buffer=malloc(HEIGHT*LINEWIDTH); + maxframes=0; } - screen = gl_allocatecontext(); - gl_getcontext(screen); - if (gl_setcontextvgavirtual(vid_mode)) { - printf("vo_svga: gl_setcontextvgavirtual(%d) failed.\n",vid_mode); - uninit(); - return(1); // error - } - virt = gl_allocatecontext(); - gl_getcontext(virt); - gl_setcontext(virt); - gl_clearscreen(0); + vga_claimvideomemory((maxframes+1)*HEIGHT*LINEWIDTH); + GRAPH_MEM=vga_getgraphmem(); + frame=0; + fillbox(0,0,WIDTH,HEIGHT*(maxframes+1),0); + orig_w = width; + orig_h = height; + maxw = orig_w; + maxh = orig_h; + if (bpp_conv) { bppbuf = malloc(maxw * maxh * BYTESPERPIXEL); if (bppbuf == NULL) { @@ -352,35 +350,7 @@ return (1); } } - - orig_w = width; - orig_h = height; - if ((fullscreen & 0x04) && (WIDTH != orig_w) && (HEIGHT != orig_h)) { - if (!vid_widescr || !res_widescr) { - maxh = HEIGHT; - scaling = maxh / (orig_h * 1.0); - maxw = (uint32_t) (orig_w * scaling); - scalebuf = malloc(maxw * maxh * BYTESPERPIXEL); - if (scalebuf == NULL) { - printf("vo_svga: scalebuf -> Not enough memory for buffering!\n"); - uninit(); - return (1); - } - } else { - maxw = WIDTH; - scaling = maxw / (orig_w * 1.0); - maxh = (uint32_t) (orig_h * scaling); - scalebuf = malloc(maxw * maxh * BYTESPERPIXEL); - if (scalebuf == NULL) { - printf("vo_svga: scalebuf -> Not enough memory for buffering!\n"); - uninit(); - return (1); - } - } - } else { - maxw = orig_w; - maxh = orig_h; - } + x_pos = (WIDTH - maxw) / 2; y_pos = (HEIGHT - maxh) / 2; @@ -398,9 +368,177 @@ if (maxw != orig_w || maxh != orig_h) printf("Video scaled to: %dx%d\n",maxw,maxh); else printf("No video scaling\n"); + vga_setdisplaystart(0); + + return (0); +} + +static const vo_info_t* get_info(void) { + return (&vo_info); +} + +static uint32_t draw_frame(uint8_t *src[]) { + if (pformat == IMGFMT_YV12) { + yuv2rgb(yuvbuf, src[0], src[1], src[2], orig_w, orig_h, orig_w * BYTESPERPIXEL, orig_w, orig_w / 2); + src[0] = yuvbuf; + } + if (bpp_conv) { + switch(bpp) { + case 32: { + uint8_t *source = src[0]; + uint8_t *dest = bppbuf; + register uint32_t i = 0; + + while (i < (maxw * maxh * 4)) { + dest[i] = source[i]; + dest[i+1] = source[i+1]; + dest[i+2] = source[i+2]; + dest[i+3] = 0; + i += 4; + } + } break; + case 16: { + rgb15to16(src[0],bppbuf,maxw * maxh * 2); + } break; + } + src[0] = bppbuf; + } + putbox(x_pos, y_pos, maxw, maxh, src[0], 1); + + return (0); +} + +static uint32_t draw_slice(uint8_t *image[], int stride[], + int w, int h, int x, int y) { + uint8_t *src = yuvbuf; + uint32_t sw, sh; + + yuv2rgb(yuvbuf, image[0], image[1], image[2], w, h, orig_w * BYTESPERPIXEL, stride[0], stride[1]); + putbox(x + x_pos, y + y_pos, w, h, src, 1); + return (0); } +static void draw_osd(void) +{ + if(oldmethod) { + if (y_pos) { + fillbox(0, 0, WIDTH, y_pos, 0); + fillbox(0, HEIGHT - y_pos, WIDTH, y_pos, 0); + if (x_pos) { + int hmy=HEIGHT - (y_pos<<1); + fillbox(0, y_pos, x_pos, hmy, 0); + fillbox(WIDTH - x_pos, y_pos, x_pos, hmy, 0); + } + } else if (x_pos) { + fillbox(0, y_pos, x_pos, HEIGHT, 0); + fillbox(WIDTH - x_pos, y_pos, x_pos, HEIGHT, 0); + } + vo_draw_text(WIDTH, HEIGHT, draw_alpha); + } else + vo_draw_text(maxw, maxh, draw_alpha); +} + +static void flip_page(void) { + if(oldmethod) { + int i; + uint8_t *b; + b=buffer; + for(i=0;i<HEIGHT;i++){ + vga_drawscansegment(b,0,i,LINEWIDTH); + b+=LINEWIDTH; + } + } else { + if(maxframes) { + vga_setdisplaystart(frame*HEIGHT*LINEWIDTH); + frame++; + if(frame>maxframes)frame=0; + } + } +} + +static void check_events(void) { +} + +static void uninit(void) { + vga_modelist_t *list = modelist; + + vga_setmode(TEXT); + + if (bppbuf != NULL) + free(bppbuf); + if (yuvbuf != NULL) + free(yuvbuf); + while (modelist != NULL) { + list=modelist; + modelist=modelist->next; + free(list); + } + checked = 0; +} + + +/* --------------------------------------------------------------------- */ + +static uint32_t add_mode(uint16_t mode, vga_modeinfo minfo) { + vga_modelist_t *list; + + if (modelist == NULL) { + modelist = (vga_modelist_t *) malloc(sizeof(vga_modelist_t)); + if (modelist == NULL) { + printf("vo_svga: add_mode() failed. Not enough memory for modelist."); + return(1); // error + } + modelist->modenum = mode; + modelist->modeinfo = minfo; + modelist->next = NULL; + } else { + list = modelist; + while (list->next != NULL) + list = list->next; + list->next = (vga_modelist_t *) malloc(sizeof(vga_modelist_t)); + if (list->next == NULL) { + printf("vo_svga: add_mode() failed. Not enough memory for modelist."); + return(1); // error + } + list = list->next; + list->modenum = mode; + list->modeinfo = minfo; + list->next = NULL; + } + return (0); +} + +static int checksupportedmodes() { + uint16_t i, max; + vga_modeinfo *minfo; + + checked = 1; + vga_init(); + vga_disabledriverreport(); + max = vga_lastmodenumber(); + if (verbose >= 2) + printf("vo_svga: Max mode : %i\n",max); + for (i = 1; i <= max; i++) + if (vga_hasmode(i) > 0) { + minfo = vga_getmodeinfo(i); + switch (minfo->colors) { + case 32768: bpp_avail |= BPP_15; break; + case 65536: bpp_avail |= BPP_16; break; + } + switch (minfo->bytesperpixel) { + case 3: bpp_avail |= BPP_24; break; + case 4: bpp_avail |= BPP_32; break; + } + if (verbose >= 2) + printf("vo_svga: Mode found: %s\n",vga_getmodename(i)); + if (add_mode(i, *minfo)) + return(1); + } + return(0); +} + + static uint32_t query_format(uint32_t format) { uint32_t res = 0; @@ -452,134 +590,84 @@ return (0); } -static const vo_info_t* get_info(void) { - return (&vo_info); +static void putbox(int x, int y, int w, int h, uint8_t *buf, int prog) { + int base, add, wid; + if(oldmethod) { + wid=w*BYTESPERPIXEL; + add=wid*prog; + while( (h--) > 0 ) { + memcpy(buffer+x*BYTESPERPIXEL+(y++)*LINEWIDTH, buf, wid); + buf+=add; + } + } else { + wid=w*BYTESPERPIXEL; + add=wid*prog; + base=frame*HEIGHT; + while( (h--) > 0 ) { + vga_drawscansegment(buf, x, (y++)+base, wid); + buf+=add; + } + } +} + +static void fillbox(int x, int y, int w, int h, uint32_t c) { + putbox(x,y,w,h,buf0,0); } static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { + int base; + + if(oldmethod) { + base=buffer; + } else + base=((frame*HEIGHT+y_pos)*WIDTH+x_pos)*BYTESPERPIXEL + GRAPH_MEM ; + switch (bpp) { case 32: - vo_draw_alpha_rgb32(w, h, src, srca, stride, virt->vbuf+4*(y0*WIDTH+x0), 4*WIDTH); + vo_draw_alpha_rgb32(w, h, src, srca, stride, base+4*(y0*WIDTH+x0), 4*WIDTH); break; case 24: - vo_draw_alpha_rgb24(w, h, src, srca, stride, virt->vbuf+3*(y0*WIDTH+x0), 3*WIDTH); + vo_draw_alpha_rgb24(w, h, src, srca, stride, base+3*(y0*WIDTH+x0), 3*WIDTH); break; case 16: - vo_draw_alpha_rgb16(w, h, src, srca, stride, virt->vbuf+2*(y0*WIDTH+x0), 2*WIDTH); + vo_draw_alpha_rgb16(w, h, src, srca, stride, base+2*(y0*WIDTH+x0), 2*WIDTH); break; case 15: - vo_draw_alpha_rgb15(w, h, src, srca, stride, virt->vbuf+2*(y0*WIDTH+x0), 2*WIDTH); + vo_draw_alpha_rgb15(w, h, src, srca, stride, base+2*(y0*WIDTH+x0), 2*WIDTH); break; } -} - -static uint32_t draw_frame(uint8_t *src[]) { - if (pformat == IMGFMT_YV12) { - yuv2rgb(yuvbuf, src[0], src[1], src[2], orig_w, orig_h, orig_w * BYTESPERPIXEL, orig_w, orig_w / 2); - src[0] = yuvbuf; - } - if (scalebuf != NULL) { - gl_scalebox(orig_w, orig_h, src[0], maxw, maxh, scalebuf); - src[0] = scalebuf; - } - if (bpp_conv) { - switch(bpp) { - case 32: { - uint8_t *source = src[0]; - uint8_t *dest = bppbuf; - register uint32_t i = 0; - - while (i < (maxw * maxh * 4)) { - dest[i] = source[i]; - dest[i+1] = source[i+1]; - dest[i+2] = source[i+2]; - dest[i+3] = 0; - i += 4; - } - } break; - case 16: { - rgb15to16(src[0],bppbuf,maxw * maxh * 2); - } break; - } - src[0] = bppbuf; - } - gl_putbox(x_pos, y_pos, maxw, maxh, src[0]); - - return (0); -} - -static uint32_t draw_slice(uint8_t *image[], int stride[], - int w, int h, int x, int y) { - uint8_t *src = yuvbuf; - uint32_t sw, sh; - - yuv2rgb(yuvbuf, image[0], image[1], image[2], w, h, orig_w * BYTESPERPIXEL, stride[0], stride[1]); - sw = (uint32_t) (w * scaling); - sh = (uint32_t) (h * scaling); - if (scalebuf != NULL) { - gl_scalebox(w, h, yuvbuf, sw, sh, scalebuf); - src = scalebuf; - } - gl_putbox((int)(x * scaling) + x_pos, (int)(y * scaling) + y_pos, sw, sh, src); - - return (0); -} - -static void draw_osd(void) -{ - if (y_pos) { - gl_fillbox(0, 0, WIDTH, y_pos, 0); - gl_fillbox(0, HEIGHT - y_pos, WIDTH, y_pos, 0); - if (x_pos) { - int hmy=HEIGHT - (y_pos<<1); - gl_fillbox(0, y_pos, x_pos, hmy, 0); - gl_fillbox(WIDTH - x_pos, y_pos, x_pos, hmy, 0); - } - } else if (x_pos) { - gl_fillbox(0, y_pos, x_pos, HEIGHT, 0); - gl_fillbox(WIDTH - x_pos, y_pos, x_pos, HEIGHT, 0); - } - - vo_draw_text(WIDTH, HEIGHT, draw_alpha); -} - -static void flip_page(void) { - gl_copyscreen(screen); -} - -static void check_events(void) { -} - -static void uninit(void) { - vga_modelist_t *list = modelist; - - gl_freecontext(screen); - gl_freecontext(virt); - vga_setmode(TEXT); - if (bppbuf != NULL) - free(bppbuf); - if (scalebuf != NULL) - free(scalebuf); - if (yuvbuf != NULL) - free(yuvbuf); - while (modelist != NULL) { - list=modelist; - modelist=modelist->next; - free(list); - } } -static uint32_t preinit(const char *arg) +static uint32_t get_image(mp_image_t *mpi) { - return 0; + if (/* zoomFlag || */ + !IMGFMT_IS_BGR(mpi->imgfmt) || + ((mpi->type != MP_IMGTYPE_STATIC) && (mpi->type != MP_IMGTYPE_TEMP)) || + (mpi->flags & MP_IMGFLAG_PLANAR) || + (mpi->flags & MP_IMGFLAG_YUV) /* + (mpi->width != image_width) || + (mpi->height != image_height) */ + ) + return(VO_FALSE); + +/* + if (Flip_Flag) + { + mpi->stride[0] = -image_width*((bpp+7)/8); + mpi->planes[0] = ImageData - mpi->stride[0]*(image_height-1); + } + else +*/ + { + mpi->stride[0] = LINEWIDTH; + if(oldmethod) { + mpi->planes[0] = buffer; + } else + mpi->planes[0] = GRAPH_MEM; + } + mpi->flags |= MP_IMGFLAG_DIRECT; + + return(VO_TRUE); } -static uint32_t control(uint32_t request, void *data, ...) -{ - switch (request) { - case VOCTRL_QUERY_FORMAT: - return query_format(*((uint32_t*)data)); - } - return VO_NOTIMPL; -}