Browse code

oops, too much cleanup ;)

Originally committed as revision 3033 to svn://svn.mplayerhq.hu/mplayer/trunk/postproc

Michael Niedermayer authored on 2001/11/21 03:07:13
Showing 2 changed files
... ...
@@ -859,6 +859,43 @@ static inline void vertX1Filter(uint8_t *src, int stride, int QP)
859 859
 #endif
860 860
 }
861 861
 
862
+/**
863
+ * Experimental Filter 1 (Horizontal)
864
+ * will not damage linear gradients
865
+ * Flat blocks should look like they where passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter
866
+ * can only smooth blocks at the expected locations (it cant smooth them if they did move)
867
+ * MMX2 version does correct clipping C version doesnt
868
+ * not identical with the vertical one
869
+ */
870
+static inline void horizX1Filter(uint8_t *src, int stride, int QP)
871
+{
872
+	int y;
873
+//FIXME (has little in common with the mmx2 version)
874
+	for(y=0; y<BLOCK_SIZE; y++)
875
+	{
876
+		int a= src[1] - src[2];
877
+		int b= src[3] - src[4];
878
+		int c= src[5] - src[6];
879
+
880
+		int d= MAX(ABS(b) - (ABS(a) + ABS(c))/2, 0);
881
+
882
+		if(d < QP)
883
+		{
884
+			int v = d * SIGN(-b);
885
+
886
+			src[1] +=v/8;
887
+			src[2] +=v/4;
888
+			src[3] +=3*v/8;
889
+			src[4] -=3*v/8;
890
+			src[5] -=v/4;
891
+			src[6] -=v/8;
892
+
893
+		}
894
+		src+=stride;
895
+	}
896
+}
897
+
898
+
862 899
 static inline void doVertDefFilter(uint8_t src[], int stride, int QP)
863 900
 {
864 901
 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
... ...
@@ -1438,6 +1475,109 @@ src-=8;
1438 1438
 #endif
1439 1439
 }
1440 1440
 
1441
+/**
1442
+ * Check if the given 8x8 Block is mostly "flat"
1443
+ */
1444
+static inline int isHorizDC(uint8_t src[], int stride)
1445
+{
1446
+	int numEq= 0;
1447
+	int y;
1448
+	for(y=0; y<BLOCK_SIZE; y++)
1449
+	{
1450
+		if(((src[0] - src[1] + 1) & 0xFFFF) < 3) numEq++;
1451
+		if(((src[1] - src[2] + 1) & 0xFFFF) < 3) numEq++;
1452
+		if(((src[2] - src[3] + 1) & 0xFFFF) < 3) numEq++;
1453
+		if(((src[3] - src[4] + 1) & 0xFFFF) < 3) numEq++;
1454
+		if(((src[4] - src[5] + 1) & 0xFFFF) < 3) numEq++;
1455
+		if(((src[5] - src[6] + 1) & 0xFFFF) < 3) numEq++;
1456
+		if(((src[6] - src[7] + 1) & 0xFFFF) < 3) numEq++;
1457
+		src+= stride;
1458
+	}
1459
+	return numEq > hFlatnessThreshold;
1460
+}
1461
+
1462
+static inline int isHorizMinMaxOk(uint8_t src[], int stride, int QP)
1463
+{
1464
+	if(abs(src[0] - src[7]) > 2*QP) return 0;
1465
+
1466
+	return 1;
1467
+}
1468
+
1469
+static inline void doHorizDefFilter(uint8_t dst[], int stride, int QP)
1470
+{
1471
+	int y;
1472
+	for(y=0; y<BLOCK_SIZE; y++)
1473
+	{
1474
+		const int middleEnergy= 5*(dst[4] - dst[5]) + 2*(dst[2] - dst[5]);
1475
+
1476
+		if(ABS(middleEnergy) < 8*QP)
1477
+		{
1478
+			const int q=(dst[3] - dst[4])/2;
1479
+			const int leftEnergy=  5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
1480
+			const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
1481
+
1482
+			int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) );
1483
+			d= MAX(d, 0);
1484
+
1485
+			d= (5*d + 32) >> 6;
1486
+			d*= SIGN(-middleEnergy);
1487
+
1488
+			if(q>0)
1489
+			{
1490
+				d= d<0 ? 0 : d;
1491
+				d= d>q ? q : d;
1492
+			}
1493
+			else
1494
+			{
1495
+				d= d>0 ? 0 : d;
1496
+				d= d<q ? q : d;
1497
+			}
1498
+
1499
+        		dst[3]-= d;
1500
+	        	dst[4]+= d;
1501
+		}
1502
+		dst+= stride;
1503
+	}
1504
+}
1505
+
1506
+/**
1507
+ * Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block)
1508
+ * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version)
1509
+ */
1510
+static inline void doHorizLowPass(uint8_t dst[], int stride, int QP)
1511
+{
1512
+
1513
+	int y;
1514
+	for(y=0; y<BLOCK_SIZE; y++)
1515
+	{
1516
+		const int first= ABS(dst[-1] - dst[0]) < QP ? dst[-1] : dst[0];
1517
+		const int last= ABS(dst[8] - dst[7]) < QP ? dst[8] : dst[7];
1518
+
1519
+		int sums[9];
1520
+		sums[0] = first + dst[0];
1521
+		sums[1] = dst[0] + dst[1];
1522
+		sums[2] = dst[1] + dst[2];
1523
+		sums[3] = dst[2] + dst[3];
1524
+		sums[4] = dst[3] + dst[4];
1525
+		sums[5] = dst[4] + dst[5];
1526
+		sums[6] = dst[5] + dst[6];
1527
+		sums[7] = dst[6] + dst[7];
1528
+		sums[8] = dst[7] + last;
1529
+
1530
+		dst[0]= ((sums[0]<<2) + ((first + sums[2])<<1) + sums[4] + 8)>>4;
1531
+		dst[1]= ((dst[1]<<2) + ((first + sums[0] + sums[3])<<1) + sums[5] + 8)>>4;
1532
+		dst[2]= ((dst[2]<<2) + ((first + sums[1] + sums[4])<<1) + sums[6] + 8)>>4;
1533
+		dst[3]= ((dst[3]<<2) + ((sums[2] + sums[5])<<1) + sums[0] + sums[7] + 8)>>4;
1534
+		dst[4]= ((dst[4]<<2) + ((sums[3] + sums[6])<<1) + sums[1] + sums[8] + 8)>>4;
1535
+		dst[5]= ((dst[5]<<2) + ((last + sums[7] + sums[4])<<1) + sums[2] + 8)>>4;
1536
+		dst[6]= (((last + dst[6])<<2) + ((dst[7] + sums[5])<<1) + sums[3] + 8)>>4;
1537
+		dst[7]= ((sums[8]<<2) + ((last + sums[6])<<1) + sums[4] + 8)>>4;
1538
+
1539
+		dst+= stride;
1540
+	}
1541
+}
1542
+
1543
+
1441 1544
 static inline void dering(uint8_t src[], int stride, int QP)
