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 |