[MPlayer-dev-eng] [PATCH] Improve NV12/NV21 support
Ville Syrjälä
syrjala at sci.fi
Sun Feb 13 02:50:49 CET 2005
The attached patch tries to make NV12/NV21 support a bit more functional.
My aim was just to get it working with DirectFB + Matrox BES so I'm not
really interested in software scaling.
Changes:
- Fixed PlanarToNV12Wrapper() and made it handle NV21.
- Added NV12/NV21 handling to various places.
- Removed NV12 from vf_hue and vf_spp as they don't look like they can
actually handle it.
- Added vDest != NULL tests to swscale since it can't actually handle
NV12/NV21. So only luma will be scaled but at least it won't crash.
Is this acceptable or do I have to add ugly private YV12->NV12 handling
like mga_vid?
--
Ville Syrjälä
syrjala at sci.fi
http://www.sci.fi/~syrjala/
-------------- next part --------------
diff -urN main/libmpcodecs/vf.c main/libmpcodecs/vf.c
--- main/libmpcodecs/vf.c 2005-01-26 00:53:46.000000000 +0200
+++ main/libmpcodecs/vf.c 2005-02-13 01:35:45.000000000 +0200
@@ -356,6 +356,7 @@
//if(!mpi->stride[0])
mpi->stride[0]=mpi->width;
//if(!mpi->stride[1])
+ if(mpi->num_planes > 2){
mpi->stride[1]=mpi->stride[2]=mpi->chroma_width;
if(mpi->flags&MP_IMGFLAG_SWAPPED){
// I420/IYUV (Y,U,V)
@@ -366,6 +367,11 @@
mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height;
mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height;
}
+ } else {
+ // NV12/NV21
+ mpi->stride[1]=mpi->chroma_width;
+ mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height;
+ }
} else {
//if(!mpi->stride[0])
mpi->stride[0]=mpi->width*mpi->bpp/8;
diff -urN main/libmpcodecs/vf_eq.c main/libmpcodecs/vf_eq.c
--- main/libmpcodecs/vf_eq.c 2004-10-25 20:05:55.000000000 +0300
+++ main/libmpcodecs/vf_eq.c 2005-02-13 01:36:02.000000000 +0200
@@ -188,6 +188,7 @@
case IMGFMT_Y800:
case IMGFMT_Y8:
case IMGFMT_NV12:
+ case IMGFMT_NV21:
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
diff -urN main/libmpcodecs/vf_hue.c main/libmpcodecs/vf_hue.c
--- main/libmpcodecs/vf_hue.c 2004-10-05 23:19:47.000000000 +0300
+++ main/libmpcodecs/vf_hue.c 2005-02-13 01:36:32.000000000 +0200
@@ -130,7 +130,6 @@
case IMGFMT_I420:
case IMGFMT_IYUV:
case IMGFMT_CLPL:
- case IMGFMT_NV12:
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
diff -urN main/libmpcodecs/vf_scale.c main/libmpcodecs/vf_scale.c
--- main/libmpcodecs/vf_scale.c 2004-11-15 23:25:47.000000000 +0200
+++ main/libmpcodecs/vf_scale.c 2005-02-13 01:37:37.000000000 +0200
@@ -56,6 +56,8 @@
IMGFMT_YVU9,
IMGFMT_IF09,
IMGFMT_411P,
+ IMGFMT_NV12,
+ IMGFMT_NV21,
IMGFMT_YUY2,
IMGFMT_UYVY,
// RGB and grayscale (Y8 and Y800):
@@ -175,6 +177,8 @@
case IMGFMT_YV12: /* YV12 needs w & h rounded to 2 */
case IMGFMT_I420:
case IMGFMT_IYUV:
+ case IMGFMT_NV12:
+ case IMGFMT_NV21:
vf->priv->h = (vf->priv->h + 1) & ~1;
case IMGFMT_YUY2: /* YUY2 needs w rounded to 2 */
case IMGFMT_UYVY:
diff -urN main/libmpcodecs/vf_spp.c main/libmpcodecs/vf_spp.c
--- main/libmpcodecs/vf_spp.c 2004-11-26 11:30:00.000000000 +0200
+++ main/libmpcodecs/vf_spp.c 2005-02-13 01:38:19.000000000 +0200
@@ -528,7 +528,6 @@
case IMGFMT_CLPL:
case IMGFMT_Y800:
case IMGFMT_Y8:
- case IMGFMT_NV12:
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
@@ -546,7 +545,6 @@
IMGFMT_CLPL,
IMGFMT_Y800,
IMGFMT_Y8,
- IMGFMT_NV12,
IMGFMT_444P,
IMGFMT_422P,
IMGFMT_411P,
diff -urN main/postproc/swscale.c main/postproc/swscale.c
--- main/postproc/swscale.c 2005-02-13 01:25:41.000000000 +0200
+++ main/postproc/swscale.c 2005-02-13 03:36:27.000000000 +0200
@@ -100,6 +100,7 @@
//FIXME replace this with something faster
#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YVU9 \
+ || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21 \
|| (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
#define isYUV(x) ((x)==IMGFMT_UYVY || (x)==IMGFMT_YUY2 || isPlanarYUV(x))
#define isGray(x) ((x)==IMGFMT_Y800)
@@ -113,6 +114,7 @@
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY\
|| (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P\
|| isRGB(x) || isBGR(x)\
+ || (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21\
|| (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9)
#define isPacked(x) ((x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY ||isRGB(x) || isBGR(x))
@@ -233,7 +235,7 @@
dest[i]= MIN(MAX(val>>19, 0), 255);
}
- if(uDest != NULL)
+ if(uDest != NULL && vDest != NULL)
for(i=0; i<chrDstW; i++)
{
int u=1<<18;
@@ -1378,13 +1380,16 @@
uint8_t *dstPtr= dst;
for(i=0; i<srcSliceH; i++)
{
- memcpy(dstPtr, srcPtr, srcStride[0]);
+ memcpy(dstPtr, srcPtr, c->srcW);
srcPtr+= srcStride[0];
dstPtr+= dstStride[0];
}
}
- dst = dstParam[1] + dstStride[1]*srcSliceY;
- interleaveBytes( src[1],src[2],dst,c->srcW,srcSliceH,srcStride[1],srcStride[2],dstStride[0] );
+ dst = dstParam[1] + dstStride[1]*srcSliceY/2;
+ if (c->dstFormat == IMGFMT_NV12)
+ interleaveBytes( src[1],src[2],dst,c->srcW/2,srcSliceH/2,srcStride[1],srcStride[2],dstStride[0] );
+ else
+ interleaveBytes( src[2],src[1],dst,c->srcW/2,srcSliceH/2,srcStride[2],srcStride[1],dstStride[0] );
return srcSliceH;
}
@@ -1554,6 +1559,15 @@
sortedStride[0]= stride[0];
sortedStride[1]= stride[1];
sortedStride[2]= stride[2];
+ }
+ else if(format == IMGFMT_NV12 || format == IMGFMT_NV21)
+ {
+ sortedP[0]= p[0];
+ sortedP[1]= p[1];
+ sortedP[2]= NULL;
+ sortedStride[0]= stride[0];
+ sortedStride[1]= stride[1];
+ sortedStride[2]= 0;
}else{
MSG_ERR("internal error in orderYUV\n");
}
@@ -1663,6 +1677,11 @@
*h=2;
*v=0;
break;
+ case IMGFMT_NV12:
+ case IMGFMT_NV21:
+ *h=1;
+ *v=1;
+ break;
default:
*h=0;
*v=0;
@@ -1872,7 +1891,7 @@
if(unscaled && !usesHFilter && !usesVFilter)
{
/* yv12_to_nv12 */
- if(srcFormat == IMGFMT_YV12 && dstFormat == IMGFMT_NV12)
+ if(srcFormat == IMGFMT_YV12 && (dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21))
{
c->swScale= PlanarToNV12Wrapper;
}
diff -urN main/postproc/swscale_template.c main/postproc/swscale_template.c
--- main/postproc/swscale_template.c 2005-01-26 00:53:50.000000000 +0200
+++ main/postproc/swscale_template.c 2005-02-13 02:33:39.000000000 +0200
@@ -760,7 +760,7 @@
uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
{
#ifdef HAVE_MMX
- if(uDest != NULL)
+ if(uDest != NULL && vDest != NULL)
{
asm volatile(
YSCALEYUV2YV12X(0, CHR_MMX_FILTER_OFFSET)
@@ -800,7 +800,7 @@
uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
{
#ifdef HAVE_MMX
- if(uDest != NULL)
+ if(uDest != NULL && vDest != NULL)
{
asm volatile(
YSCALEYUV2YV121
@@ -837,7 +837,7 @@
dest[i]= val;
}
- if(uDest != NULL)
+ if(uDest != NULL && vDest != NULL)
for(i=0; i<chrDstW; i++)
{
int u=chrSrc[i]>>7;
More information about the MPlayer-dev-eng
mailing list