1442 1545
 {
1443 1546
 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
... ...
@@ -859,6 +859,43 @@ static inline void vertX1Filter(uint8_t *src, int stride, int QP)
859 859
 #endif
860 860
 }
861 861
 
862
+/**
863
+ * Experimental Filter 1 (Horizontal)
864
+ * will not damage linear gradients
865
+ * Flat blocks should look like they where passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter
866
+ * can only smooth blocks at the expected locations (it cant smooth them if they did move)
867
+ * MMX2 version does correct clipping C version doesnt
868
+ * not identical with the vertical one
869
+ */
870
+static inline void horizX1Filter(uint8_t *src, int stride, int QP)
871
+{
872
+	int y;
873
+//FIXME (has little in common with the mmx2 version)
874
+	for(y=0; y<BLOCK_SIZE; y++)
875
+	{
876
+		int a= src[1] - src[2];
877
+		int b= src[3] - src[4];
878
+		int c= src[5] - src[6];
879
+
880
+		int d= MAX(ABS(b) - (ABS(a) + ABS(c))/2, 0);
881
+
882
+		if(d < QP)
883
+		{
884
+			int v = d * SIGN(-b);
885
+
886
+			src[1] +=v/8;
887
+			src[2] +=v/4;
888
+			src[3] +=3*v/8;
889
+			src[4] -=3*v/8;
890
+			src[5] -=v/4;
891
+			src[6] -=v/8;
892
+
893
+		}
894
+		src+=stride;
895
+	}
896
+}
897
+
898
+
862 899
 static inline void doVertDefFilter(uint8_t src[], int stride, int QP)
863 900
 {
864 901
 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)
... ...
@@ -1438,6 +1475,109 @@ src-=8;
1438 1438
 #endif
1439 1439
 }
1440 1440
 
