mirror of
https://github.com/mpv-player/mpv
synced 2024-12-30 02:52:10 +00:00
Improved NV12/NV21 support.
- Fixed PlanarToNV12Wrapper() and made it handle NV21. - Added yuv2nv12XinC() to handle software scaling. - 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. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14716 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
078b838090
commit
c260a1139d
@ -356,6 +356,7 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
|
||||
//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 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
|
||||
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;
|
||||
|
@ -188,6 +188,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt)
|
||||
case IMGFMT_Y800:
|
||||
case IMGFMT_Y8:
|
||||
case IMGFMT_NV12:
|
||||
case IMGFMT_NV21:
|
||||
case IMGFMT_444P:
|
||||
case IMGFMT_422P:
|
||||
case IMGFMT_411P:
|
||||
|
@ -130,7 +130,6 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt)
|
||||
case IMGFMT_I420:
|
||||
case IMGFMT_IYUV:
|
||||
case IMGFMT_CLPL:
|
||||
case IMGFMT_NV12:
|
||||
case IMGFMT_444P:
|
||||
case IMGFMT_422P:
|
||||
case IMGFMT_411P:
|
||||
|
@ -56,6 +56,8 @@ static unsigned int outfmt_list[]={
|
||||
IMGFMT_YVU9,
|
||||
IMGFMT_IF09,
|
||||
IMGFMT_411P,
|
||||
IMGFMT_NV12,
|
||||
IMGFMT_NV21,
|
||||
IMGFMT_YUY2,
|
||||
IMGFMT_UYVY,
|
||||
// RGB and grayscale (Y8 and Y800):
|
||||
@ -175,6 +177,8 @@ static int config(struct vf_instance_s* vf,
|
||||
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:
|
||||
|
@ -528,7 +528,6 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){
|
||||
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 @@ static unsigned int fmt_list[]={
|
||||
IMGFMT_CLPL,
|
||||
IMGFMT_Y800,
|
||||
IMGFMT_Y8,
|
||||
IMGFMT_NV12,
|
||||
IMGFMT_444P,
|
||||
IMGFMT_422P,
|
||||
IMGFMT_411P,
|
||||
|
@ -101,6 +101,7 @@ untested special converters
|
||||
|
||||
//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)
|
||||
@ -114,6 +115,7 @@ untested special converters
|
||||
#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))
|
||||
|
||||
@ -251,6 +253,56 @@ static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilt
|
||||
}
|
||||
}
|
||||
|
||||
static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
|
||||
int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
|
||||
uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
|
||||
{
|
||||
//FIXME Optimize (just quickly writen not opti..)
|
||||
int i;
|
||||
for(i=0; i<dstW; i++)
|
||||
{
|
||||
int val=1<<18;
|
||||
int j;
|
||||
for(j=0; j<lumFilterSize; j++)
|
||||
val += lumSrc[j][i] * lumFilter[j];
|
||||
|
||||
dest[i]= MIN(MAX(val>>19, 0), 255);
|
||||
}
|
||||
|
||||
if(uDest == NULL)
|
||||
return;
|
||||
|
||||
if(dstFormat == IMGFMT_NV12)
|
||||
for(i=0; i<chrDstW; i++)
|
||||
{
|
||||
int u=1<<18;
|
||||
int v=1<<18;
|
||||
int j;
|
||||
for(j=0; j<chrFilterSize; j++)
|
||||
{
|
||||
u += chrSrc[j][i] * chrFilter[j];
|
||||
v += chrSrc[j][i + 2048] * chrFilter[j];
|
||||
}
|
||||
|
||||
uDest[2*i]= MIN(MAX(u>>19, 0), 255);
|
||||
uDest[2*i+1]= MIN(MAX(v>>19, 0), 255);
|
||||
}
|
||||
else
|
||||
for(i=0; i<chrDstW; i++)
|
||||
{
|
||||
int u=1<<18;
|
||||
int v=1<<18;
|
||||
int j;
|
||||
for(j=0; j<chrFilterSize; j++)
|
||||
{
|
||||
u += chrSrc[j][i] * chrFilter[j];
|
||||
v += chrSrc[j][i + 2048] * chrFilter[j];
|
||||
}
|
||||
|
||||
uDest[2*i]= MIN(MAX(v>>19, 0), 255);
|
||||
uDest[2*i+1]= MIN(MAX(u>>19, 0), 255);
|
||||
}
|
||||
}
|
||||
|
||||
#define YSCALE_YUV_2_PACKEDX_C(type) \
|
||||
for(i=0; i<(dstW>>1); i++){\
|
||||
@ -1379,13 +1431,16 @@ static int PlanarToNV12Wrapper(SwsContext *c, uint8_t* src[], int srcStride[], i
|
||||
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;
|
||||
}
|
||||
@ -1555,6 +1610,15 @@ static inline void sws_orderYUV(int format, uint8_t * sortedP[], int sortedStrid
|
||||
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");
|
||||
}
|
||||
@ -1645,6 +1709,8 @@ static void getSubSampleFactors(int *h, int *v, int format){
|
||||
break;
|
||||
case IMGFMT_YV12:
|
||||
case IMGFMT_Y800: //FIXME remove after different subsamplings are fully implemented
|
||||
case IMGFMT_NV12:
|
||||
case IMGFMT_NV21:
|
||||
*h=1;
|
||||
*v=1;
|
||||
break;
|
||||
@ -1873,7 +1939,7 @@ SwsContext *sws_getContext(int srcW, int srcH, int origSrcFormat, int dstW, int
|
||||
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;
|
||||
}
|
||||
|
@ -796,6 +796,15 @@ yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void RENAME(yuv2nv12X)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
|
||||
int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
|
||||
uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
|
||||
{
|
||||
yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
|
||||
chrFilter, chrSrc, chrFilterSize,
|
||||
dest, uDest, dstW, chrDstW, dstFormat);
|
||||
}
|
||||
|
||||
static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc,
|
||||
uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
|
||||
{
|
||||
@ -2792,7 +2801,15 @@ i--;
|
||||
((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;
|
||||
}
|
||||
#endif
|
||||
if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like
|
||||
if(dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21){
|
||||
const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
|
||||
if(dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
|
||||
RENAME(yuv2nv12X)(c,
|
||||
vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
|
||||
vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
|
||||
dest, uDest, dstW, chrDstW, dstFormat);
|
||||
}
|
||||
else if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like
|
||||
{
|
||||
const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
|
||||
if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
|
||||
@ -2840,7 +2857,15 @@ i--;
|
||||
{
|
||||
int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
|
||||
int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
|
||||
if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12
|
||||
if(dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21){
|
||||
const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
|
||||
if(dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
|
||||
yuv2nv12XinC(
|
||||
vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize,
|
||||
vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
|
||||
dest, uDest, dstW, chrDstW, dstFormat);
|
||||
}
|
||||
else if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12
|
||||
{
|
||||
const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
|
||||
if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
|
||||
|
Loading…
Reference in New Issue
Block a user