Revision c7a810cc

View differences:

postproc/swscale.c
266 266
}
267 267
#endif
268 268

  
269
static int testFormat[]={
270
IMGFMT_YV12,
271
//IMGFMT_IYUV,
272
IMGFMT_I420,
273
IMGFMT_BGR15,
274
IMGFMT_BGR16,
275
IMGFMT_BGR24,
276
IMGFMT_BGR32,
277
//IMGFMT_Y8,
278
IMGFMT_Y800,
279
//IMGFMT_YUY2,
280
0
281
};
282

  
283
static uint64_t getSSD(uint8_t *src1, uint8_t *src2, int stride1, int stride2, int w, int h){
284
	int x,y;
285
	uint64_t ssd=0;
286

  
287
	for(y=0; y<h; y++){
288
		for(x=0; x<w; x++){
289
			int d= src1[x + y*stride1] - src2[x + y*stride2];
290
			ssd+= d*d;
291
		}
292
	}
293
	return ssd;
294
}
295

  
296
// test by ref -> src -> dst -> out & compare out against ref
297
// ref & out are YV12
298
static void doTest(uint8_t *ref[3], int refStride[3], int w, int h, int srcFormat, int dstFormat, 
299
                   int srcW, int srcH, int dstW, int dstH, int flags){
300
	uint8_t *src[3];
301
	uint8_t *dst[3];
302
	uint8_t *out[3];
303
	int srcStride[3], dstStride[3];
304
	int i;
305
	uint64_t ssdY, ssdU, ssdV;
306
	SwsContext *srcContext, *dstContext, *outContext;
307
	
308
	for(i=0; i<3; i++){
309
		srcStride[i]= srcW*4;
310
		dstStride[i]= dstW*4;
311
		src[i]= malloc(srcStride[i]*srcH);
312
		dst[i]= malloc(dstStride[i]*dstH);
313
		out[i]= malloc(refStride[i]*h);
314
	}
315

  
316
	srcContext= getSwsContext(w, h, IMGFMT_YV12, srcW, srcH, srcFormat, flags, NULL, NULL);
317
	dstContext= getSwsContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, NULL, NULL);
318
	outContext= getSwsContext(dstW, dstH, dstFormat, w, h, IMGFMT_YV12, flags, NULL, NULL);
319
	if(srcContext==NULL ||dstContext==NULL ||outContext==NULL){
320
		printf("Failed allocating swsContext\n");
321
		goto end;
322
	}
323
//	printf("test %X %X %X -> %X %X %X\n", (int)ref[0], (int)ref[1], (int)ref[2],
324
//		(int)src[0], (int)src[1], (int)src[2]);
325

  
326
	srcContext->swScale(srcContext, ref, refStride, 0, h   , src, srcStride);
327
	dstContext->swScale(dstContext, src, srcStride, 0, srcH, dst, dstStride);
328
	outContext->swScale(outContext, dst, dstStride, 0, dstH, out, refStride);
329
	     
330
	ssdY= getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
331
	ssdU= getSSD(ref[1], out[1], refStride[1], refStride[1], (w+1)>>1, (h+1)>>1);
332
	ssdV= getSSD(ref[2], out[2], refStride[2], refStride[2], (w+1)>>1, (h+1)>>1);
333
	
334
	if(isGray(srcFormat) || isGray(dstFormat)) ssdU=ssdV=0; //FIXME check that output is really gray
335
	
336
	ssdY/= w*h;
337
	ssdU/= w*h/4;
338
	ssdV/= w*h/4;
339
	
340
	if(ssdY>10 || ssdU>10 || ssdV>10){
341
		printf(" %s %dx%d -> %s %4dx%4d flags=%2d SSD=%5lld,%5lld,%5lld\n", 
342
			vo_format_name(srcFormat), srcW, srcH, 
343
			vo_format_name(dstFormat), dstW, dstH,
344
			flags,
345
			ssdY, ssdU, ssdV);
346
	}
347

  
348
	end:
349
	
350
	freeSwsContext(srcContext);
351
	freeSwsContext(dstContext);
352
	freeSwsContext(outContext);
353

  
354
	for(i=0; i<3; i++){
355
		free(src[i]);
356
		free(dst[i]);
357
		free(out[i]);
358
	}
