[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.6 - (view) (download)

1 : edgomez 1.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 : syskin 1.6 * $Id: plugin_lumimasking.c,v 1.5 2006/04/15 04:17:02 syskin Exp $
24 : edgomez 1.2 *
25 :     ****************************************************************************/
26 :    
27 :     #include <stdlib.h>
28 :    
29 :     #include "../xvid.h"
30 : syskin 1.6 #include "../global.h"
31 : edgomez 1.2 #include "../portab.h"
32 :     #include "../utils/emms.h"
33 :    
34 :     /*****************************************************************************
35 :     * Private data type
36 :     ****************************************************************************/
37 :    
38 :     typedef struct
39 :     {
40 :     float *quant;
41 :     float *val;
42 :     } lumi_data_t;
43 :    
44 :     /*****************************************************************************
45 :     * Sub plugin functions
46 :     ****************************************************************************/
47 :    
48 :     static int lumi_plg_info(xvid_plg_info_t *info);
49 :     static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle);
50 :     static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy);
51 :     static int lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data);
52 :     static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data);
53 :    
54 :     /*****************************************************************************
55 :     * The plugin entry function
56 :     ****************************************************************************/
57 :    
58 :     int
59 :     xvid_plugin_lumimasking(void * handle, int opt, void * param1, void * param2)
60 :     {
61 :     switch(opt) {
62 :     case XVID_PLG_INFO:
63 :     return(lumi_plg_info((xvid_plg_info_t*)param1));
64 :     case XVID_PLG_CREATE:
65 :     return(lumi_plg_create((xvid_plg_create_t *)param1, (lumi_data_t **)param2));
66 :     case XVID_PLG_DESTROY:
67 :     return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1));
68 :     case XVID_PLG_BEFORE :
69 :     return 0;
70 :     case XVID_PLG_FRAME :
71 :     return(lumi_plg_frame((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
72 :     case XVID_PLG_AFTER :
73 :     return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
74 :     }
75 :    
76 :     return(XVID_ERR_FAIL);
77 :     }
78 :    
79 :     /*----------------------------------------------------------------------------
80 :     * Info plugin function
81 :     *--------------------------------------------------------------------------*/
82 :    
83 :     static int
84 :     lumi_plg_info(xvid_plg_info_t *info)
85 :     {
86 :     /* We just require a diff quant array access */
87 :     info->flags = XVID_REQDQUANTS;
88 :     return(0);
89 :     }
90 :    
91 :     /*----------------------------------------------------------------------------
92 :     * Create plugin function
93 :     *
94 :     * Allocates the private plugin data arrays
95 :     *--------------------------------------------------------------------------*/
96 :    
97 :     static int
98 :     lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle)
99 :     {
100 :     lumi_data_t *lumi;
101 :    
102 :     if ((lumi = (lumi_data_t*)malloc(sizeof(lumi_data_t))) == NULL)
103 :     return(XVID_ERR_MEMORY);
104 :    
105 :     lumi->quant = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));
106 :     if (lumi->quant == NULL) {
107 :     free(lumi);
108 :     return(XVID_ERR_MEMORY);
109 :     }
110 :    
111 :     lumi->val = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));
112 :     if (lumi->val == NULL) {
113 :     free(lumi->quant);
114 :     free(lumi);
115 :     return(XVID_ERR_MEMORY);
116 :     }
117 :    
118 :     /* Bind the data structure to the handle */
119 :     *handle = lumi;
120 :    
121 :     return(0);
122 :     }
123 :    
124 :     /*----------------------------------------------------------------------------
125 :     * Destroy plugin function
126 :     *
127 :     * Free the private plugin data arrays
128 :     *--------------------------------------------------------------------------*/
129 :    
130 :     static int
131 :     lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t *destroy)
132 :     {
133 :     if (handle) {
134 :     if (handle->quant) {
135 :     free(handle->quant);
136 :     handle->quant = NULL;
137 :     }
138 :     if (handle->val) {
139 :     free(handle->val);
140 :     handle->val = NULL;
141 :     }
142 :     free(handle);
143 :     }
144 :     return(0);
145 :     }
146 :    
147 :     /*----------------------------------------------------------------------------
148 :     * Before plugin function
149 :     *
150 :     * Here is all the magic about lumimasking.
151 :     *--------------------------------------------------------------------------*/
152 :    
153 :     /* Helper function defined later */
154 :     static int normalize_quantizer_field(float *in,
155 :     int *out,
156 :     int num,
157 :     int min_quant,
158 :     int max_quant);
159 :    
160 :     static int
161 :     lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data)
162 :     {
163 :     int i, j;
164 :    
165 :     float global = 0.0f;
166 :    
167 :     const float DarkAmpl = 14 / 4;
168 :     const float BrightAmpl = 10 / 3;
169 :     float DarkThres = 90;
170 :     float BrightThres = 200;
171 :    
172 :     const float GlobalDarkThres = 60;
173 :     const float GlobalBrightThres = 170;
174 :    
175 :     if (data->type == XVID_TYPE_BVOP) return 0;
176 :    
177 :     /* Do this for all macroblocks individually */
178 :     for (j = 0; j < data->mb_height; j++) {
179 :     for (i = 0; i < data->mb_width; i++) {
180 :     int k, l, sum = 0;
181 :     unsigned char *ptr;
182 :    
183 :     /* Initialize the current quant value to the frame quant */
184 :     handle->quant[j*data->mb_width + i] = (float)data->quant;
185 :    
186 :     /* Next steps compute the luminance-masking */
187 :    
188 :     /* Get the MB address */
189 :     ptr = data->current.plane[0];
190 :     ptr += 16*j*data->current.stride[0] + 16*i;
191 :    
192 :     /* Accumulate luminance */
193 :     for (k = 0; k < 16; k++)
194 :     for (l = 0; l < 16; l++)
195 :     sum += ptr[k*data->current.stride[0] + l];
196 :    
197 :     handle->val[j*data->mb_width + i] = (float)sum/256.0f;
198 :    
199 :     /* Accumulate the global frame luminance */
200 :     global += (float)sum/256.0f;
201 :     }
202 :     }
203 :    
204 :     /* Normalize the global luminance accumulator */
205 :     global /= data->mb_width*data->mb_height;
206 :    
207 : suxen_drol 1.3 DarkThres = DarkThres*global/127.0f;
208 :     BrightThres = BrightThres*global/127.0f;
209 : edgomez 1.2
210 :    
211 :     /* Apply luminance masking only to frames where the global luminance is
212 :     * higher than DarkThreshold and lower than Bright Threshold */
213 :     if ((global < GlobalBrightThres) && (global > GlobalDarkThres)) {
214 :    
215 :     /* Apply the luminance masking formulas to all MBs */
216 :     for (i = 0; i < data->mb_height; i++) {
217 :     for (j = 0; j < data->mb_width; j++) {
218 :     if (handle->val[i*data->mb_width + j] < DarkThres)
219 :     handle->quant[i*data->mb_width + j] *= 1 + DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres;
220 :     else if (handle->val[i*data->mb_width + j] > BrightThres)
221 :     handle->quant[i*data->mb_width + j] *= 1 + BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres);
222 :     }
223 :     }
224 :     }
225 :    
226 :     /* Normalize the quantizer field */
227 :     data->quant = normalize_quantizer_field(handle->quant,
228 :     data->dquant,
229 :     data->mb_width*data->mb_height,
230 :     data->quant,
231 : syskin 1.5 MAX(2,data->quant + data->quant/2));
232 : edgomez 1.2
233 :     /* Plugin job finished */
234 :     return(0);
235 :     }
236 :    
237 :     /*----------------------------------------------------------------------------
238 :     * After plugin function (dummy function)
239 :     *--------------------------------------------------------------------------*/
240 :    
241 :     static int
242 :     lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data)
243 :     {
244 :     return(0);
245 :     }
246 :    
247 :     /*****************************************************************************
248 :     * Helper functions
249 :     ****************************************************************************/
250 :    
251 :     #define RDIFF(a, b) ((int)(a+0.5)-(int)(b+0.5))
252 :    
253 :     static int
254 :     normalize_quantizer_field(float *in,
255 :     int *out,
256 :     int num,
257 :     int min_quant,
258 :     int max_quant)
259 :     {
260 :     int i;
261 :     int finished;
262 :    
263 :     do {
264 :     finished = 1;
265 :     for (i = 1; i < num; i++) {
266 :     if (RDIFF(in[i], in[i - 1]) > 2) {
267 :     in[i] -= (float) 0.5;
268 :     finished = 0;
269 :     } else if (RDIFF(in[i], in[i - 1]) < -2) {
270 :     in[i - 1] -= (float) 0.5;
271 :     finished = 0;
272 :     }
273 :    
274 :     if (in[i] > max_quant) {
275 :     in[i] = (float) max_quant;
276 :     finished = 0;
277 :     }
278 :     if (in[i] < min_quant) {
279 :     in[i] = (float) min_quant;
280 :     finished = 0;
281 :     }
282 :     if (in[i - 1] > max_quant) {
283 :     in[i - 1] = (float) max_quant;
284 :     finished = 0;
285 :     }
286 :     if (in[i - 1] < min_quant) {
287 :     in[i - 1] = (float) min_quant;
288 :     finished = 0;
289 :     }
290 :     }
291 :     } while (!finished);
292 :    
293 :     out[0] = 0;
294 :     for (i = 1; i < num; i++)
295 :     out[i] = RDIFF(in[i], in[i - 1]);
296 :    
297 :     return (int) (in[0] + 0.5);
298 :     }

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