mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-05 01:48:02 +02:00
XVideo improvements
This commit is contained in:
parent
eb16fa5323
commit
5e4ef5afc5
8 changed files with 172 additions and 26 deletions
14
ChangeLog
14
ChangeLog
|
|
@ -1,5 +1,19 @@
|
|||
2006-04-13 David Reveman <davidr@novell.com>
|
||||
|
||||
* hw/xgl/xglparse.c (xglProcessArgument, xglUseMsg):
|
||||
* hw/xgl/xglxv.c:
|
||||
* hw/xgl/egl/xeglinit.c:
|
||||
* hw/xgl/glx/xglxinit.c:
|
||||
* hw/xgl/xglinit.c:
|
||||
* hw/xgl/xglscreen.c (xglScreenInit):
|
||||
* hw/xgl/xgl.h: Add xvfilter and noyuv options. xvfilter can be used
|
||||
to set the filter used for XVideo, currently available filters are
|
||||
nearest and linear (default is linear). Nearest filter can improve
|
||||
performance signifcantly when XVideo isn't accelerated. noyuv
|
||||
option can be used to force use of software YUV to RGB conversions,
|
||||
which can improve performance when GL_ARB_fragment_program support
|
||||
isn't fast enough.
|
||||
|
||||
* fb/fbpict.c (fbComposite):
|
||||
* fb/fbmmx.h:
|
||||
* fb/fbmmx.c: Add fast YUV conversion code.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,14 @@ static xglScreenInfoRec xglScreenInfo = {
|
|||
FALSE,
|
||||
XGL_DEFAULT_PBO_MASK,
|
||||
FALSE,
|
||||
FALSE
|
||||
FALSE,
|
||||
FilterBilinear,
|
||||
{
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } }
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef GLXEXT
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ xglScreenInfoRec xglScreenInfo = {
|
|||
FALSE,
|
||||
XGL_DEFAULT_PBO_MASK,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FilterBilinear,
|
||||
{
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ typedef struct _xglScreenInfo {
|
|||
Bool yInverted;
|
||||
int pboMask;
|
||||
Bool lines;
|
||||
Bool noYuv;
|
||||
char *xvFilter;
|
||||
xglScreenAccelInfoRec accel;
|
||||
} xglScreenInfoRec, *xglScreenInfoPtr;
|
||||
|
||||
|
|
@ -255,6 +257,8 @@ typedef struct _xglScreen {
|
|||
Bool yInverted;
|
||||
int pboMask;
|
||||
Bool lines;
|
||||
Bool noYuv;
|
||||
char *xvFilter;
|
||||
xglGeometryRec scratchGeometry;
|
||||
xglScreenAccelInfoRec accel;
|
||||
|
||||
|
|
@ -372,6 +376,7 @@ typedef struct _xglXvPort {
|
|||
PixmapPtr pPixmap;
|
||||
PicturePtr pSrc;
|
||||
PicturePtr pDst;
|
||||
PicturePtr pTmp;
|
||||
} xglXvPortRec, *xglXvPortPtr;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ xglScreenInfoRec xglScreenInfo = {
|
|||
FALSE,
|
||||
XGL_DEFAULT_PBO_MASK,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FilterBilinear,
|
||||
{
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
{ FALSE, FALSE, { 0, 0, 0, 0 } },
|
||||
|
|
|
|||
|
|
@ -188,6 +188,13 @@ xglUseMsg (void)
|
|||
ErrorF ("-yinverted Y is upside-down\n");
|
||||
ErrorF ("-lines "
|
||||
"accelerate lines that are not vertical or horizontal\n");
|
||||
ErrorF ("-noyuv "
|
||||
"turns off hardware color-space conversion of YUV data\n");
|
||||
|
||||
#ifdef XV
|
||||
ErrorF ("-xvfilter [nearest|linear] set xvideo filter\n");
|
||||
#endif
|
||||
|
||||
ErrorF ("-vbo "
|
||||
"use vertex buffer objects for streaming of vertex data\n");
|
||||
ErrorF ("-pbomask [1|4|8|16|32] "
|
||||
|
|
@ -225,6 +232,29 @@ xglProcessArgument (int argc,
|
|||
xglScreenInfo.lines = TRUE;
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp (argv[i], "-noyuv"))
|
||||
{
|
||||
xglScreenInfo.noYuv = TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef XV
|
||||
else if (!strcmp (argv[i], "-xvfilter"))
|
||||
{
|
||||
if ((i + 1) < argc)
|
||||
{
|
||||
if (!strcasecmp (argv[i + 1], "nearest"))
|
||||
xglScreenInfo.xvFilter = FilterNearest;
|
||||
else if (!strcasecmp (argv[i + 1], "linear"))
|
||||
xglScreenInfo.xvFilter = FilterBilinear;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (!strcmp (argv[i], "-vbo"))
|
||||
{
|
||||
xglScreenInfo.geometryUsage = GEOMETRY_USAGE_STREAM;
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ xglScreenInit (ScreenPtr pScreen)
|
|||
pScreenPriv->yInverted = xglScreenInfo.yInverted;
|
||||
pScreenPriv->pboMask = xglScreenInfo.pboMask;
|
||||
pScreenPriv->lines = xglScreenInfo.lines;
|
||||
pScreenPriv->noYuv = xglScreenInfo.noYuv;
|
||||
pScreenPriv->xvFilter = xglScreenInfo.xvFilter;
|
||||
pScreenPriv->accel = xglScreenInfo.accel;
|
||||
|
||||
if (monitorResolution)
|
||||
|
|
|
|||
134
hw/xgl/xglxv.c
134
hw/xgl/xglxv.c
|
|
@ -200,6 +200,12 @@ xglXvFreePort (XvPortPtr pPort)
|
|||
pPortPriv->pSrc = (PicturePtr) 0;
|
||||
}
|
||||
|
||||
if (pPortPriv->pTmp)
|
||||
{
|
||||
FreePicture ((pointer) pPortPriv->pTmp, 0);
|
||||
pPortPriv->pTmp = (PicturePtr) 0;
|
||||
}
|
||||
|
||||
if (pPortPriv->pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen;
|
||||
|
|
@ -239,6 +245,37 @@ xglXvStopVideo (ClientPtr client,
|
|||
return Success;
|
||||
}
|
||||
|
||||
static PicturePtr
|
||||
xglXvCreateDstPict (DrawablePtr pDrawable,
|
||||
Mask vmask,
|
||||
XID *vlist,
|
||||
int *error)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
PictFormatPtr pFormat = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScreen->numVisuals; i++)
|
||||
{
|
||||
if (pScreen->visuals[i].nplanes == pDrawable->depth)
|
||||
{
|
||||
pFormat = PictureMatchVisual (pScreen, pDrawable->depth,
|
||||
&pScreen->visuals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pFormat)
|
||||
{
|
||||
*error = BadImplementation;
|
||||
return (PicturePtr) 0;
|
||||
}
|
||||
|
||||
return CreatePicture (0, pDrawable,
|
||||
pFormat, vmask, vlist, serverClient,
|
||||
error);
|
||||
}
|
||||
|
||||
static int
|
||||
xglXvPutImage (ClientPtr client,
|
||||
DrawablePtr pDrawable,
|
||||
|
|
@ -259,8 +296,9 @@ xglXvPutImage (ClientPtr client,
|
|||
CARD16 height)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
PicturePtr pSrc;
|
||||
PictTransform transform;
|
||||
int depth, bpp;
|
||||
int depth, bpp, noVisual = FALSE;
|
||||
CARD32 format;
|
||||
|
||||
XGL_SCREEN_PRIV (pScreen);
|
||||
|
|
@ -272,10 +310,12 @@ xglXvPutImage (ClientPtr client,
|
|||
case GLITZ_FOURCC_YUY2:
|
||||
bpp = depth = 16;
|
||||
format = PICT_yuy2;
|
||||
noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YUY2].format.surface;
|
||||
break;
|
||||
case GLITZ_FOURCC_YV12:
|
||||
depth = bpp = 12;
|
||||
format = PICT_yv12;
|
||||
noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YV12].format.surface;
|
||||
break;
|
||||
case GLITZ_FOURCC_RGB:
|
||||
depth = 24;
|
||||
|
|
@ -326,34 +366,21 @@ xglXvPutImage (ClientPtr client,
|
|||
}
|
||||
|
||||
SetPictureFilter (pPortPriv->pSrc,
|
||||
FilterBilinear, strlen (FilterBilinear),
|
||||
pScreenPriv->xvFilter,
|
||||
strlen (pScreenPriv->xvFilter),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
pSrc = pPortPriv->pSrc;
|
||||
|
||||
if (!pPortPriv->pDst || pPortPriv->pDst->pDrawable != pDrawable)
|
||||
{
|
||||
PictFormatPtr pFormat = 0;
|
||||
int i, error;
|
||||
|
||||
for (i = 0; i < pScreen->numVisuals; i++)
|
||||
{
|
||||
if (pScreen->visuals[i].nplanes == pDrawable->depth)
|
||||
{
|
||||
pFormat = PictureMatchVisual (pScreen, pDrawable->depth,
|
||||
&pScreen->visuals[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pFormat)
|
||||
return BadImplementation;
|
||||
int error;
|
||||
|
||||
if (pPortPriv->pDst)
|
||||
FreePicture ((pointer) pPortPriv->pDst, 0);
|
||||
|
||||
pPortPriv->pDst = CreatePicture (0, pDrawable,
|
||||
pFormat, 0, 0, serverClient,
|
||||
&error);
|
||||
pPortPriv->pDst = xglXvCreateDstPict (pDrawable, 0, NULL, &error);
|
||||
if (!pPortPriv->pDst)
|
||||
{
|
||||
xglXvFreePort (pPort);
|
||||
|
|
@ -361,6 +388,66 @@ xglXvPutImage (ClientPtr client,
|
|||
}
|
||||
}
|
||||
|
||||
if (pPixmap != pScreenPriv->pScreenPixmap && !pPixmapPriv->target)
|
||||
xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.xv);
|
||||
|
||||
/* software color-space conversion */
|
||||
if (pPixmapPriv->target && (noVisual || pScreenPriv->noYuv))
|
||||
{
|
||||
if (!pPortPriv->pTmp ||
|
||||
srcWidth != pPortPriv->pTmp->pDrawable->width ||
|
||||
srcHeight != pPortPriv->pTmp->pDrawable->height)
|
||||
{
|
||||
static XID value = RepeatPad;
|
||||
int error;
|
||||
|
||||
if (pPortPriv->pTmp)
|
||||
FreePicture ((pointer) pPortPriv->pTmp, 0);
|
||||
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen,
|
||||
srcWidth, srcHeight,
|
||||
pDrawable->depth);
|
||||
if (!pPixmap)
|
||||
{
|
||||
xglXvFreePort (pPort);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
pPortPriv->pTmp = xglXvCreateDstPict (&pPixmap->drawable,
|
||||
CPRepeat, &value,
|
||||
&error);
|
||||
if (!pPortPriv->pTmp)
|
||||
{
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
xglXvFreePort (pPort);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* no accelerated drawing */
|
||||
XGL_GET_PIXMAP_PRIV (pPixmap)->target = xglPixmapTargetNo;
|
||||
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
|
||||
SetPictureFilter (pPortPriv->pTmp,
|
||||
pScreenPriv->xvFilter,
|
||||
strlen (pScreenPriv->xvFilter),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
SetPictureTransform (pSrc, 0);
|
||||
|
||||
CompositePicture (PictOpSrc,
|
||||
pSrc,
|
||||
(PicturePtr) 0,
|
||||
pPortPriv->pTmp,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
srcWidth, srcHeight);
|
||||
|
||||
pSrc = pPortPriv->pTmp;
|
||||
}
|
||||
|
||||
transform.matrix[0][0] = ((srcWidth << 16) + (dstWidth >> 1))
|
||||
/ dstWidth;
|
||||
transform.matrix[0][1] = 0;
|
||||
|
|
@ -376,13 +463,10 @@ xglXvPutImage (ClientPtr client,
|
|||
transform.matrix[2][1] = 0;
|
||||
transform.matrix[2][2] = 1 << 16;
|
||||
|
||||
SetPictureTransform (pPortPriv->pSrc, &transform);
|
||||
|
||||
if (pPixmap != pScreenPriv->pScreenPixmap && !pPixmapPriv->target)
|
||||
xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.xv);
|
||||
SetPictureTransform (pSrc, &transform);
|
||||
|
||||
CompositePicture (PictOpSrc,
|
||||
pPortPriv->pSrc,
|
||||
pSrc,
|
||||
(PicturePtr) 0,
|
||||
pPortPriv->pDst,
|
||||
srcX, srcY,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue