Compute stride for other formats than YV12 correctly in xglXvPutImage. Add

some decent YUY2 conversion code and enable YUV2 image format again.
This commit is contained in:
David Reveman 2006-06-12 10:12:14 +02:00
parent 6296f79886
commit 75846b85b0
4 changed files with 290 additions and 17 deletions

View file

@ -2416,9 +2416,9 @@ mmx_pack8888 (CARD8 *image)
}
static __inline__ CARD32
loadyv12 (CARD8 *py,
CARD8 *pu,
CARD8 *pv)
loadyuv (CARD8 *py,
CARD8 *pu,
CARD8 *pv)
{
INT16 y, u, v;
INT32 r, g, b;
@ -2560,7 +2560,7 @@ loadyv12_scanline (ScanlineBuf *slb,
while (w && (unsigned long) py & 7)
{
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 1;
@ -2589,7 +2589,7 @@ loadyv12_scanline (ScanlineBuf *slb,
while (w)
{
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 1;
@ -2606,6 +2606,51 @@ loadyv12_scanline (ScanlineBuf *slb,
return slb->line[i];
}
static __inline__ CARD8 *
loadyuy2_scanline (ScanlineBuf *slb,
int y,
CARD8 *src,
int stride,
int x,
int width)
{
CARD8 *py, *pu, *pv, *pd;
int i, w;
y = _y_to_scanline (slb, y);
for (i = 0; slb->lock[i]; i++);
slb->y[i] = y;
slb->lock[i] = TRUE;
py = src + stride * (y >> 0);
pu = py + 1;
pv = py + 3;
pd = slb->line[i];
w = width;
while (w)
{
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 2;
if (w & 1)
{
pu += 4;
pv += 4;
}
w--;
}
return slb->line[i];
}
static __inline__ CARD8
interpolate_bilinear (int distx,
int idistx,
@ -2857,7 +2902,7 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
while (w && (unsigned long) py & 7)
{
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 1;
@ -2886,7 +2931,7 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
while (w)
{
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 1;
@ -2916,5 +2961,215 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
_mm_empty ();
}
/* TODO: MMX code for yuy2 */
void
fbCompositeSrc_yuy2x8888mmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
{
PictTransform *transform = pSrc->transform;
CARD8 *dst, *src;
FbBits *srcBits;
FbStride srcStride;
int srcXoff;
int srcYoff;
FbBits *dstBits;
FbStride dstStride;
int dstXoff;
int dstYoff;
int bpp, offset, w;
CARD8 *pd;
fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, bpp, srcXoff, srcYoff);
fbGetDrawable (pDst->pDrawable, dstBits, dstStride, bpp, dstXoff, dstYoff);
dst = (CARD8 *) dstBits;
dstStride *= sizeof (FbBits);
src = (CARD8 *) srcBits;
srcStride *= sizeof (FbBits);
if (transform)
{
/* transformation is a Y coordinate flip, this is achieved by
moving start offsets for each plane and changing sign of stride */
if (pSrc->transform->matrix[0][0] == (1 << 16) &&
pSrc->transform->matrix[1][1] == -(1 << 16) &&
pSrc->transform->matrix[0][2] == 0 &&
pSrc->transform->matrix[1][2] == (pSrc->pDrawable->height << 16))
{
src = src + (pSrc->pDrawable->height - 1) * srcStride;
srcStride = -srcStride;
transform = 0;
}
}
dst += dstStride * (yDst + dstYoff) + ((xDst + dstXoff) << 2);
if (transform)
{
ScanlineBuf slb;
CARD8 _scanline_buf[8192];
CARD8 *ps, *ps0, *ps1;
int x, x0, y, line, xStep, yStep;
int distx, idistx, disty, idisty;
int srcEnd = pSrc->pDrawable->width << 16;
x0 = pSrc->transform->matrix[0][2] + ((xSrc + srcXoff) << 16);
y = pSrc->transform->matrix[1][2] + ((ySrc + srcYoff) << 16);
xStep = pSrc->transform->matrix[0][0];
yStep = pSrc->transform->matrix[1][1];
init_scanline_buffer (&slb,
_scanline_buf, sizeof (_scanline_buf),
pSrc->pDrawable->width << 2,
pSrc->pDrawable->height);
while (height--)
{
disty = (y >> 8) & 0xff;
idisty = 256 - disty;
line = y >> 16;
ps0 = get_scanline (&slb, line);
ps1 = get_scanline (&slb, line + 1);
if (!ps0)
ps0 = loadyuy2_scanline (&slb, line,
src, srcStride,
0, pSrc->pDrawable->width);
if (!ps1)
ps1 = loadyuy2_scanline (&slb, line + 1,
src, srcStride,
0, pSrc->pDrawable->width);
pd = dst;
x = x0;
w = width;
if (pSrc->filter == PictFilterBilinear)
{
while (w && x < 0)
{
interpolate_bilinear_8888 (0, 256, disty, idisty,
ps0, ps1, 0, pd);
x += xStep;
pd += 4;
w -= 1;
}
while (w && x < srcEnd)
{
distx = (x >> 8) & 0xff;
idistx = 256 - distx;
interpolate_bilinear_8888 (distx, idistx, disty, idisty,
ps0, ps1, (x >> 14) & ~3, pd);
x += xStep;
pd += 4;
w -= 1;
}
while (w)
{
interpolate_bilinear_8888 (256, 0, disty, idisty,
ps0, ps1, (x >> 14) & ~3, pd);
pd += 4;
w -= 1;
}
}
else
{
while (w && x < 0)
{
*(CARD32 *) pd = *(CARD32 *) ps0;
x += xStep;
pd += 4;
w -= 1;
}
while (w && x < srcEnd)
{
*(CARD32 *) pd = ((CARD32 *) ps0)[x >> 16];
x += xStep;
pd += 4;
w -= 1;
}
while (w)
{
*(CARD32 *) pd = ((CARD32 *) ps0)[x >> 16];
pd += 4;
w -= 1;
}
}
y += yStep;
dst += dstStride;
release_scanlines (&slb);
}
fini_scanline_buffer (&slb);
}
else
{
CARD8 *py, *pu, *pv;
src += srcStride * (ySrc >> 0) + srcYoff + (xSrc + srcXoff);
while (height)
{
py = src;
pu = src + 1;
pv = src + 3;
pd = dst;
w = width;
while (w)
{
*((CARD32 *) pd) = loadyuv (py, pu, pv);
pd += 4;
py += 2;
if (w & 1)
{
pu += 4;
pv += 4;
}
w--;
}
dst += dstStride;
src += srcStride;
height--;
}
}
}
#endif /* RENDER */
#endif /* USE_MMX */

View file

@ -231,4 +231,18 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
CARD16 width,
CARD16 height);
void
fbCompositeSrc_yuy2x8888mmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
#endif /* USE_MMX */

View file

@ -874,8 +874,8 @@ fbComposite (CARD8 op,
maskAlphaMap = pMask->alphaMap != 0;
}
/* YV12 is only used internally for XVideo */
if (pSrc->format == PICT_yv12)
/* YUV is only used internally for XVideo */
if (pSrc->format == PICT_yv12 || pSrc->format == PICT_yuy2)
{
#ifdef USE_MMX
/* non rotating transformation */
@ -890,7 +890,12 @@ fbComposite (CARD8 op,
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
if (fbHaveMMX())
func = fbCompositeSrc_yv12x8888mmx;
{
if (pSrc->format == PICT_yv12)
func = fbCompositeSrc_yv12x8888mmx;
else
func = fbCompositeSrc_yuy2x8888mmx;
}
break;
}
}

View file

@ -298,7 +298,7 @@ xglXvPutImage (ClientPtr client,
ScreenPtr pScreen = pDrawable->pScreen;
PicturePtr pSrc;
PictTransform transform;
int depth, bpp, noVisual = FALSE;
int depth, bpp, stride, noVisual = FALSE;
CARD32 format;
XGL_SCREEN_PRIV (pScreen);
@ -306,11 +306,14 @@ xglXvPutImage (ClientPtr client,
XGL_DRAWABLE_PIXMAP (pDrawable);
XGL_PIXMAP_PRIV (pPixmap);
stride = ((srcWidth + 7) & ~7);
switch (pImage->id) {
case GLITZ_FOURCC_YUY2:
bpp = depth = 16;
format = PICT_yuy2;
noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YUY2].format.surface;
stride *= 2;
break;
case GLITZ_FOURCC_YV12:
depth = bpp = 12;
@ -321,6 +324,7 @@ xglXvPutImage (ClientPtr client,
depth = 24;
bpp = 32;
format = PICT_x8r8g8b8;
stride *= 4;
break;
default:
return BadImplementation;
@ -339,7 +343,7 @@ xglXvPutImage (ClientPtr client,
srcWidth, srcHeight,
depth, bpp, -1, (pointer) data);
XGL_GET_PIXMAP_PRIV (pPortPriv->pPixmap)->stride = -((srcWidth + 7) & ~7);
XGL_GET_PIXMAP_PRIV (pPortPriv->pPixmap)->stride = -stride;
pPortPriv->pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
@ -594,11 +598,6 @@ xglXvInitAdaptors (ScreenPtr pScreen)
pAdaptor->nImages = sizeof (xvImages) / sizeof (XvImageRec);
pAdaptor->pImages = xvImages;
/* XXX: Disable YUY2 format as it's not accelerated and the software
fallback got issues. */
pAdaptor->nImages = sizeof (xvImages) / sizeof (XvImageRec) - 1;
pAdaptor->pImages = &xvImages[1];
/* TODO: Currently no attributes */
pAdaptor->nAttributes = 0;
pAdaptor->pAttributes = 0;