359
}
360

  
361
static void selfTest(uint8_t *src[3], int stride[3], int w, int h){
362
	int srcFormat, dstFormat, srcFormatIndex, dstFormatIndex;
363
	int srcW, srcH, dstW, dstH;
364
	int flags;
365

  
366
	for(srcFormatIndex=0; ;srcFormatIndex++){
367
		srcFormat= testFormat[srcFormatIndex];
368
		if(!srcFormat) break;
369
		for(dstFormatIndex=0; ;dstFormatIndex++){
370
			dstFormat= testFormat[dstFormatIndex];
371
			if(!dstFormat) break;
372
			if(!isSupportedOut(dstFormat)) continue;
373

  
374
			srcW= w+w/3;
375
			srcH= h+h/3;
376
			for(dstW=w; dstW<w*2; dstW+= dstW/3){
377
				for(dstH=h; dstH<h*2; dstH+= dstH/3){
378
					for(flags=1; flags<33; flags*=2)
379
						doTest(src, stride, w, h, srcFormat, dstFormat,
380
							srcW, srcH, dstW, dstH, flags);
381
				}
382
			}
383
		}
384
	}
385
}
386

  
269 387
static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,
270 388
				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,
271 389
				    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW)
......
1540 1658
/**
1541 1659
 * bring pointers in YUV order instead of YVU
1542 1660
 */