1441
+/**
1442
+ * Check if the given 8x8 Block is mostly "flat"
1443
+ */
1444
+static inline int isHorizDC(uint8_t src[], int stride)
1445
+{
1446
+	int numEq= 0;
1447
+	int y;
1448
+	for(y=0; y<BLOCK_SIZE; y++)
1449
+	{
1450
+		if(((src[0] - src[1] + 1) & 0xFFFF) < 3) numEq++;
1451
+		if(((src[1] - src[2] + 1) & 0xFFFF) < 3) numEq++;
1452
+		if(((src[2] - src[3] + 1) & 0xFFFF) < 3) numEq++;
1453
+		if(((src[3] - src[4] + 1) & 0xFFFF) < 3) numEq++;
1454
+		if(((src[4] - src[5] + 1) & 0xFFFF) < 3) numEq++;
1455
+		if(((src[5] - src[6] + 1) & 0xFFFF) < 3) numEq++;
1456
+		if(((src[6] - src[7] + 1) & 0xFFFF) < 3) numEq++;
1457
+		src+= stride;
1458
+	}
1459
+	return numEq > hFlatnessThreshold;
1460
+}
1461
+
1462
+static inline int isHorizMinMaxOk(uint8_t src[], int stride, int QP)
1463
+{
1464
+	if(abs(src[0] - src[7]) > 2*QP) return 0;
1465
+
1466
+	return 1;
1467
+}
1468
+
1469
+static inline void doHorizDefFilter(uint8_t dst[], int stride, int QP)
1470
+{
1471
+	int y;
1472
+	for(y=0; y<BLOCK_SIZE; y++)
1473
+	{
1474
+		const int middleEnergy= 5*(dst[4] - dst[5]) + 2*(dst[2] - dst[5]);
1475
+
1476
+		if(ABS(middleEnergy) < 8*QP)
1477
+		{
1478
+			const int q=(dst[3] - dst[4])/2;
1479
+			const int leftEnergy=  5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
1480
+			const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
1481
+
1482
+			int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) );
1483
+			d= MAX(d, 0);
1484
+
1485
+			d= (5*d + 32) >> 6;
1486
+			d*= SIGN(-middleEnergy);
1487
+
1488
+			if(q>0)
1489
+			{
1490
+				d= d<0 ? 0 : d;
1491
+				d= d>q ? q : d;
1492
+			}
1493
+			else
1494
+			{
1495
+				d= d>0 ? 0 : d;
1496
+				d= d<q ? q : d;
1497
+			}
1498
+
1499
+        		dst[3]-= d;
1500
+	        	dst[4]+= d;
1501
+		}
1502
+		dst+= stride;
1503
+	}
1504
+}
1505
+
1506
+/**
1507
+ * Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block)
1508
+ * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version)
1509
+ */
1510
+static inline void doHorizLowPass(uint8_t dst[], int stride, int QP)
1511
+{
1512
+
1513
+	int y;
1514
+	for(y=0; y<BLOCK_SIZE; y++)
1515
+	{
1516
+		const int first= ABS(dst[-1] - dst[0]) < QP ? dst[-1] : dst[0];
1517
+		const int last= ABS(dst[8] - dst[7]) < QP ? dst[8] : dst[7];
1518
+
1519
+		int sums[9];
1520
+		sums[0] = first + dst[0];
1521
+		sums[1] = dst[0] + dst[1];
1522
+		sums[2] = dst[1] + dst[2];
1523
+		sums[3] = dst[2] + dst[3];
1524
+		sums[4] = dst[3] + dst[4];
1525
+		sums[5] = dst[4] + dst[5];
1526
+		sums[6] = dst[5] + dst[6];
1527
+		sums[7] = dst[6] + dst[7];
1528
+		sums[8] = dst[7] + last;
1529
+
1530
+		dst[0]= ((sums[0]<<2) + ((first + sums[2])<<1) + sums[4] + 8)>>4;
1531
+		dst[1]= ((dst[1]<<2) + ((first + sums[0] + sums[3])<<1) + sums[5] + 8)>>4;
1532
+		dst[2]= ((dst[2]<<2) + ((first + sums[1] + sums[4])<<1) + sums[6] + 8)>>4;
1533
+		dst[3]= ((dst[3]<<2) + ((sums[2] + sums[5])<<1) + sums[0] + sums[7] + 8)>>4;
1534
+		dst[4]= ((dst[4]<<2) + ((sums[3] + sums[6])<<1) + sums[1] + sums[8] + 8)>>4;
1535
+		dst[5]= ((dst[5]<<2) + ((last + sums[7] + sums[4])<<1) + sums[2] + 8)>>4;
1536
+		dst[6]= (((last + dst[6])<<2) + ((dst[7] + sums[5])<<1) + sums[3] + 8)>>4;
1537
+		dst[7]= ((sums[8]<<2) + ((last + sums[6])<<1) + sums[4] + 8)>>4;
1538
+
1539
+		dst+= stride;
1540
+	}
1541
+}
1542
+
1543
+
1441 1544
 static inline void dering(uint8_t src[], int stride, int QP)
1442 1545
 {
1443 1546
 #if defined (HAVE_MMX2) || defined (HAVE_3DNOW)