[cvs] / xvidcore / src / plugins / plugin_lumimasking.c Repository:
ViewVC logotype

Annotation of /xvidcore/src/plugins/plugin_lumimasking.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.2.5 - (view) (download)

1 : edgomez 1.1.2.2 /*****************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - XviD plugin: performs a lumimasking algorithm on encoded frame -
5 :     *
6 :     * Copyright(C) 2002-2003 Peter Ross <pross@xvid.org>
7 :     * 2002 Christoph Lampert <gruel@web.de>
8 :     *
9 :     * This program is free software ; you can redistribute it and/or modify
10 :     * it under the terms of the GNU General Public License as published by
11 :     * the Free Software Foundation ; either version 2 of the License, or
12 :     * (at your option) any later version.
13 :     *
14 :     * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 :     *
19 :     * You should have received a copy of the GNU General Public License
20 :     * along with this program ; if not, write to the Free Software
21 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     *
23 : edgomez 1.1.2.4 * $Id$
24 : edgomez 1.1.2.2 *
25 :     ****************************************************************************/
26 :    
27 : edgomez 1.1.2.4 #include <stdlib.h>
28 : edgomez 1.1.2.3
29 : suxen_drol 1.1.2.1 #include "../xvid.h"
30 : edgomez 1.1.2.3 #include "../portab.h"
31 :    
32 : edgomez 1.1.2.5 /*****************************************************************************
33 :     * Private data type
34 :     ****************************************************************************/
35 : edgomez 1.1.2.3
36 : edgomez 1.1.2.5 typedef struct
37 :     {
38 :     float *quant;
39 :     float *val;
40 :     } lumi_data_t;
41 : edgomez 1.1.2.3
42 :     /*****************************************************************************
43 : edgomez 1.1.2.5 * Sub plugin functions
44 : edgomez 1.1.2.3 ****************************************************************************/
45 :    
46 : edgomez 1.1.2.5 static int lumi_plg_info(xvid_plg_info_t *info);
47 :     static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle);
48 :     static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy);
49 :     static int lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data);
50 :     static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data);
51 : edgomez 1.1.2.3
52 :     /*****************************************************************************
53 : edgomez 1.1.2.5 * The plugin entry function
54 : edgomez 1.1.2.3 ****************************************************************************/
55 :    
56 :     int
57 :     xvid_plugin_lumimasking(void * handle, int opt, void * param1, void * param2)
58 :     {
59 : edgomez 1.1.2.5 switch(opt) {
60 :     case XVID_PLG_INFO:
61 :     return(lumi_plg_info((xvid_plg_info_t*)param1));
62 :     case XVID_PLG_CREATE:
63 :     return(lumi_plg_create((xvid_plg_create_t *)param1, (lumi_data_t **)param2));
64 :     case XVID_PLG_DESTROY:
65 :     return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1));
66 :     case XVID_PLG_BEFORE :
67 :     return(lumi_plg_before((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
68 :     case XVID_PLG_AFTER :
69 :     return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
70 : edgomez 1.1.2.3 }
71 :    
72 : edgomez 1.1.2.5 return(XVID_ERR_FAIL);
73 :     }
74 : edgomez 1.1.2.3
75 : edgomez 1.1.2.5 /*----------------------------------------------------------------------------
76 :     * Info plugin function
77 :     *--------------------------------------------------------------------------*/
78 : edgomez 1.1.2.3
79 : edgomez 1.1.2.5 static int
80 :     lumi_plg_info(xvid_plg_info_t *info)
81 :     {
82 :     /* We just require a diff quant array access */
83 :     info->flags = XVID_REQDQUANTS;
84 :     return(0);
85 :     }
86 :    
87 :     /*----------------------------------------------------------------------------
88 :     * Create plugin function
89 :     *
90 :     * Allocates the private plugin data arrays
91 :     *--------------------------------------------------------------------------*/
92 : edgomez 1.1.2.3
93 : edgomez 1.1.2.5 static int
94 :     lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle)
95 :     {
96 :     lumi_data_t *lumi;
97 :    
98 :     if ((lumi = (lumi_data_t*)malloc(sizeof(lumi_data_t))) == NULL)
99 :     return(XVID_ERR_MEMORY);
100 :    
101 :     lumi->quant = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));
102 :     if (lumi->quant == NULL) {
103 :     free(lumi);
104 :     return(XVID_ERR_MEMORY);
105 : edgomez 1.1.2.3 }
106 :    
107 : edgomez 1.1.2.5 lumi->val = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));
108 :     if (lumi->val == NULL) {
109 :     free(lumi->quant);
110 :     free(lumi);
111 :     return(XVID_ERR_MEMORY);
112 : edgomez 1.1.2.3 }
113 :    
114 : edgomez 1.1.2.5 /* Bind the data structure to the handle */
115 :     *handle = lumi;
116 :    
117 :     return(0);
118 :     }
119 :    
120 :     /*----------------------------------------------------------------------------
121 :     * Destroy plugin function
122 :     *
123 :     * Free the private plugin data arrays
124 :     *--------------------------------------------------------------------------*/
125 :    
126 :     static int
127 :     lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t *destroy)
128 :     {
129 :     if (handle) {
130 :     if (handle->quant) {
131 :     free(handle->quant);
132 :     handle->quant = NULL;
133 :     }
134 :     if (handle->val) {
135 :     free(handle->val);
136 :     handle->val = NULL;
137 :     }
138 :     free(handle);
139 :     }
140 :     return(0);
141 :     }
142 :    
143 :     /*----------------------------------------------------------------------------
144 :     * Before plugin function
145 :     *
146 :     * Here is all the magic about lumimasking.
147 :     *--------------------------------------------------------------------------*/
148 :    
149 :     /* Helper function defined later */
150 :     static int normalize_quantizer_field(float *in,
151 :     int *out,
152 :     int num,
153 :     int min_quant,
154 :     int max_quant);
155 :    
156 :     static int
157 :     lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data)
158 :     {
159 :     int i, j;
160 :    
161 :     float global = 0.0f;
162 :     uint32_t mid_range = 0;
163 :    
164 :     const float DarkAmpl = 14 / 2;
165 :     const float BrightAmpl = 10 / 2;
166 :     const float DarkThres = 70;
167 :     const float BrightThres = 200;
168 :    
169 :     const float GlobalDarkThres = 60;
170 :     const float GlobalBrightThres = 170;
171 :    
172 :     const float MidRangeThres = 20;
173 :     const float UpperLimit = 200;
174 :     const float LowerLimit = 25;
175 :    
176 :     /* Do this for all macroblocks individually */
177 :     for (j = 0; j < data->mb_height; j++) {
178 :     for (i = 0; i < data->mb_width; i++) {
179 :     int k, l;
180 :     unsigned char *ptr;
181 :    
182 :     /* Initialize the current quant value to the frame quant */
183 :     handle->quant[j*data->mb_width + i] = (float)data->quant;
184 :    
185 :     /* Reset the val value */
186 :     handle->val[j*data->mb_width + i] = 0.0f;
187 :    
188 :     /* Next steps compute the luminance-masking */
189 :    
190 :     /* Get the MB address */
191 :     ptr = data->current.plane[0];
192 :     ptr += 16*j*data->current.stride[0] + 16*i;
193 :    
194 :     /* Accumulate luminance */
195 :     for (k = 0; k < 16; k++)
196 :     for (l = 0; l < 16; l++)
197 :     handle->val[j*data->mb_width + i] += ptr[k*data->current.stride[0] + l];
198 :    
199 :     /* Normalize its value */
200 :     handle->val[j*data->mb_width + i] /= 256.0f;
201 :    
202 :     /* Accumulate the global frame luminance */
203 :     global += handle->val[j*data->mb_width + i];
204 :    
205 :     /* Count the number of middle luminance blocks */
206 :     if ((handle->val[j*data->mb_width + i] > LowerLimit) &&
207 :     (handle->val[j*data->mb_width + i] < UpperLimit))
208 :     mid_range++;
209 :     }
210 :     }
211 :    
212 :     /* Normalize the global luminance accumulator */
213 :     global /= data->mb_width*data->mb_height;
214 :    
215 :     /* Apply luminance masking only to frames where the global luminance is
216 :     * higher than DarkThreshold and lower than Bright Threshold, or where
217 :     * "middle" luminance blocks are lower than its corresponding threshold */
218 :     if (((global < GlobalBrightThres) && (global > GlobalDarkThres)) ||
219 :     (mid_range < MidRangeThres)) {
220 :    
221 :     /* Apply the luminance masking formulas to all MBs */
222 :     for (i = 0; i < data->mb_height; i++) {
223 :     for (j = 0; j < data->mb_width; j++) {
224 :     if (handle->val[i*data->mb_width + j] < DarkThres)
225 :     handle->quant[i*data->mb_width + j] += DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres;
226 :     else if (handle->val[i*data->mb_width + j] > BrightThres)
227 :     handle->quant[i*data->mb_width + j] += BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres);
228 :     }
229 :     }
230 :     }
231 :    
232 :     /* Normalize the quantizer field */
233 :     data->quant = normalize_quantizer_field(handle->quant,
234 :     data->dquant,
235 :     data->mb_width*data->mb_height,
236 :     data->quant,
237 :     data->quant*2);
238 :    
239 :     /* Plugin job finished */
240 :     return(0);
241 :     }
242 :    
243 :     /*----------------------------------------------------------------------------
244 :     * After plugin function (dummy function)
245 :     *--------------------------------------------------------------------------*/
246 :    
247 :     static int
248 :     lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data)
249 :     {
250 :     return(0);
251 : edgomez 1.1.2.3 }
252 :    
253 :     /*****************************************************************************
254 :     * Helper functions
255 :     ****************************************************************************/
256 :    
257 : edgomez 1.1.2.5 #define RDIFF(a, b) ((int)(a+0.5)-(int)(b+0.5))
258 : suxen_drol 1.1.2.1
259 : edgomez 1.1.2.3 static int
260 :     normalize_quantizer_field(float *in,
261 :     int *out,
262 :     int num,
263 :     int min_quant,
264 :     int max_quant)
265 : suxen_drol 1.1.2.1 {
266 : edgomez 1.1.2.3 int i;
267 :     int finished;
268 :    
269 :     do {
270 :     finished = 1;
271 :     for (i = 1; i < num; i++) {
272 :     if (RDIFF(in[i], in[i - 1]) > 2) {
273 :     in[i] -= (float) 0.5;
274 :     finished = 0;
275 :     } else if (RDIFF(in[i], in[i - 1]) < -2) {
276 :     in[i - 1] -= (float) 0.5;
277 :     finished = 0;
278 :     }
279 :    
280 :     if (in[i] > max_quant) {
281 :     in[i] = (float) max_quant;
282 :     finished = 0;
283 :     }
284 :     if (in[i] < min_quant) {
285 :     in[i] = (float) min_quant;
286 :     finished = 0;
287 :     }
288 :     if (in[i - 1] > max_quant) {
289 :     in[i - 1] = (float) max_quant;
290 :     finished = 0;
291 :     }
292 :     if (in[i - 1] < min_quant) {
293 :     in[i - 1] = (float) min_quant;
294 :     finished = 0;
295 :     }
296 :     }
297 :     } while (!finished);
298 :    
299 :     out[0] = 0;
300 :     for (i = 1; i < num; i++)
301 :     out[i] = RDIFF(in[i], in[i - 1]);
302 :    
303 :     return (int) (in[0] + 0.5);
304 : suxen_drol 1.1.2.1 }

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4