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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.2.2, Mon Jun 9 13:55:07 2003 UTC revision 1.6, Sat May 6 04:37:15 2006 UTC
# Line 24  Line 24 
24   *   *
25   ****************************************************************************/   ****************************************************************************/
26    
27    #include <stdlib.h>
28    
29  #include "../xvid.h"  #include "../xvid.h"
30  #include "../image/image.h"  #include "../global.h"
31  #include "../quant/adapt_quant.h"  #include "../portab.h"
32    #include "../utils/emms.h"
33    
34    /*****************************************************************************
35     * Private data type
36     ****************************************************************************/
37    
38  int xvid_plugin_lumimasking(void * handle, int opt, void * param1, void * param2)  typedef struct
39  {  {
40      switch(opt)          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 :      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          xvid_plg_info_t * info = (xvid_plg_info_t*)param1;          /* We just require a diff quant array access */
87          info->flags = XVID_REQDQUANTS;          info->flags = XVID_REQDQUANTS;
88          return 0;          return(0);
89          }          }
90    
91      case XVID_PLG_CREATE :  /*----------------------------------------------------------------------------
92      case XVID_PLG_DESTROY :   * Create plugin function
93          return 0;   *
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      case XVID_PLG_BEFORE :          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          xvid_plg_data_t * data = (xvid_plg_data_t*)param1;          int i, j;
164               data->quant =  
165                      adaptive_quantization(data->current.plane[0], data->current.stride[0],          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            DarkThres = DarkThres*global/127.0f;
208            BrightThres = BrightThres*global/127.0f;
209    
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,                                            data->dquant,
229                                    data->quant /* framequant*/,                                                                                           data->mb_width*data->mb_height,
230                                    data->quant /* min_quant */,                                                                                           data->quant,
231                                                            data->quant*2 /* max_quant */,                                                                                           MAX(2,data->quant + data->quant/2));
                                                           data->mb_width, data->mb_height);  
232    
233          return 0;           /* Plugin job finished */
234             return(0);
235         }         }
236    
237      case XVID_PLG_AFTER :  /*----------------------------------------------------------------------------
238         return 0;   * 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      return XVID_ERR_FAIL;  /*****************************************************************************
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  }  }

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.6

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