Experimental vo_gl with (limited) support for hardware YUV.
Reimar Döffinger <[email protected]> Fri, 23 Apr 2004 23:39:14 +0200
| Newsgroups | gmane.comp.video.mplayer.g2.devel |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
--------------010405090309040607050200
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: quoted-printable
Hi,
just thought I let everyone have a look at what I'm currently working=20
on. It can play YUV directly on nVidia GPUs better than GeForce3, but=20
probably won't work at all with older cards :( - it's still a long way=20
till it's finished, but I hope the concept will be extensible enough.
On my PC it uses slightly less CPU even than xv (even with=20
sync-to-vblank enabled).
As always comments or test results are welcome.
Greetings,
Reimar D=F6ffinger
--------------010405090309040607050200
Content-Type: text/plain;
name="vo_gl.c"
Content-Disposition: inline;
filename="vo_gl.c"
Content-Transfer-Encoding: quoted-printable
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "config.h"
#include "mp_msg.h"
#include "video_out.h"
#include "video/vfcap.h"
#include "video/img_format.h"
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <GL/glx.h>
#define DEFAULT_INTERNAL_FORMAT GL_RGB
typedef enum {
VO_GL_NO_CONV, VO_GL_REG_COMB_CONV, VO_GL_FRAG_PROG_CONV
} glConvType;
struct vo_buffer_priv_s {
GLuint planeTexture[4];
GLuint glDisplayList;
};
struct vo_priv_s {
Window window;
Display *display;
int img_width;
int img_height;
int d_width;
int d_height;
char numPlanes;
GLint planeInternalFormat[4];
GLsizei planeTextureWidth[4];
GLsizei planeTextureHeight[4];
int planeWidth[4];
int planeHeight[4];
char planeBytesPerPixel[4];
GLenum planeFormat[4];
GLenum planeType[4];
glConvType conversion;
char supportYUV;
char useGL12;
XVisualInfo vinfo;
GLXContext context;
glConvType bestYUVConversion;
void (APIENTRY * glCombinerParameterfv) (GLenum, const GLfloat *);
void (APIENTRY * glCombinerParameteri) (GLenum, GLint);
void (APIENTRY * glCombinerInput) (GLenum, GLenum, GLenum, GLenum, GLen=
um,
GLenum);
void (APIENTRY * glCombinerOutput) (GLenum, GLenum, GLenum, GLenum, GLe=
num,
GLenum, GLenum, GLboolean, GLboolea=
n,
GLboolean);
void (APIENTRY * glActiveTexture) (GLenum);
void (APIENTRY * glMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
};
static void resize (vo_instance_t * vo, int src[4])
{
mp_msg (MSGT_VO, MSGL_V, "[gl] resize ");
mp_msg (MSGT_VO, MSGL_V, "(%i, %i, %i, %i),", vo->x, vo->y, vo->w, vo->=
h);
if (src)
mp_msg (MSGT_VO, MSGL_V, "(%i, %i, %i, %i)\n", src[0], src[1], src[2]=
,
src[3]);
else
mp_msg (MSGT_VO, MSGL_V, "NULL\n");
glViewport (vo->x, vo->y, vo->w, vo->h);
if (src) {
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
// FIXME: how do we find out when we should flip ??
glTranslatef (-src[0], -src[1], 0);
glOrtho (0, src[2], src[3], 0, -1, 1);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
}
static void getGLFunctions (vo_instance_t * vo)
{
GLint maxGeneralCombiners;
GLint maxTextureUnits;
vo->priv->glCombinerParameterfv =3D
glXGetProcAddressARB ("glCombinerParameterfvNV");
vo->priv->glCombinerParameteri =3D
glXGetProcAddressARB ("glCombinerParameteriNV");
vo->priv->glCombinerInput =3D glXGetProcAddressARB ("glCombinerInputNV"=
);
vo->priv->glCombinerOutput =3D glXGetProcAddressARB ("glCombinerOutputN=
V");
vo->priv->glActiveTexture =3D glXGetProcAddressARB ("glActiveTextureARB=
");
vo->priv->glMultiTexCoord2f =3D glXGetProcAddressARB ("glMultiTexCoord2=
fARB");
glGetIntegerv (GL_MAX_GENERAL_COMBINERS_NV, &maxGeneralCombiners);
glGetIntegerv (GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
if (maxTextureUnits >=3D 3 && maxGeneralCombiners >=3D 2)
vo->priv->bestYUVConversion =3D VO_GL_REG_COMB_CONV;
else
vo->priv->bestYUVConversion =3D VO_GL_NO_CONV;
}
static int control (vo_instance_t * vo, int request, void *data, ...)
{
switch (request) {
case VOCTRL_SET_WINDOW:
vo->priv->window =3D *((Window *) data);
if (!vo->priv->context) {
vo->priv->context =3D
glXCreateContext (vo->priv->display, &vo->priv->vinfo, NULL, Tr=
ue);
} else
glFinish ();
glXMakeCurrent (vo->priv->display, vo->priv->window, vo->priv->cont=
ext);
return VO_TRUE;
case VOCTRL_MOVE_DEST:
vo->x =3D ((int *) data)[0];
vo->y =3D ((int *) data)[1];
resize (vo, NULL);
return VO_TRUE;
case VOCTRL_RESIZE_DEST:
vo->w =3D ((int *) data)[0];
vo->h =3D ((int *) data)[1];
resize (vo, NULL);
return VO_TRUE;
case VOCTRL_RESIZE_SRC:
resize (vo, data);
return VO_TRUE;
}
return VO_NOTIMPL;
}
static unsigned int query_format (vo_instance_t * vo,
unsigned int format, int width, int hei=
ght)
{
const int supported =3D
VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP |
VFCAP_HWSCALE_DOWN | VFCAP_FLIP;
switch (format) {
case IMGFMT_RGB8:
case IMGFMT_RGB15:
case IMGFMT_RGB16:
case IMGFMT_RGB24:
case IMGFMT_RGB32:
case IMGFMT_BGR8:
case IMGFMT_BGR15:
case IMGFMT_BGR16:
case IMGFMT_BGR24:
case IMGFMT_BGR32:
case IMGFMT_Y800:
case IMGFMT_YV12:
return supported;
}
return 0;
}
static void uninit (vo_instance_t * vo)
{
if (vo->priv->context)
glXDestroyContext (vo->priv->display, vo->priv->context);
free (vo->priv);
free (vo);
}
typedef struct {
int pixelBytes;
GLint internalFormat;
GLenum format;
GLenum type;
int width_div;
int height_div;
} PlaneInfo;
typedef struct {
unsigned int format;
char numPlanes;
PlaneInfo plane[4];
} FormatInfo;
FormatInfo formatInfos[] =3D {
{
IMGFMT_RGB8, 1, {
{1, 0, GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 1, 1},
}
}, {
IMGFMT_RGB15, 1, {
{2, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 1, 1},
}
}, {
IMGFMT_RGB16, 1, {
{2, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 1, 1},
}
}, {
IMGFMT_RGB24, 1, {
{3, 0, GL_RGB, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
IMGFMT_RGB32, 1, {
{4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
IMGFMT_BGR8, 1, {
{1, 0, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 1, 1},
}
}, {
IMGFMT_BGR15, 1, {
{2, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 1, 1},
}
}, {
IMGFMT_BGR16, 1, {
{2, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, 1},
}
}, {
IMGFMT_BGR24, 1, {
{3, 0, GL_BGR, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
IMGFMT_BGR32, 1, {
{4, 0, GL_BGRA, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
IMGFMT_Y800, 1, {
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
IMGFMT_YV12, 3, {
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1},
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 2, 2},
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 2, 2},
}
}, {
IMGFMT_444P, 3, {
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1},
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1},
{1, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1},
}
}, {
0, 0, {
{0, 0, 0, 0, 0, 0},
}
}
};
static void analyzeFormat (vo_instance_t * vo, unsigned int format)
{
int i =3D 0;
FormatInfo *fi;
while (formatInfos[i].format !=3D 0 && formatInfos[i].format !=3D forma=
t)
i++;
if (formatInfos[i].format !=3D format) {
mp_msg (MSGT_VO, MSGL_ERR,
"[gl] Unknown image format. This shouldn't happen!\n");
};
fi =3D &formatInfos[i];
vo->priv->numPlanes =3D fi->numPlanes;
for (i =3D 0; i < fi->numPlanes; i++) {
vo->priv->planeWidth[i] =3D vo->priv->img_width / fi->plane[i].width_=
div;
vo->priv->planeHeight[i] =3D vo->priv->img_height / fi->plane[i].heig=
ht_div;
vo->priv->planeBytesPerPixel[i] =3D fi->plane[i].pixelBytes;
if (fi->plane[i].internalFormat !=3D 0)
vo->priv->planeInternalFormat[i] =3D fi->plane[i].internalFormat;
else
vo->priv->planeInternalFormat[i] =3D DEFAULT_INTERNAL_FORMAT;
vo->priv->planeFormat[i] =3D fi->plane[i].format;
vo->priv->planeType[i] =3D fi->plane[i].type;
}
}
static void findTextureSizes (vo_instance_t * vo)
{
int i, tmp;
for (i =3D 0; i < vo->priv->numPlanes; i++) {
tmp =3D 1;
while (tmp < vo->priv->planeWidth[i])
tmp *=3D 2;
vo->priv->planeTextureWidth[i] =3D tmp;
tmp =3D 1;
while (tmp < vo->priv->planeHeight[i])
tmp *=3D 2;
vo->priv->planeTextureHeight[i] =3D tmp;
}
}
static void createTextures (vo_instance_t * vo, vo_buffer_t * buf)
{
int i;
char *texInitData =3D NULL;
char initVal =3D 0;
GLfloat borderColor[4];
int size;
glGenTextures (vo->priv->numPlanes, buf->priv->planeTexture);
for (i =3D 0; i < vo->priv->numPlanes; i++) {
glActiveTexture (GL_TEXTURE0 + i);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[i]);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
mp_msg (MSGT_VO, MSGL_V,
"[gl] Allocating texture of size %dx%d ...\n",
vo->priv->planeTextureWidth[i], vo->priv->planeTextureHeight[=
i]);
size =3D vo->priv->planeTextureWidth[i] * vo->priv->planeTextureHeigh=
t[i];
texInitData =3D malloc (size);
if (i =3D=3D 0) {
borderColor[0] =3D 0.0;
borderColor[1] =3D 0.0;
borderColor[2] =3D 0.0;
borderColor[3] =3D 0.0;
initVal =3D 0;
} else { // no green borders in YUV
borderColor[0] =3D 0.5;
borderColor[1] =3D 0.5;
borderColor[2] =3D 0.5;
borderColor[3] =3D 0.0;
initVal =3D 128;
}
memset (texInitData, initVal, size);
glTexImage2D (GL_TEXTURE_2D, 0, vo->priv->planeInternalFormat[i],
vo->priv->planeTextureWidth[i],
vo->priv->planeTextureHeight[i], 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, texInitData);
mp_msg (MSGT_VO, MSGL_V, "[gl] glTexImage2D finished with %d\n",
glGetError ());
free (texInitData);
glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor=
);
}
}
static void setupConversion (vo_instance_t * vo)
{
int i;
GLfloat ucoef[] =3D { 0, -0.344, 1.770, 0 };
GLfloat vcoef[] =3D { 1.403, -0.714, 0, 0 };
switch (vo->priv->conversion) {
case VO_GL_NO_CONV:
break;
case VO_GL_REG_COMB_CONV:
// It seems that coefficient must be in [0,1] range, so here comes
// the trick:
// first put them in [-0.5, 0.5] range, then add 0.5;
// can be undone with the HALF_BIAS and SCALE_BY_FOUR arguments
// for CombinerInput and CombinerOutput
for (i =3D 0; i < 4; i++) {
ucoef[i] =3D ucoef[i] * 0.25 + 0.5;
vcoef[i] =3D vcoef[i] * 0.25 + 0.5;
}
vo->priv->glCombinerParameterfv (GL_CONSTANT_COLOR0_NV, ucoef);
vo->priv->glCombinerParameterfv (GL_CONSTANT_COLOR1_NV, vcoef);
// UV first, like this green component can't overflow
vo->priv->glCombinerInput (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_N=
V,
GL_TEXTURE1, GL_HALF_BIAS_NORMAL_NV, GL_=
RGB);
vo->priv->glCombinerInput (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_N=
V,
GL_CONSTANT_COLOR0_NV,
GL_HALF_BIAS_NORMAL_NV, GL_RGB);
vo->priv->glCombinerInput (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_N=
V,
GL_TEXTURE2, GL_HALF_BIAS_NORMAL_NV, GL_=
RGB);
vo->priv->glCombinerInput (GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_N=
V,
GL_CONSTANT_COLOR1_NV,
GL_HALF_BIAS_NORMAL_NV, GL_RGB);
vo->priv->glCombinerOutput (GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV,
GL_DISCARD_NV, GL_SPARE0_NV,
GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE,
GL_FALSE, GL_FALSE);
vo->priv->glCombinerInput (GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_N=
V,
GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_=
RGB);
vo->priv->glCombinerInput (GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_N=
V,
GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
vo->priv->glCombinerInput (GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_C_N=
V,
GL_TEXTURE0, GL_SIGNED_IDENTITY_NV, GL_R=
GB);
vo->priv->glCombinerInput (GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_D_N=
V,
GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
vo->priv->glCombinerOutput (GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV,
GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE,
GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
// leave final combiner stage in default mode
vo->priv->glCombinerParameteri (GL_NUM_GENERAL_COMBINERS_NV, 2);
break;
case VO_GL_FRAG_PROG_CONV:
break;
default:
mp_msg (MSGT_VO, MSGL_ERR, "[gl] unknown conversion type!");
break;
}
}
static void activateConversion (vo_instance_t * vo, vo_buffer_t * buf)
{
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[0]);
switch (vo->priv->conversion) {
case VO_GL_NO_CONV:
break;
case VO_GL_REG_COMB_CONV:
vo->priv->glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[0]);
vo->priv->glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[2]);
vo->priv->glActiveTexture (GL_TEXTURE2);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[1]);
glEnable (GL_REGISTER_COMBINERS_NV);
break;
case VO_GL_FRAG_PROG_CONV:
break;
default:
mp_msg (MSGT_VO, MSGL_ERR, "[gl] unknown conversion type!");
break;
}
}
static void deactivateConversion (vo_instance_t * vo, vo_buffer_t * buf)
{
switch (vo->priv->conversion) {
case VO_GL_NO_CONV:
break;
case VO_GL_REG_COMB_CONV:
glDisable (GL_REGISTER_COMBINERS_NV);
break;
case VO_GL_FRAG_PROG_CONV:
break;
default:
mp_msg (MSGT_VO, MSGL_ERR, "[gl] unknown conversion type!");
break;
}
}
static void createDisplayList (vo_instance_t * vo, vo_buffer_t * buf)
{
int i;
GLfloat xcov[4], ycov[4];
buf->priv->glDisplayList =3D glGenLists (1);
for (i =3D 0; i < vo->priv->numPlanes; i++) {
xcov[i] =3D
(GLfloat) vo->priv->planeWidth[i] /
(GLfloat) vo->priv->planeTextureWidth[i];
ycov[i] =3D
(GLfloat) vo->priv->planeHeight[i] /
(GLfloat) vo->priv->planeTextureHeight[i];
}
// TODO: set this at an appropriate place to a useable default
if (vo->priv->numPlanes =3D=3D 3)
vo->priv->conversion =3D vo->priv->bestYUVConversion;
setupConversion (vo);
glNewList (buf->priv->glDisplayList, GL_COMPILE);
activateConversion (vo, buf);
glBegin (GL_QUADS);
for (i =3D 0; i < vo->priv->numPlanes; i++)
glMultiTexCoord2f (GL_TEXTURE0 + i, 0, 0);
glVertex2i (0, 0);
for (i =3D 0; i < vo->priv->numPlanes; i++)
glMultiTexCoord2f (GL_TEXTURE0 + i, xcov[i], 0);
glVertex2i (vo->priv->img_width, 0);
for (i =3D 0; i < vo->priv->numPlanes; i++)
glMultiTexCoord2f (GL_TEXTURE0 + i, xcov[i], ycov[i]);
glVertex2i (vo->priv->img_width, vo->priv->img_height);
for (i =3D 0; i < vo->priv->numPlanes; i++)
glMultiTexCoord2f (GL_TEXTURE0 + i, 0, ycov[i]);
glVertex2i (0, vo->priv->img_height);
glEnd ();
deactivateConversion (vo, buf);
glEndList ();
}
static int config (vo_instance_t * vo, int width, int height,
int d_width, int d_height, unsigned int format)
{
int dest_coords[] =3D { 0, 0, width, height };
vo->priv->img_width =3D width;
vo->priv->img_height =3D height;
vo->priv->d_width =3D d_width;
vo->priv->d_height =3D d_height;
vo->buffer_w =3D width;
vo->buffer_h =3D height;
vo->w =3D d_width;
vo->h =3D d_height;
getGLFunctions (vo);
analyzeFormat (vo, format);
findTextureSizes (vo);
glDisable (GL_BLEND);
glDisable (GL_DEPTH_TEST);
glDepthMask (GL_FALSE);
glDisable (GL_CULL_FACE);
glClearColor (0, 0, 0, 0);
resize (vo, dest_coords);
return VO_TRUE;
}
static void updateTexture (vo_instance_t * vo, vo_buffer_t * buf, int pla=
neNr,
int x, int y, int w, int h, unsigned char *dat=
a)
{
mp_msg (MSGT_VO, MSGL_DBG1, "[gl] updateTexture (%i, %i, %i, %i, %i, %x=
)\n",
planeNr, x, y, w, h, data);
glBindTexture (GL_TEXTURE_2D, buf->priv->planeTexture[planeNr]);
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, w, h,
vo->priv->planeFormat[planeNr],
vo->priv->planeType[planeNr], data);
mp_msg (MSGT_VO, MSGL_DBG1, "[gl] glTexSubImage2D finished with %d\n",
glGetError ());
}
static void draw_slice (vo_instance_t * vo, vo_buffer_t * buf,
unsigned char *src[], int stride[], int w, int h,
int x, int y)
{
mp_msg (MSGT_VO, MSGL_DBG1, "[gl] draw_slice\n");
}
static int frame_done (vo_instance_t * vo, vo_buffer_t * buf)
{
int i;
mp_msg (MSGT_VO, MSGL_DBG1, "[gl] frame_done\n");
for (i =3D 0; i < vo->priv->numPlanes; i++)
updateTexture (vo, buf, i, 0, 0, vo->priv->planeWidth[i],
vo->priv->planeHeight[i], buf->planes[i]);
glFlush ();
return 0;
}
static void show_frame (vo_instance_t * vo, vo_buffer_t * buf,
unsigned int time_pos)
{
mp_msg (MSGT_VO, MSGL_DBG1, "[gl] show_frame\n");
glCallList (buf->priv->glDisplayList);
glXSwapBuffers (vo->priv->display, vo->priv->window);
glClear (GL_COLOR_BUFFER_BIT);
}
static vo_buffer_t *get_buffer (vo_instance_t * vo)
{
int i;
vo_buffer_t *buffer =3D calloc (sizeof (vo_buffer_t), 1);
buffer->priv =3D calloc (sizeof (struct vo_buffer_priv_s), 1);
createTextures (vo, buffer);
createDisplayList (vo, buffer);
buffer->status =3D 0;
for (i =3D 0; i < vo->priv->numPlanes; i++) {
buffer->planes[i] =3D
calloc (vo->priv->planeWidth[i] * vo->priv->planeHeight[i] *
vo->priv->planeBytesPerPixel[i], 1);
buffer->stride[i] =3D
vo->priv->planeWidth[i] * vo->priv->planeBytesPerPixel[i];
}
return buffer;
}
static void release_buffer (vo_instance_t * vo, vo_buffer_t * buf)
{
int i;
for (i =3D 0; i < vo->priv->numPlanes; i++)
free (buf->planes[i]);
glDeleteLists (buf->priv->glDisplayList, 1);
glDeleteTextures (vo->priv->numPlanes, buf->priv->planeTexture);
free (buf->priv);
free (buf);
}
static vo_instance_t *preinit (char *args, void *x11_display)
{
vo_instance_t *vo;
if (!x11_display)
return NULL; // X11 not available
vo =3D calloc (sizeof (vo_instance_t), 1);
vo->priv =3D calloc (sizeof (struct vo_priv_s), 1);
memset (vo->priv, 0, sizeof (struct vo_priv_s));
vo->priv->useGL12 =3D 1;
vo->priv->supportYUV =3D 0;
vo->priv->display =3D x11_display;
XMatchVisualInfo (vo->priv->display, DefaultScreen (vo->priv->display),=
24,
TrueColor, &vo->priv->vinfo);
#if 0
if (arg) {
if (strcmp (arg, "gl11") =3D=3D 0) {
useGL12 =3D 0;
} else if (strcmp (arg, "glyuv") =3D=3D 0) {
supportYUV =3D 1;
} else {
printf ("[gl] Unknown subdevice: %s\n", arg);
return ENOSYS;
}
}
#endif
vo->buffer_flags =3D 0;
vo->num_buffers =3D 0;
// functions:
vo->query_format =3D query_format;
vo->control =3D control;
vo->config =3D config;
vo->draw_slice =3D draw_slice;
vo->frame_done =3D frame_done;
vo->show_frame =3D show_frame;
vo->uninit =3D uninit;
vo->get_buffer =3D get_buffer;
vo->release_buffer =3D release_buffer;
return vo;
}
vo_info_t vo_driver_gl =3D {
MODULE_TYPE_VO, MODULE_VERSION, preinit, "gl", "OpenGL driver",
"Reimar D=F6ffinger", "Reimar D=F6ffinger", NULL,
VO_MODULE_CAPS_X11 | VO_MODULE_CAPS_WINDOW | VO_MODULE_CAPS_GUI, NULL,
NULL, 0
};
--------------010405090309040607050200
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
MPlayer-G2-dev mailing list
[email protected]
http://mplayerhq.hu/mailman/listinfo/mplayer-g2-dev
--------------010405090309040607050200--