1543
static inline void orderYUV(SwsContext *c, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]){
1544
	if(c->srcFormat == IMGFMT_YV12){
1661
static inline void orderYUV(int format, uint8_t * sortedP[], int sortedStride[], uint8_t * p[], int stride[]){
1662
	if(format == IMGFMT_YV12){
1545 1663
		sortedP[0]= p[0];
1546 1664
		sortedP[1]= p[1];
1547 1665
		sortedP[2]= p[2];
1548
		sortedStride[0]= sortedStride[0];
1549
		sortedStride[1]= sortedStride[1];
1550
		sortedStride[2]= sortedStride[2];
1666
		sortedStride[0]= stride[0];
1667
		sortedStride[1]= stride[1];
1668
		sortedStride[2]= stride[2];
1551 1669
	}
1552
	else if(isPacked(c->srcFormat) || isGray(c->srcFormat))
1670
	else if(isPacked(format) || isGray(format))
1553 1671
	{
1554 1672
		sortedP[0]= p[0];
1555 1673
		sortedP[1]= 
1556 1674
		sortedP[2]= NULL;
1557
		sortedStride[0]= sortedStride[0];
1675
		sortedStride[0]= stride[0];
1558 1676
		sortedStride[1]= 
1559 1677
		sortedStride[2]= 0;
1560 1678
	}
......
1563 1681
		sortedP[0]= p[0];
1564 1682
		sortedP[1]= p[2];
1565 1683
		sortedP[2]= p[1];
1566
		sortedStride[0]= sortedStride[0];
1567
		sortedStride[1]= sortedStride[2];
1568
		sortedStride[2]= sortedStride[1];
1684
		sortedStride[0]= stride[0];
1685
		sortedStride[1]= stride[2];
1686
		sortedStride[2]= stride[1];
1569 1687
	}
1570 1688
}
1571 1689

  
......
1578 1696
	uint8_t *src[3];
1579 1697
	uint8_t *dst[3];
1580 1698

  
1581
	orderYUV(c, src, srcStride, srcParam, srcStrideParam);
1582
	orderYUV(c, dst, dstStride, dstParam, dstStrideParam);
1699
	orderYUV(c->srcFormat, src, srcStride, srcParam, srcStrideParam);
1700
	orderYUV(c->dstFormat, dst, dstStride, dstParam, dstStrideParam);
1583 1701

  
1584 1702
	if(isPacked(c->srcFormat))
1585 1703
	{
......
1650 1768
	}
1651 1769
}
1652 1770

  
1771
static void getSubSampleFactors(int *h, int *v, int format){
1772
	switch(format){
1773
	case IMGFMT_YUY2:
1774
		*h=1;
1775
		*v=0;
1776
		break;
1777
	case IMGFMT_YV12:
1778
	case IMGFMT_I420:
1779
		*h=1;
1780
		*v=1;
1781
		break;
1782
	case IMGFMT_YVU9:
1783
		*h=2;
1784
		*v=2;
1785
		break;
1786
	default:
1787
		*h=0;
1788
		*v=0;
1789
		break;
1790
	}
1791
}
1792

  
1653 1793
SwsContext *getSwsContext(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags,
1654 1794
                         SwsFilter *srcFilter, SwsFilter *dstFilter){
1655 1795

  
......
1925 2065
	else
1926 2066
		c->canMMX2BeUsed=0;
1927 2067

  
2068
	getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
2069
	getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
1928 2070

  
1929
	/* dont use full vertical UV input/internaly if the source doesnt even have it */
1930
	if(isHalfChrV(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_V);
1931
	/* dont use full horizontal UV input if the source doesnt even have it */
1932
	if(isHalfChrH(srcFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INP);
1933
	/* dont use full horizontal UV internally if the destination doesnt even have it */
1934
	if(isHalfChrH(dstFormat)) c->flags= flags= flags&(~SWS_FULL_CHR_H_INT);
2071
	// reuse chroma for 2 pixles rgb/bgr unless user wants full chroma interpolation
2072
	if((isBGR(dstFormat) || isRGB(dstFormat)) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1;
1935 2073

  
1936
	if(flags&SWS_FULL_CHR_H_INP)	c->chrSrcW= srcW;
1937
	else				c->chrSrcW= (srcW+1)>>1;
2074
	// drop eery 2. pixel for chroma calculation unless user wants full chroma
2075
	if((isBGR(srcFormat) || isRGB(srcFormat) || srcFormat==IMGFMT_YUY2) && !(flags&SWS_FULL_CHR_V)) 
2076
		c->chrSrcVSubSample=1;
1938 2077

  
1939
	if(flags&SWS_FULL_CHR_H_INT)	c->chrDstW= dstW;
1940
	else				c->chrDstW= (dstW+1)>>1;
1941

  
1942
	if(flags&SWS_FULL_CHR_V)	c->chrSrcH= srcH;
1943
	else				c->chrSrcH= (srcH+1)>>1;
1944

  
1945
	if(isHalfChrV(dstFormat))	c->chrDstH= (dstH+1)>>1;
1946
	else				c->chrDstH= dstH;
2078
	// drop eery 2. pixel for chroma calculation unless user wants full chroma
2079
	if((isBGR(srcFormat) || isRGB(srcFormat)) && !(flags&SWS_FULL_CHR_H_INP)) 
2080
		c->chrSrcHSubSample=1;
1947 2081

  
2082
	c->chrIntHSubSample= c->chrDstHSubSample;
2083
	c->chrIntVSubSample= c->chrSrcVSubSample;
2084
	
2085
	// note the -((-x)>>y) is so that we allways round toward +inf
2086
	c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);
2087
	c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);
2088
	c->chrDstW= -((-dstW) >> c->chrDstHSubSample);
2089
	c->chrDstH= -((-dstH) >> c->chrDstVSubSample);
2090
/*	printf("%d %d %d %d / %d %d %d %d //\n", 
2091
	c->chrSrcW,
2092
c->chrSrcH,
2093
c->chrDstW,
2094
c->chrDstH,
2095
srcW,
2096
srcH,
2097
dstW,
2098
dstH);*/
1948 2099
	c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;
1949 2100
	c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;
1950 2101

  
1951

  
1952 2102
	// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst
1953 2103
	// but only for the FAST_BILINEAR mode otherwise do correct scaling
1954 2104
	// n-2 is the last chrominance sample available
postproc/swscale.h
43 43
	int lumXInc, chrXInc;
44 44
	int lumYInc, chrYInc;
45 45
	int dstFormat, srcFormat;
46
	int chrSrcHSubSample, chrSrcVSubSample;
47
	int chrIntHSubSample, chrIntVSubSample;
48
	int chrDstHSubSample, chrDstVSubSample;
46 49

  
47 50
	int16_t **lumPixBuf;
48 51
	int16_t **chrPixBuf;
postproc/swscale_template.c
2669 2669
		dstStride[1]= dstStrideParam[1];
2670 2670
		dstStride[2]= dstStrideParam[2];
2671 2671
	}
2672
	
2673
//	printf("swscale %X %X %X -> %X %X %X\n", (int)src[0], (int)src[1], (int)src[2],
2674
//		(int)dst[0], (int)dst[1], (int)dst[2]);
2675

  
2676
#if 0 //self test FIXME move to a vfilter or something
2677
{
2678
static volatile int i=0;
2679
i++;
2680
if(srcFormat==IMGFMT_YV12 && i==1 && srcSliceH>= c->srcH)
2681
	selfTest(src, srcStride, c->srcW, c->srcH);
2682
i--;
2683
}
2684
#endif
2672 2685

  
2673 2686
//printf("sws Strides:%d %d %d -> %d %d %d\n", srcStride[0],srcStride[1],srcStride[2],
2674 2687
//dstStride[0],dstStride[1],dstStride[2]);

Also available in: Unified diff