Revision 6118e52e

View differences:

postproc/swscale.c
101 101

  
102 102
//FIXME replace this with something faster
103 103
#define isPlanarYUV(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YVU9 \
104
			|| (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21 \
104 105
			|| (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P)
105 106
#define isYUV(x)       ((x)==IMGFMT_UYVY || (x)==IMGFMT_YUY2 || isPlanarYUV(x))
106 107
#define isGray(x)      ((x)==IMGFMT_Y800)
......
114 115
#define isSupportedOut(x) ((x)==IMGFMT_YV12 || (x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY\
115 116
			|| (x)==IMGFMT_444P || (x)==IMGFMT_422P || (x)==IMGFMT_411P\
116 117
			|| isRGB(x) || isBGR(x)\
118
			|| (x)==IMGFMT_NV12 || (x)==IMGFMT_NV21\
117 119
			|| (x)==IMGFMT_Y800 || (x)==IMGFMT_YVU9)
118 120
#define isPacked(x)    ((x)==IMGFMT_YUY2 || (x)==IMGFMT_UYVY ||isRGB(x) || isBGR(x))
119 121

  
......
251 253
		}
252 254
}
253 255

  
256
static inline void yuv2nv12XinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
257
				int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
258
				uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
259
{
260
	//FIXME Optimize (just quickly writen not opti..)
261
	int i;
262
	for(i=0; i<dstW; i++)
263
	{
264
		int val=1<<18;
265
		int j;
266
		for(j=0; j<lumFilterSize; j++)
267
			val += lumSrc[j][i] * lumFilter[j];
268

  
269
		dest[i]= MIN(MAX(val>>19, 0), 255);
270
	}
271

  
272
	if(uDest == NULL)
273
		return;
274

  
275
	if(dstFormat == IMGFMT_NV12)
276
		for(i=0; i<chrDstW; i++)
277
		{
278
			int u=1<<18;
279
			int v=1<<18;
280
			int j;
281
			for(j=0; j<chrFilterSize; j++)
282
			{
283
				u += chrSrc[j][i] * chrFilter[j];
284
				v += chrSrc[j][i + 2048] * chrFilter[j];
285
			}
286

  
287
			uDest[2*i]= MIN(MAX(u>>19, 0), 255);
288
			uDest[2*i+1]= MIN(MAX(v>>19, 0), 255);
289
		}
290
	else
291
		for(i=0; i<chrDstW; i++)
292
		{
293
			int u=1<<18;
294
			int v=1<<18;
295
			int j;
296
			for(j=0; j<chrFilterSize; j++)
297
			{
298
				u += chrSrc[j][i] * chrFilter[j];
299
				v += chrSrc[j][i + 2048] * chrFilter[j];
300
			}
301

  
302
			uDest[2*i]= MIN(MAX(v>>19, 0), 255);
303
			uDest[2*i+1]= MIN(MAX(u>>19, 0), 255);
304
		}
305
}
254 306

  
255 307
#define YSCALE_YUV_2_PACKEDX_C(type) \
256 308
		for(i=0; i<(dstW>>1); i++){\
......
1379 1431
		uint8_t *dstPtr= dst;
1380 1432
		for(i=0; i<srcSliceH; i++)
1381 1433
		{
1382
			memcpy(dstPtr, srcPtr, srcStride[0]);
1434
			memcpy(dstPtr, srcPtr, c->srcW);
1383 1435
			srcPtr+= srcStride[0];
1384 1436
			dstPtr+= dstStride[0];
1385 1437
		}
1386 1438
	}
1387
	dst = dstParam[1] + dstStride[1]*srcSliceY;
1388
	interleaveBytes( src[1],src[2],dst,c->srcW,srcSliceH,srcStride[1],srcStride[2],dstStride[0] );
1439
	dst = dstParam[1] + dstStride[1]*srcSliceY/2;
1440
	if (c->dstFormat == IMGFMT_NV12)
1441
		interleaveBytes( src[1],src[2],dst,c->srcW/2,srcSliceH/2,srcStride[1],srcStride[2],dstStride[0] );
1442
	else
1443
		interleaveBytes( src[2],src[1],dst,c->srcW/2,srcSliceH/2,srcStride[2],srcStride[1],dstStride[0] );
1389 1444

  
1390 1445
	return srcSliceH;
1391 1446
}
......
1555 1610
		sortedStride[0]= stride[0];
1556 1611
		sortedStride[1]= stride[1];
1557 1612
		sortedStride[2]= stride[2];
1613
	}
1614
	else if(format == IMGFMT_NV12 || format == IMGFMT_NV21)
1615
	{
1616
		sortedP[0]= p[0];
1617
		sortedP[1]= p[1];
1618
		sortedP[2]= NULL;
1619
		sortedStride[0]= stride[0];
1620
		sortedStride[1]= stride[1];
1621
		sortedStride[2]= 0;
1558 1622
	}else{
1559 1623
		MSG_ERR("internal error in orderYUV\n");
1560 1624
	}
......
1645 1709
		break;
1646 1710
	case IMGFMT_YV12:
1647 1711
	case IMGFMT_Y800: //FIXME remove after different subsamplings are fully implemented
1712
	case IMGFMT_NV12:
1713
	case IMGFMT_NV21:
1648 1714
		*h=1;
1649 1715
		*v=1;
1650 1716
		break;
......
1873 1939
	if(unscaled && !usesHFilter && !usesVFilter)
1874 1940
	{
1875 1941
		/* yv12_to_nv12 */
1876
		if(srcFormat == IMGFMT_YV12 && dstFormat == IMGFMT_NV12)
1942
		if(srcFormat == IMGFMT_YV12 && (dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21))
1877 1943
		{
1878 1944
			c->swScale= PlanarToNV12Wrapper;
1879 1945
		}
postproc/swscale_template.c
796 796
#endif
797 797
}
798 798

  
799
static inline void RENAME(yuv2nv12X)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
800
				     int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
801
				     uint8_t *dest, uint8_t *uDest, int dstW, int chrDstW, int dstFormat)
802
{
803
yuv2nv12XinC(lumFilter, lumSrc, lumFilterSize,
804
	     chrFilter, chrSrc, chrFilterSize,
805
	     dest, uDest, dstW, chrDstW, dstFormat);
806
}
807

  
799 808
static inline void RENAME(yuv2yuv1)(int16_t *lumSrc, int16_t *chrSrc,
800 809
				    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)
801 810
{
......
2792 2801
				((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;
2793 2802
		}
2794 2803
#endif
2795
		if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like
2804
		if(dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21){
2805
			const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2806
			if(dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
2807
			RENAME(yuv2nv12X)(c,
2808
				vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
2809
				vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
2810
				dest, uDest, dstW, chrDstW, dstFormat);
2811
		}
2812
		else if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12 like
2796 2813
		{
2797 2814
			const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2798 2815
			if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
......
2840 2857
	    {
2841 2858
		int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
2842 2859
		int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
2843
		if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12
2860
		if(dstFormat == IMGFMT_NV12 || dstFormat == IMGFMT_NV21){
2861
			const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2862
			if(dstY&chrSkipMask) uDest= NULL; //FIXME split functions in lumi / chromi
2863
			yuv2nv12XinC(
2864
				vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
2865
				vChrFilter+chrDstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,
2866
				dest, uDest, dstW, chrDstW, dstFormat);
2867
		}
2868
		else if(isPlanarYUV(dstFormat) || isGray(dstFormat)) //YV12
2844 2869
		{
2845 2870
			const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
2846 2871
			if((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi

Also available in: Unified diff