[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.5, Thu Oct 2 13:54:27 2003 UTC revision 1.9, Tue Mar 9 10:00:14 2010 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
3   *  XVID MPEG-4 VIDEO CODEC   *  XVID MPEG-4 VIDEO CODEC
4   *  - XviD plugin: performs a lumimasking algorithm on encoded frame  -   *  - Xvid plugin: performs a lumimasking algorithm on encoded frame  -
5   *   *
6   *  Copyright(C) 2002-2003 Peter Ross <pross@xvid.org>   *  Copyright(C) 2002-2003 Peter Ross <pross@xvid.org>
7   *               2002      Christoph Lampert <gruel@web.de>   *               2002      Christoph Lampert <gruel@web.de>
8     *               2008      Jason Garrett-Glaser <darkshikari@gmail.com>
9   *   *
10   *  This program is free software ; you can redistribute it and/or modify   *  This program is free software ; you can redistribute it and/or modify
11   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
# Line 25  Line 26 
26   ****************************************************************************/   ****************************************************************************/
27    
28  #include <stdlib.h>  #include <stdlib.h>
29    #include <stdio.h>
30    #include <math.h>
31    
32  #include "../xvid.h"  #include "../xvid.h"
33    #include "../global.h"
34  #include "../portab.h"  #include "../portab.h"
35    #include "../utils/emms.h"
36    
37  /*****************************************************************************  /*****************************************************************************
38   * Private data type   * Private data type
# Line 37  Line 42 
42  {  {
43          float *quant;          float *quant;
44          float *val;          float *val;
45            int method;
46  } lumi_data_t;  } lumi_data_t;
47    
48  /*****************************************************************************  /*****************************************************************************
# Line 46  Line 52 
52  static int lumi_plg_info(xvid_plg_info_t *info);  static int lumi_plg_info(xvid_plg_info_t *info);
53  static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle);  static int lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle);
54  static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy);  static int lumi_plg_destroy(lumi_data_t *handle, xvid_plg_destroy_t * destroy);
55  static int lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data);  static int lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data);
56  static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data);  static int lumi_plg_after(lumi_data_t *handle, xvid_plg_data_t *data);
57    
58  /*****************************************************************************  /*****************************************************************************
# Line 64  Line 70 
70          case XVID_PLG_DESTROY:          case XVID_PLG_DESTROY:
71                  return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1));                  return(lumi_plg_destroy((lumi_data_t *)handle, (xvid_plg_destroy_t*)param1));
72          case XVID_PLG_BEFORE :          case XVID_PLG_BEFORE :
73                  return(lumi_plg_before((lumi_data_t *)handle, (xvid_plg_data_t *)param1));                  return 0;
74            case XVID_PLG_FRAME :
75                    return(lumi_plg_frame((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
76          case XVID_PLG_AFTER :          case XVID_PLG_AFTER :
77                  return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1));                  return(lumi_plg_after((lumi_data_t *)handle, (xvid_plg_data_t *)param1));
78          }          }
# Line 94  Line 102 
102  lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle)  lumi_plg_create(xvid_plg_create_t *create, lumi_data_t **handle)
103  {  {
104          lumi_data_t *lumi;          lumi_data_t *lumi;
105            xvid_plugin_lumimasking_t *param = (xvid_plugin_lumimasking_t *) create->param;
106    
107          if ((lumi = (lumi_data_t*)malloc(sizeof(lumi_data_t))) == NULL)          if ((lumi = (lumi_data_t*)malloc(sizeof(lumi_data_t))) == NULL)
108                  return(XVID_ERR_MEMORY);                  return(XVID_ERR_MEMORY);
109    
110            lumi->method = 0;
111          lumi->quant = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));          lumi->quant = (float*)malloc(create->mb_width*create->mb_height*sizeof(float));
112          if (lumi->quant == NULL) {          if (lumi->quant == NULL) {
113                  free(lumi);                  free(lumi);
# Line 111  Line 121 
121                  return(XVID_ERR_MEMORY);                  return(XVID_ERR_MEMORY);
122          }          }
123    
124            if (param != NULL)
125                    lumi->method = param->method;
126    
127          /* Bind the data structure to the handle */          /* Bind the data structure to the handle */
128          *handle = lumi;          *handle = lumi;
129    
# Line 154  Line 167 
167                                                                           int max_quant);                                                                           int max_quant);
168    
169  static int  static int
170  lumi_plg_before(lumi_data_t *handle, xvid_plg_data_t *data)  lumi_plg_frame(lumi_data_t *handle, xvid_plg_data_t *data)
171  {  {
172          int i, j;          int i, j;
173    
174          float global = 0.0f;          float global = 0.0f;
         uint32_t mid_range = 0;  
175    
176          const float DarkAmpl = 14 / 2;          const float DarkAmpl = 14 / 4;
177          const float BrightAmpl = 10 / 2;          const float BrightAmpl = 10 / 3;
178          const float DarkThres = 70;          float DarkThres = 90;
179          const float BrightThres = 200;          float BrightThres = 200;
180    
181          const float GlobalDarkThres = 60;          const float GlobalDarkThres = 60;
182          const float GlobalBrightThres = 170;          const float GlobalBrightThres = 170;
183    
184          const float MidRangeThres = 20;          /* Arbitrary centerpoint for variance-based AQ.  Roughly the same as used in x264. */
185          const float UpperLimit = 200;          float center = 14000.f;
186          const float LowerLimit = 25;          /* Arbitrary strength for variance-based AQ. */
187            float strength = 0.2f;
188    
189            if (data->type == XVID_TYPE_BVOP) return 0;
190    
191          /* Do this for all macroblocks individually  */          /* Do this for all macroblocks individually  */
192          for (j = 0; j < data->mb_height; j++) {          for (j = 0; j < data->mb_height; j++) {
193                  for (i = 0; i < data->mb_width; i++) {                  for (i = 0; i < data->mb_width; i++) {
194                          int k, l;                          int k, l, sum = 0, sum_of_squares = 0;
195                          unsigned char *ptr;                          unsigned char *ptr;
196    
197                          /* Initialize the current quant value to the frame quant */                          /* Initialize the current quant value to the frame quant */
198                          handle->quant[j*data->mb_width + i] = (float)data->quant;                          handle->quant[j*data->mb_width + i] = (float)data->quant;
199    
                         /* Reset the val value */  
                         handle->val[j*data->mb_width + i] = 0.0f;  
   
200                          /* Next steps compute the luminance-masking */                          /* Next steps compute the luminance-masking */
201    
202                          /* Get the MB address */                          /* Get the MB address */
203                          ptr  = data->current.plane[0];                          ptr  = data->current.plane[0];
204                          ptr += 16*j*data->current.stride[0] + 16*i;                          ptr += 16*j*data->current.stride[0] + 16*i;
205    
206                            if (handle->method) { /* Variance masking mode */
207                                    int variance = 0;
208                                    /* Accumulate sum and sum of squares over the MB */
209                                    for (k = 0; k < 16; k++) {
210                                            for (l = 0; l < 16; l++) {
211                                                    int val = ptr[k*data->current.stride[0] + l];
212                                                    sum += val;
213                                                    sum_of_squares += val * val;
214                                            }
215                                    }
216                                    /* Variance = SSD - SAD^2 / (numpixels) */
217                                    variance = sum_of_squares - sum * sum / 256;
218                                    handle->val[j*data->mb_width + i] = (float)variance;
219                            }
220                            else { /* Luminance masking mode */
221                          /* Accumulate luminance */                          /* Accumulate luminance */
222                          for (k = 0; k < 16; k++)                          for (k = 0; k < 16; k++)
223                                  for (l = 0; l < 16; l++)                                  for (l = 0; l < 16; l++)
224                                          handle->val[j*data->mb_width + i] += ptr[k*data->current.stride[0] + l];                                                   sum += ptr[k*data->current.stride[0] + l];
225    
226                          /* Normalize its value */                                  handle->val[j*data->mb_width + i] = (float)sum/256.0f;
                         handle->val[j*data->mb_width + i] /= 256.0f;  
227    
228                          /* Accumulate the global frame luminance */                          /* Accumulate the global frame luminance */
229                          global += handle->val[j*data->mb_width + i];                                  global += (float)sum/256.0f;
230                            }
                         /* Count the number of middle luminance blocks */  
                         if ((handle->val[j*data->mb_width + i] > LowerLimit) &&  
                                 (handle->val[j*data->mb_width + i] < UpperLimit))  
                                 mid_range++;  
231                  }                  }
232          }          }
233    
234            if (handle->method) { /* Variance masking */
235                    /* Apply the variance masking formula to all MBs */
236                    for (i = 0; i < data->mb_height; i++)
237                    {
238                            for (j = 0; j < data->mb_width; j++)
239                            {
240                                    float value = handle->val[i*data->mb_width + j];
241                                    float qscale_diff = strength * logf(value / center);
242                                    handle->quant[i*data->mb_width + j] *= (1.0f + qscale_diff);
243                            }
244                    }
245            }
246            else { /* Luminance masking */
247          /* Normalize the global luminance accumulator */          /* Normalize the global luminance accumulator */
248          global /= data->mb_width*data->mb_height;          global /= data->mb_width*data->mb_height;
249    
250                    DarkThres = DarkThres*global/127.0f;
251                    BrightThres = BrightThres*global/127.0f;
252    
253    
254          /* Apply luminance masking only to frames where the global luminance is          /* Apply luminance masking only to frames where the global luminance is
255           * higher than DarkThreshold and lower than Bright Threshold, or where                   * higher than DarkThreshold and lower than Bright Threshold */
256           * "middle" luminance blocks are lower than its corresponding threshold */                   if ((global < GlobalBrightThres) && (global > GlobalDarkThres)) {
          if (((global < GlobalBrightThres) && (global > GlobalDarkThres)) ||  
                 (mid_range < MidRangeThres)) {  
257    
258                  /* Apply the luminance masking formulas to all MBs */                  /* Apply the luminance masking formulas to all MBs */
259                  for (i = 0; i < data->mb_height; i++) {                  for (i = 0; i < data->mb_height; i++) {
260                          for (j = 0; j < data->mb_width; j++) {                          for (j = 0; j < data->mb_width; j++) {
261                                  if (handle->val[i*data->mb_width + j] < DarkThres)                                  if (handle->val[i*data->mb_width + j] < DarkThres)
262                                          handle->quant[i*data->mb_width + j] += DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres;                                                  handle->quant[i*data->mb_width + j] *= 1 + DarkAmpl * (DarkThres - handle->val[i*data->mb_width + j]) / DarkThres;
263                                  else if (handle->val[i*data->mb_width + j] > BrightThres)                                  else if (handle->val[i*data->mb_width + j] > BrightThres)
264                                          handle->quant[i*data->mb_width + j] += BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres);                                                  handle->quant[i*data->mb_width + j] *= 1 + BrightAmpl * (handle->val[i*data->mb_width + j] - BrightThres) / (255 - BrightThres);
265                                    }
266                          }                          }
267                  }                  }
268          }          }
# Line 234  Line 272 
272                                                                                           data->dquant,                                                                                           data->dquant,
273                                                                                           data->mb_width*data->mb_height,                                                                                           data->mb_width*data->mb_height,
274                                                                                           data->quant,                                                                                           data->quant,
275                                                                                           data->quant*2);                                                                                           MAX(2,data->quant + data->quant/2));
276    
277           /* Plugin job finished */           /* Plugin job finished */
278           return(0);           return(0);

Legend:
Removed from v.1.1.2.5  
changed lines
  Added in v.1.9

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