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

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

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