View difference between Paste ID: f1718874b and
SHOW: | | - or go back to the newest paste.
1
--- /c/Documents and Settings/Jason/Desktop/plugin_lumimasking.c	2006-05-05 21:37:15.000000000 -0700
2
+++ ../src/plugins/plugin_lumimasking.c	2008-02-22 10:11:53.310000000 -0800
3
@@ -2,11 +2,11 @@
4
  *
5
  *  XVID MPEG-4 VIDEO CODEC
6
  *  - XviD plugin: performs a lumimasking algorithm on encoded frame  -
7
  *
8
  *  Copyright(C) 2002-2003 Peter Ross <pross@xvid.org>
9
- *               2002      Christoph Lampert <gruel@web.de>
10
+ *			   2002	  Christoph Lampert <gruel@web.de>
11
  *
12
  *  This program is free software ; you can redistribute it and/or modify
13
  *  it under the terms of the GNU General Public License as published by
14
  *  the Free Software Foundation ; either version 2 of the License, or
15
  *  (at your option) any later version.
16
@@ -23,10 +23,11 @@
17
  * $Id: plugin_lumimasking.c,v 1.6 2006/05/06 04:37:15 syskin Exp $
18
  *
19
  ****************************************************************************/
20
 
21
 #include <stdlib.h>
22
+#include <math.h>
23
 
24
 #include "../xvid.h"
25
 #include "../global.h"
26
 #include "../portab.h"
27
 #include "../utils/emms.h"
28
@@ -155,31 +156,31 @@
29
 									 int *out,
30
 									 int num,
31
 									 int min_quant,
32
 									 int max_quant);
33
 
34
-static int
35
-lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data)
36
+static int lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data)
37
 {
38
-	int i, j;
39
-
40
-	float global = 0.0f;
41
+	//Don't apply variance-masking to B-frames.
42
+	if (data->type == XVID_TYPE_BVOP) return 0;
43
 
44
-	const float DarkAmpl = 14 / 4;
45
-	const float BrightAmpl = 10 / 3;
46
-	float DarkThres = 90;
47
-	float BrightThres = 200;
48
+	int i, j;
49
 
50
-	const float GlobalDarkThres = 60;
51
-	const float GlobalBrightThres = 170;
52
+	/* Arbitrary centerpoint for variance-based AQ.  Roughly the same as used in x264. */
53
+	float center = 14000;
54
 
55
-	if (data->type == XVID_TYPE_BVOP) return 0;
56
+	/* Arbitrary strength for variance-based AQ. */
57
+	float strength = 0.2;
58
 
59
 	/* Do this for all macroblocks individually  */
60
-	for (j = 0; j < data->mb_height; j++) {
61
-		for (i = 0; i < data->mb_width; i++) {
62
-			int k, l, sum = 0;
63
+	for (j = 0; j < data->mb_height; j++)
64
+	{
65
+		for (i = 0; i < data->mb_width; i++)
66
+		{
67
+			int k, l;
68
+            unsigned int sum = 0;
69
+            unsigned int sum_of_squares = 0;
70
 			unsigned char *ptr;
71
 
72
 			/* Initialize the current quant value to the frame quant */
73
 			handle->quant[j*data->mb_width + i] = (float)data->quant;
74
 
75
@@ -187,41 +188,34 @@
76
 
77
 			/* Get the MB address */
78
 			ptr  = data->current.plane[0];
79
 			ptr += 16*j*data->current.stride[0] + 16*i;
80
 
81
-			/* Accumulate luminance */
82
+			/* Accumulate sum and sum of squares over the MB */
83
 			for (k = 0; k < 16; k++)
84
 				for (l = 0; l < 16; l++)
85
-					 sum += ptr[k*data->current.stride[0] + l];
86
+				{
87
+					int val = ptr[k*data->current.stride[0] + l];
88
+					sum += val;
89
+					sum_of_squares += val * val;
90
+				}
91
+					 
92
+			/* Variance = SSD - SAD^2 / (numpixels) */
93
+			int variance = sum_of_squares - sum * sum / 256;
94
 			
95
-			handle->val[j*data->mb_width + i] = (float)sum/256.0f;
96
-
97
-			/* Accumulate the global frame luminance */
98
-			global += (float)sum/256.0f;
99
+			handle->val[j*data->mb_width + i] = variance;
100
 		}
101
 	}
102
-
103
-	/* Normalize the global luminance accumulator */
104
-	global /= data->mb_width*data->mb_height;
105
-
106
-	DarkThres = DarkThres*global/127.0f;
107
-	BrightThres = BrightThres*global/127.0f;
108
-
109
-
110
-	/* Apply luminance masking only to frames where the global luminance is
111
-	 * higher than DarkThreshold and lower than Bright Threshold */
112
-	 if ((global < GlobalBrightThres) && (global > GlobalDarkThres)) {
113
-
114
-		/* Apply the luminance masking formulas to all MBs */
115
-		for (i = 0; i < data->mb_height; i++) {
116
-			for (j = 0; j < data->mb_width; j++) {
117
-				if (handle->val[i*data->mb_width + j] < DarkThres)
118
-					handle->quant[i*data->mb_width + j] *= 1 + DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres;
119
-				else if (handle->val[i*data->mb_width + j] > BrightThres)
120
-					handle->quant[i*data->mb_width + j] *= 1 + BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres);
121
-			}
122
+    
123
+	/* Apply the variance masking formula to all MBs */
124
+	for (i = 0; i < data->mb_height; i++)
125
+	{
126
+		for (j = 0; j < data->mb_width; j++)
127
+		{
128
+			float value = handle->val[i*data->mb_width + j];
129
+			float qscale_diff = strength * logf(value / center);
130
+			handle->quant[i*data->mb_width + j] *= (1.0 + qscale_diff);
131
 		}
132
 	}
133
 
134
 	 /* Normalize the quantizer field */
135
 	 data->quant = normalize_quantizer_field(handle->quant,
136
@@ -246,11 +240,11 @@
137
 
138
 /*****************************************************************************
139
  * Helper functions
140
  ****************************************************************************/
141
 
142
-#define RDIFF(a, b)    ((int)(a+0.5)-(int)(b+0.5))
143
+#define RDIFF(a, b)	((int)(a+0.5)-(int)(b+0.5))
144
 
145
 static int
146
 normalize_quantizer_field(float *in,
147
 						  int *out,
148
 						  int num,
149