1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-21 02:41:13 +00:00

totally reworked, working fine on fbdev too, applied Andres Beck's patches, quad-buffering support

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4829 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
alex 2002-02-23 23:31:08 +00:00
parent d840ddb7c5
commit 723c3a1fd0

View File

@ -5,6 +5,7 @@
Uses libGGI - http://www.ggi-project.org/ Uses libGGI - http://www.ggi-project.org/
Thanks to Andreas Beck for his patches.
Many thanks to Atmosfear, he hacked this driver to working with Planar Many thanks to Atmosfear, he hacked this driver to working with Planar
formats, and he fixed the RGB handling. formats, and he fixed the RGB handling.
*/ */
@ -14,6 +15,8 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "mp_msg.h"
#include "../config.h" #include "../config.h"
#include "video_out.h" #include "video_out.h"
#include "video_out_internal.h" #include "video_out_internal.h"
@ -22,16 +25,14 @@
#include <ggi/ggi.h> #include <ggi/ggi.h>
#undef GGI_OST #undef GET_DB_INFO
#undef GII_BUGGY_KEYCODES
#define GGI_OSD
#undef get_db_info #define GGI_FRAMES 4
/* do not make conversions from planar formats */ /* do not make conversions from planar formats */
#undef GGI_PLANAR_NOCONV #undef GGI_YUV_SUPPORT
#ifndef GGI_PLANAR_NOCONV #ifndef GGI_YUV_SUPPORT
#include "../postproc/rgb2rgb.h" #include "../postproc/rgb2rgb.h"
#endif #endif
@ -45,14 +46,15 @@ static vo_info_t vo_info =
"under developement" "under developement"
}; };
extern int verbose;
/* idea stolen from vo_sdl.c :) */
static struct ggi_conf_s { static struct ggi_conf_s {
char *driver; char *driver;
ggi_visual_t vis; ggi_visual_t vis;
ggi_directbuffer *buffer; ggi_directbuffer *buffer[GGI_FRAMES];
ggi_mode gmode;
int frames;
int currframe;
uint8_t bpp; uint8_t bpp;
uint8_t bppmul; uint8_t bppmul;
@ -71,31 +73,23 @@ static struct ggi_conf_s {
int stridePlaneRGB; int stridePlaneRGB;
/* original */ /* original */
int width, height; int srcwidth, srcheight;
int srcformat;
int srcdepth;
int srctype;
/* destination */ /* destination */
int dstwidth, dstheight; int dstwidth, dstheight;
/* source image format */ /* source image format */
int format; int format;
/* direct buffer */
uint8_t *dbuff;
/* i.e. need lock */
int need_acquire;
#ifdef GGI_OST
ggi_pixel white;
ggi_pixel black;
#endif
} ggi_conf; } ggi_conf;
static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth) static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth)
{ {
ggi_mode mode = ggi_mode mode =
{ {
1, /* frames */ GGI_FRAMES, /* frames */
{ GGI_AUTO, GGI_AUTO }, /* visible */ { GGI_AUTO, GGI_AUTO }, /* visible */
{ GGI_AUTO, GGI_AUTO }, /* virt */ { GGI_AUTO, GGI_AUTO }, /* virt */
{ GGI_AUTO, GGI_AUTO }, /* size */ { GGI_AUTO, GGI_AUTO }, /* size */
@ -104,14 +98,13 @@ static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth)
}; };
ggi_color pal[256]; ggi_color pal[256];
if (verbose) mp_msg(MSGT_VO, MSGL_V, "[ggi] mode requested: %dx%d (%d depth)\n",
printf("ggi-setmode: requested: %dx%d (%d depth)\n", d_width, d_height, d_depth);
d_width, d_height, d_depth);
mode.size.x = vo_screenwidth; // mode.size.x = vo_screenwidth;
mode.size.y = vo_screenheight; // mode.size.y = vo_screenheight;
mode.visible.x = mode.virt.x = d_width; mode.visible.x = d_width;
mode.visible.y = mode.virt.y = d_height; mode.visible.y = d_height;
switch(d_depth) switch(d_depth)
{ {
@ -140,30 +133,29 @@ static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth)
mode.graphtype = GT_32BIT; mode.graphtype = GT_32BIT;
break; break;
default: default:
printf("ggi-setmode: unknown bit depth - using auto\n"); mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unknown bit depth - using auto\n");
mode.graphtype = GT_AUTO; mode.graphtype = GT_AUTO;
} }
/* FIXME */
ggiCheckMode(ggi_conf.vis, &mode); ggiCheckMode(ggi_conf.vis, &mode);
if (ggiSetMode(ggi_conf.vis, &mode) != 0) if (ggiSetMode(ggi_conf.vis, &mode) != 0)
{ {
printf("ggi-setmode: unable to set mode\n"); mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to set mode\n");
ggiClose(ggi_conf.vis); uninit();
ggiExit();
return(-1); return(-1);
} }
if (ggiGetMode(ggi_conf.vis, &mode) != 0) if (ggiGetMode(ggi_conf.vis, &mode) != 0)
{ {
printf("ggi-setmode: unable to get mode\n"); mp_msg(MSGT_VO, MSGL_ERR, "[ggi] unable to get mode\n");
ggiClose(ggi_conf.vis); uninit();
ggiExit();
return(-1); return(-1);
} }
ggi_conf.width = mode.virt.x; ggi_conf.gmode = mode;
ggi_conf.height = mode.virt.y;
vo_screenwidth = mode.visible.x; vo_screenwidth = mode.visible.x;
vo_screenheight = mode.visible.y; vo_screenheight = mode.visible.y;
vo_depthonscreen = d_depth; vo_depthonscreen = d_depth;
@ -171,7 +163,7 @@ static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth)
// ggi_bpp = GT_SIZE(mode.graphtype); // ggi_bpp = GT_SIZE(mode.graphtype);
ggi_conf.bpp = vo_depthonscreen; ggi_conf.bpp = vo_depthonscreen;
#ifdef get_db_info #ifdef GET_DB_INFO
{ {
const ggi_directbuffer *db = ggiDBGetBuffer(ggi_conf.vis, 0); const ggi_directbuffer *db = ggiDBGetBuffer(ggi_conf.vis, 0);
@ -189,138 +181,74 @@ static int ggi_setmode(uint32_t d_width, uint32_t d_height, int d_depth)
ggiGetPalette(ggi_conf.vis, 0, 1 << ggi_conf.bpp, pal); ggiGetPalette(ggi_conf.vis, 0, 1 << ggi_conf.bpp, pal);
} }
if (verbose) #if 0
printf("ggi-setmode: %dx%d (virt: %dx%d) (size: %dx%d) screen depth: %d, bpp: %d\n", printf("[ggi] mode: ");
vo_screenwidth, vo_screenheight, ggi_conf.width, ggi_conf.height, ggiPrintMode(&ggi_conf.gmode);
mode.size.x, mode.size.y, printf("\n");
vo_depthonscreen, ggi_conf.bpp); #endif
mp_msg(MSGT_VO, MSGL_INFO, "[ggi] screen: %dx%dx%d frames: %d\n",
vo_screenwidth, vo_screenheight, vo_depthonscreen, ggi_conf.gmode.frames);
ggi_conf.bppmul = (ggi_conf.bpp+7)/8; ggi_conf.bppmul = (ggi_conf.bpp+7)/8;
return(0); return(0);
} }
typedef struct ggi_aspect_ret_s { int w, h, x, y; } ggi_aspect_ret;
/* stolen from vo_sdl.c */
#define MONITOR_ASPECT 4.0/3.0
static ggi_aspect_ret aspect_size(int srcw, int srch, int dstw, int dsth)
{
ggi_aspect_ret ret;
float float_h;
if (verbose)
printf("ggi-aspectsize: src: %dx%d dst: %dx%d\n",
srcw, srch, dstw, dsth);
float_h = ((float)dsth / (float)srcw * (float)srch) * ((float)dsth /
((float)dstw / (MONITOR_ASPECT)));
if (float_h > dsth)
{
ret.w = (int)((float)dsth / (float)float_h) * dstw;
ret.h = dsth;
ret.x = (dstw - ret.w) / 2;
ret.y = 0;
}
else
{
ret.h = (int)float_h;
ret.w = dstw;
ret.x = 0;
ret.y = (dsth - ret.h) / 2;
}
printf("ggi-aspectsize: %dx%d (x: %d, y: %d)\n", ret.w, ret.h, ret.x, ret.y);
return(ret);
}
static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info) uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format,const vo_tune_info_t *info)
{ {
int i;
vo_depthonscreen = 32; vo_depthonscreen = 32;
printf("ggi-init: This driver has got bugs, if you can, fix them.\n"); mp_msg(MSGT_VO, MSGL_INFO, "[ggi] This driver has got bugs, if you can, fix them.\n");
if (ggiInit() != 0) /* source image parameters */
ggi_conf.srcwidth = width;
ggi_conf.srcheight = height;
ggi_conf.srcformat = format;
if (IMGFMT_IS_RGB(ggi_conf.srcformat))
{ {
printf("ggi-init: unable to initialize GGI\n"); ggi_conf.srcdepth = IMGFMT_RGB_DEPTH(ggi_conf.srcformat);
return(-1); ggi_conf.srctype = RGB;
} }
else
ggi_conf.driver = NULL; if (IMGFMT_IS_BGR(ggi_conf.srcformat))
if ((ggi_conf.vis = ggiOpen(ggi_conf.driver)) == NULL)
{ {
printf("ggi-init: unable to open GGI for %s output\n", ggi_conf.srcdepth = IMGFMT_BGR_DEPTH(ggi_conf.srcformat);
(ggi_conf.driver == NULL) ? "default" : ggi_conf.driver); ggi_conf.srctype = BGR;
ggiExit();
return(-1);
} }
else
printf("ggi-init: using %s GGI output\n", switch(ggi_conf.srcformat)
(ggi_conf.driver == NULL) ? "default" : ggi_conf.driver);
switch(format)
{ {
case IMGFMT_RGB8:
ggi_conf.bpp = 8;
ggi_conf.mode = RGB;
break;
case IMGFMT_RGB15:
ggi_conf.bpp = 15;
ggi_conf.mode = RGB;
break;
case IMGFMT_RGB16:
ggi_conf.bpp = 16;
ggi_conf.mode = RGB;
break;
case IMGFMT_RGB24:
ggi_conf.bpp = 24;
ggi_conf.mode = RGB;
break;
case IMGFMT_RGB32:
ggi_conf.bpp = 32;
ggi_conf.mode = RGB;
break;
case IMGFMT_BGR8:
ggi_conf.bpp = 8;
ggi_conf.mode = BGR;
break;
case IMGFMT_BGR15:
ggi_conf.bpp = 15;
ggi_conf.mode = BGR;
break;
case IMGFMT_BGR16:
ggi_conf.bpp = 16;
ggi_conf.mode = BGR;
break;
case IMGFMT_BGR24:
ggi_conf.bpp = 24;
ggi_conf.mode = BGR;
break;
case IMGFMT_BGR32:
ggi_conf.bpp = 32;
ggi_conf.mode = BGR;
break;
case IMGFMT_YV12: /* rgb, 24bit */
case IMGFMT_I420:
case IMGFMT_IYUV: case IMGFMT_IYUV:
ggi_conf.bpp = 16; case IMGFMT_I420:
ggi_conf.mode = YUV; case IMGFMT_YV12:
#ifndef GGI_PLANAR_NOCONV #ifdef GGI_YUV_SUPPORT
yuv2rgb_init(32/*vo_depthonscreen*/, MODE_RGB); ggi_conf.srcdepth = 12;
ggi_conf.srctype = YUV;
#else
ggi_conf.bpp = vo_depthonscreen;
ggi_conf.mode = RGB;
yuv2rgb_init(vo_depthonscreen, MODE_RGB);
#endif #endif
break; break;
case IMGFMT_UYVY:
case IMGFMT_YUY2: case IMGFMT_YUY2:
ggi_conf.bpp = 24; #ifdef GGI_YUV_SUPPORT
ggi_conf.mode = YUV; ggi_conf.srcdepth = 16;
#ifndef GGI_PLANAR_NOCONV ggi_conf.srctype = YUV;
yuv2rgb_init(32, MODE_RGB); #else
ggi_conf.bpp = vo_depthonscreen;
ggi_conf.mode = RGB;
yuv2rgb_init(vo_depthonscreen, MODE_RGB);
#endif #endif
break; break;
default: default:
printf("ggi-init: no suitable image format found (requested: %s)\n", mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] Unknown image format: %s\n",
vo_format_name(format)); vo_format_name(ggi_conf.srcformat));
uninit();
return(-1); return(-1);
} }
@ -328,7 +256,7 @@ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
ggi_conf.framePlaneRGB = width * height * ((ggi_conf.bpp+7)/8); /* fix it! */ ggi_conf.framePlaneRGB = width * height * ((ggi_conf.bpp+7)/8); /* fix it! */
ggi_conf.stridePlaneRGB = width * ((ggi_conf.bpp+7)/8); ggi_conf.stridePlaneRGB = width * ((ggi_conf.bpp+7)/8);
#ifdef GGI_PLANAR_NOCONV #ifdef GGI_YUV_SUPPORT
ggi_conf.framePlaneY = width * height; ggi_conf.framePlaneY = width * height;
ggi_conf.framePlaneUV = (width * height) >> 2; ggi_conf.framePlaneUV = (width * height) >> 2;
ggi_conf.framePlaneYUY = width * height * 2; ggi_conf.framePlaneYUY = width * height * 2;
@ -336,12 +264,13 @@ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
ggi_conf.stridePlaneUV = width/2; ggi_conf.stridePlaneUV = width/2;
ggi_conf.stridePlaneYUY = width * 2; ggi_conf.stridePlaneYUY = width * 2;
#endif #endif
ggi_conf.width = width; // ggi_conf.width = width;
ggi_conf.height = height; // ggi_conf.height = height;
ggi_conf.dstwidth = d_width ? d_width : width; ggi_conf.dstwidth = d_width ? d_width : width;
ggi_conf.dstheight = d_height ? d_height : height; ggi_conf.dstheight = d_height ? d_height : height;
{ {
#if 0
ggi_aspect_ret asp; ggi_aspect_ret asp;
if (width != d_width || height != d_height) if (width != d_width || height != d_height)
@ -351,67 +280,63 @@ static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
asp.w = width; asp.w = width;
asp.h = height; asp.h = height;
} }
#endif
if (ggi_setmode(asp.w, asp.h, vo_depthonscreen) != 0) if (ggi_setmode(width, height, vo_depthonscreen) != 0)
{ {
printf("ggi-init: setmode returned with error\n"); printf("ggi-init: setmode returned with error\n");
return(-1); return(-1);
} }
} }
printf("ggi-init: input: %d bpp %s - screen depth: %d\n", ggi_conf.bpp, mp_msg(MSGT_VO, MSGL_INFO, "[ggi] input: %d bpp %s - screen depth: %d\n",
vo_format_name(ggi_conf.format), vo_depthonscreen); ggi_conf.bpp, vo_format_name(ggi_conf.format), vo_depthonscreen);
ggiSetFlags(ggi_conf.vis, GGIFLAG_ASYNC); // ggiSetFlags(ggi_conf.vis, GGIFLAG_ASYNC);
ggi_conf.buffer = (ggi_directbuffer *)ggiDBGetBuffer(ggi_conf.vis, 0);
if (ggi_conf.buffer == NULL)
{ {
printf("ggi-init: double buffering is not available\n"); ggi_directbuffer *DB;
ggiClose(ggi_conf.vis);
ggiExit(); for (i = 0; i < GGI_FRAMES; i++)
ggi_conf.buffer[i] = NULL;
ggi_conf.frames = ggi_conf.currframe = 0;
for (i = 0; DB = ggiDBGetBuffer(ggi_conf.vis, i); i++)
{
if (!(DB->type & GGI_DB_SIMPLE_PLB) ||
(DB->page_size != 0) ||
(DB->write == NULL) ||
(DB->noaccess != 0) ||
(DB->align != 0) ||
(DB->layout != blPixelLinearBuffer))
continue;
ggi_conf.buffer[DB->frame] = DB;
ggi_conf.frames++;
}
}
if (ggi_conf.buffer[0] == NULL)
{
mp_msg(MSGT_VO, MSGL_ERR, "[ggi] direct buffer is not available\n");
uninit();
return(-1); return(-1);
} }
if (!(ggi_conf.buffer->type & GGI_DB_SIMPLE_PLB) || for (i = 0; i < ggi_conf.frames; i++)
(ggi_conf.buffer->page_size != 0) ||
(ggi_conf.buffer->write == NULL) ||
(ggi_conf.buffer->noaccess != 0) ||
(ggi_conf.buffer->align != 0) ||
(ggi_conf.buffer->layout != blPixelLinearBuffer))
{ {
printf("ggi-init: incorrect video memory type\n"); if (ggi_conf.buffer[i] == NULL)
ggiClose(ggi_conf.vis); {
ggiExit(); mp_msg(MSGT_VO, MSGL_ERR, "[ggi] direct buffer for doublbuffering is not available\n");
return(-1); uninit();
return(-1);
}
} }
if (ggi_conf.buffer->resource != NULL) ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.currframe);
ggi_conf.need_acquire = 1; ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe);
if (verbose && ggi_conf.need_acquire)
printf("ggi-init: ggi needs acquire\n");
ggi_conf.dbuff = ggi_conf.buffer->write;
#ifdef GGI_OST
/* just for fun */
{
ggi_color col;
/* set black */
col.r = col.g = col.b = 0x0000;
ggi_conf.black = ggiMapColor(ggi_conf.vis, &col);
/* set white */
col.r = col.g = col.b = 0xffff;
ggi_conf.white = ggiMapColor(ggi_conf.vis, &col);
ggiSetGCForeground(ggi_conf.vis, ggi_conf.white);
ggiSetGCBackground(ggi_conf.vis, ggi_conf.black);
}
#endif
return(0); return(0);
} }
@ -423,38 +348,46 @@ static const vo_info_t *get_info(void)
static uint32_t draw_frame(uint8_t *src[]) static uint32_t draw_frame(uint8_t *src[])
{ {
if (ggi_conf.need_acquire) int x, y, size;
ggiResourceAcquire(ggi_conf.buffer->resource, GGI_ACTYPE_WRITE); unsigned char *ptr, *ptr2, *spt;
// ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.buffer->frame); ggiResourceAcquire(ggi_conf.buffer[ggi_conf.currframe]->resource,
// ggiSetWriteFrame(ggi_conf.vis, ggi_conf.buffer->frame); GGI_ACTYPE_WRITE);
#ifdef GGI_PLANAR_NOCONV ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe);
switch(ggi_conf.format)
#if 1
ptr = ggi_conf.buffer[ggi_conf.currframe]->write;
spt = src[0];
size = ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.pixelformat->size/8;
for (y = 0; y < ggi_conf.srcheight; y++)
{ {
case IMGFMT_YV12: ptr2 = ptr;
case IMGFMT_I420: for (x = 0; x < ggi_conf.srcwidth; x++)
case IMGFMT_IYUV: {
memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneY); ptr2[0] = *spt++;
ggi_conf.dbuff += ggi_conf.framePlaneY; ptr2[1] = *spt++;
memcpy(ggi_conf.dbuff, src[2], ggi_conf.framePlaneUV); ptr2[2] = *spt++;
ggi_conf.dbuff += ggi_conf.framePlaneUV; switch(ggi_conf.format)
memcpy(ggi_conf.dbuff, src[1], ggi_conf.framePlaneUV); {
printf("yv12 img written"); case IMGFMT_BGR32:
break; case IMGFMT_RGB32:
default: spt++;
memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneRGB); break;
}
ptr2 += size;
}
ptr += ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride;
} }
#else #else
memcpy(ggi_conf.dbuff, src[0], ggi_conf.framePlaneRGB); memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[0], ggi_conf.framePlaneRGB);
#endif #endif
if (ggi_conf.need_acquire) ggiResourceRelease(ggi_conf.buffer[ggi_conf.currframe]->resource);
ggiResourceRelease(ggi_conf.buffer->resource);
return(0); return(0);
} }
#ifdef GGI_OSD
static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
unsigned char *srca, int stride) unsigned char *srca, int stride)
{ {
@ -463,28 +396,28 @@ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
case IMGFMT_YV12: case IMGFMT_YV12:
case IMGFMT_I420: case IMGFMT_I420:
case IMGFMT_IYUV: case IMGFMT_IYUV:
#ifdef GGI_PLANAR_NOCONV #ifdef GGI_YUV_SUPPORT
vo_draw_alpha_yv12(w, h, src, srca, stride, vo_draw_alpha_yv12(w, h, src, srca, stride,
ggi_conf.dbuff+(ggi_conf.width*y0+x0), ggi_conf.buffer[ggi_conf.currframe]->write+(ggi_conf.srcwidth*y0+x0),
ggi_conf.width); ggi_conf.srcwidth);
#else #else
switch (vo_depthonscreen) switch (vo_depthonscreen)
{ {
case 32: case 32:
vo_draw_alpha_rgb32(w, h, src, srca, stride, vo_draw_alpha_rgb32(w, h, src, srca, stride,
ggi_conf.dbuff+4*(ggi_conf.width*y0+x0), 4*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+4*(ggi_conf.srcwidth*y0+x0), 4*ggi_conf.srcwidth);
break; break;
case 24: case 24:
vo_draw_alpha_rgb24(w, h, src, srca, stride, vo_draw_alpha_rgb24(w, h, src, srca, stride,
ggi_conf.dbuff+3*(ggi_conf.width*y0+x0), 3*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+3*(ggi_conf.srcwidth*y0+x0), 3*ggi_conf.srcwidth);
break; break;
case 16: case 16:
vo_draw_alpha_rgb16(w, h, src, srca, stride, vo_draw_alpha_rgb16(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth);
break; break;
case 15: case 15:
vo_draw_alpha_rgb15(w, h, src, srca, stride, vo_draw_alpha_rgb15(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth);
break; break;
} }
#endif #endif
@ -492,68 +425,74 @@ static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
case IMGFMT_YUY2: case IMGFMT_YUY2:
case IMGFMT_YVYU: case IMGFMT_YVYU:
vo_draw_alpha_yuy2(w, h, src, srca, stride, vo_draw_alpha_yuy2(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0),
2*ggi_conf.width); 2*ggi_conf.srcwidth);
break; break;
case IMGFMT_UYVY: case IMGFMT_UYVY:
vo_draw_alpha_yuy2(w, h, src, srca, stride, vo_draw_alpha_yuy2(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0)+1, ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0)+1,
2*ggi_conf.width); 2*ggi_conf.srcwidth);
break; break;
case IMGFMT_RGB15: case IMGFMT_RGB15:
case IMGFMT_BGR15: case IMGFMT_BGR15:
vo_draw_alpha_rgb15(w, h, src, srca, stride, vo_draw_alpha_rgb15(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth);
break; break;
case IMGFMT_RGB16: case IMGFMT_RGB16:
case IMGFMT_BGR16: case IMGFMT_BGR16:
vo_draw_alpha_rgb16(w, h, src, srca, stride, vo_draw_alpha_rgb16(w, h, src, srca, stride,
ggi_conf.dbuff+2*(ggi_conf.width*y0+x0), 2*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+2*(ggi_conf.srcwidth*y0+x0), 2*ggi_conf.srcwidth);
break; break;
case IMGFMT_RGB24: case IMGFMT_RGB24:
case IMGFMT_BGR24: case IMGFMT_BGR24:
vo_draw_alpha_rgb24(w, h, src, srca, stride, vo_draw_alpha_rgb24(w, h, src, srca, stride,
ggi_conf.dbuff+3*(ggi_conf.width*y0+x0), 3*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+3*(ggi_conf.srcwidth*y0+x0), 3*ggi_conf.srcwidth);
break; break;
case IMGFMT_RGB32: case IMGFMT_RGB32:
case IMGFMT_BGR32: case IMGFMT_BGR32:
vo_draw_alpha_rgb32(w, h, src, srca, stride, vo_draw_alpha_rgb32(w, h, src, srca, stride,
ggi_conf.dbuff+4*(ggi_conf.width*y0+x0), 4*ggi_conf.width); ggi_conf.buffer[ggi_conf.currframe]->write+4*(ggi_conf.srcwidth*y0+x0), 4*ggi_conf.srcwidth);
break; break;
} }
} }
#endif
static void draw_osd(void) static void draw_osd(void)
{ {
#ifdef GGI_OSD vo_draw_text(ggi_conf.srcwidth, ggi_conf.srcheight, draw_alpha);
vo_draw_text(ggi_conf.width, ggi_conf.height, draw_alpha);
#endif
} }
static void flip_page(void) static void flip_page(void)
{ {
ggiFlush(ggi_conf.vis); ggiSetDisplayFrame(ggi_conf.vis, ggi_conf.currframe);
mp_dbg(MSGT_VO, MSGL_DBG2, "flip_page: current write frame: %d, display frame: %d\n",
ggiGetWriteFrame(ggi_conf.vis), ggiGetDisplayFrame(ggi_conf.vis));
ggi_conf.currframe = (ggi_conf.currframe+1) % ggi_conf.frames;
} }
static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h, static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h,
int x, int y) int x, int y)
{ {
if (ggi_conf.need_acquire) ggiResourceAcquire(ggi_conf.buffer[ggi_conf.currframe]->resource,
ggiResourceAcquire(ggi_conf.buffer->resource, GGI_ACTYPE_WRITE); GGI_ACTYPE_WRITE);
#ifndef GGI_PLANAR_NOCONV
yuv2rgb(((uint8_t *) ggi_conf.dbuff)+(ggi_conf.width*y+x)*ggi_conf.bppmul, ggiSetWriteFrame(ggi_conf.vis, ggi_conf.currframe);
src[0], src[1], src[2], w, h, ggi_conf.width*ggi_conf.bppmul, stride[0],
stride[1]); #ifndef GGI_YUV_SUPPORT
yuv2rgb(((uint8_t *) ggi_conf.buffer[ggi_conf.currframe]->write)+
ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride*y+
x*(ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.pixelformat->size/8),
src[0], src[1], src[2], w, h, ggi_conf.buffer[ggi_conf.currframe]->buffer.plb.stride,
stride[0], stride[1]);
#else #else
int i; int i;
ggi_conf.dbuff += (ggi_conf.stridePlaneY * y + x); ggi_conf.buffer[ggi_conf.currframe]->write += (ggi_conf.stridePlaneY * y + x);
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
memcpy(ggi_conf.dbuff, src[0], w); memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[0], w);
src[0] += stride[0]; src[0] += stride[0];
ggi_conf.dbuff += ggi_conf.stridePlaneY; ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneY;
} }
x /= 2; x /= 2;
@ -561,16 +500,16 @@ static uint32_t draw_slice(uint8_t *src[], int stride[], int w, int h,
w /= 2; w /= 2;
h /= 2; h /= 2;
ggi_conf.dbuff += ggi_conf.stridePlaneY + (ggi_conf.stridePlaneUV * y + x); ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneY + (ggi_conf.stridePlaneUV * y + x);
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
memcpy(ggi_conf.dbuff, src[1], w); memcpy(ggi_conf.buffer[ggi_conf.currframe]->write, src[1], w);
src[1] += stride[1]; src[1] += stride[1];
ggi_conf.dbuff += ggi_conf.stridePlaneUV; ggi_conf.buffer[ggi_conf.currframe]->write += ggi_conf.stridePlaneUV;
} }
#endif #endif
if (ggi_conf.need_acquire)
ggiResourceRelease(ggi_conf.buffer->resource); ggiResourceRelease(ggi_conf.buffer[ggi_conf.currframe]->resource);
return(0); return(0);
} }
@ -600,13 +539,48 @@ static uint32_t query_format(uint32_t format)
return(0); return(0);
} }
static uint32_t preinit(const char *arg)
{
if (ggiInit() != 0)
{
mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] unable to initialize GGI\n");
return(-1);
}
if (arg)
ggi_conf.driver = arg;
else
ggi_conf.driver = NULL;
if ((ggi_conf.vis = ggiOpen(ggi_conf.driver)) == NULL)
{
mp_msg(MSGT_VO, MSGL_FATAL, "[ggi] unable to open '%s' output\n",
(ggi_conf.driver == NULL) ? "default" : ggi_conf.driver);
ggiExit();
return(-1);
}
mp_msg(MSGT_VO, MSGL_V, "[ggi] using '%s' output\n",
(ggi_conf.driver == NULL) ? "default" : ggi_conf.driver);
return 0;
}
static void uninit(void) static void uninit(void)
{ {
ggiResourceRelease(ggi_conf.buffer->resource);
ggiClose(ggi_conf.vis); ggiClose(ggi_conf.vis);
ggiExit(); ggiExit();
} }
static uint32_t control(uint32_t request, void *data, ...)
{
switch (request) {
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
}
return VO_NOTIMPL;
}
#include "../linux/keycodes.h" #include "../linux/keycodes.h"
extern void mplayer_put_key(int code); extern void mplayer_put_key(int code);
@ -619,75 +593,11 @@ static void check_events(void)
if ((mask = ggiEventPoll(ggi_conf.vis, emAll, &tv))) if ((mask = ggiEventPoll(ggi_conf.vis, emAll, &tv)))
if (ggiEventRead(ggi_conf.vis, &event, emAll) != 0) if (ggiEventRead(ggi_conf.vis, &event, emAll) != 0)
{ {
#if 0 /* debug ;) */ mp_dbg(MSGT_VO, MSGL_DBG3, "type: %4x, origin: %4x, sym: %4x, label: %4x, button=%4x\n",
printf("type: %4x, origin: %4x, sym: %4x, label: %4x, button=%4x\n",
event.any.origin, event.any.type, event.key.sym, event.key.label, event.key.button); event.any.origin, event.any.type, event.key.sym, event.key.label, event.key.button);
#endif
if (event.key.type == evKeyPress) if (event.key.type == evKeyPress)
{ {
#ifdef GII_BUGGY_KEYCODES
switch(event.key.button)
{
case 0x37:
mplayer_put_key('*');
break;
case 0x68:
mplayer_put_key('/');
break;
case 0x4e:
mplayer_put_key('+');
break;
case 0x4a:
mplayer_put_key('-');
break;
case 0x18: /* o */
mplayer_put_key('o');
break;
case 0x22: /* g */
mplayer_put_key('g');
break;
case 0x15: /* z */
mplayer_put_key('z');
break;
case 0x2d: /* x */
mplayer_put_key('x');
break;
case 0x32: /* m */
mplayer_put_key('m');
break;
case 0x20: /* d */
mplayer_put_key('d');
break;
case 0x10: /* q */
mplayer_put_key('q');
break;
case 0x39: /* space */
case 0x19: /* p */
mplayer_put_key('p');
break;
case 0x5a:
mplayer_put_key(KEY_UP);
break;
case 0x60:
mplayer_put_key(KEY_DOWN);
break;
case 0x5c:
mplayer_put_key(KEY_LEFT);
break;
case 0x5e:
mplayer_put_key(KEY_RIGHT);
break;
case 0x5b:
mplayer_put_key(KEY_PAGE_UP);
break;
case 0x61:
mplayer_put_key(KEY_PAGE_DOWN);
break;
default:
break;
}
#else
switch(event.key.sym) switch(event.key.sym)
{ {
case GIIK_PAsterisk: /* PStar */ case GIIK_PAsterisk: /* PStar */
@ -734,6 +644,14 @@ static void check_events(void)
case GIIUC_Q: case GIIUC_Q:
mplayer_put_key('q'); mplayer_put_key('q');
break; break;
case GIIUC_h:
case GIIUC_H:
mplayer_put_key('h');
break;
case GIIUC_l:
case GIIUC_L:
mplayer_put_key('l');
break;
case GIIUC_Space: case GIIUC_Space:
case GIIUC_p: case GIIUC_p:
case GIIUC_P: case GIIUC_P:
@ -760,27 +678,7 @@ static void check_events(void)
default: default:
break; break;
} }
#endif
} }
} }
return; return;
} }
static uint32_t preinit(const char *arg)
{
if(arg)
{
printf("vo_ggi: Unknown subdevice: %s\n",arg);
return ENOSYS;
}
return 0;
}
static uint32_t control(uint32_t request, void *data, ...)
{
switch (request) {
case VOCTRL_QUERY_FORMAT:
return query_format(*((uint32_t*)data));
}
return VO_NOTIMPL;
}