[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, Sun Mar 16 12:05:09 2003 UTC revision 1.1.2.4, Thu Sep 11 12:58:37 2003 UTC
# Line 0  Line 1 
1    /*****************************************************************************
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     * $Id$
24     *
25     ****************************************************************************/
26    
27    #include <stdlib.h>
28    
29    #include "../xvid.h"
30    #include "../portab.h"
31    
32    
33    
34    /*****************************************************************************
35     * Prototypes
36     ****************************************************************************/
37    
38    static int
39    adaptive_quantization(unsigned char *buf,
40                                              int stride,
41                                              int *intquant,
42                                              int framequant,
43                                              int min_quant,
44                                              int max_quant,
45                                              int mb_width,
46                                              int mb_height);
47    
48    
49    /*****************************************************************************
50     * The plugin entry
51     ****************************************************************************/
52    
53    int
54    xvid_plugin_lumimasking(void * handle, int opt, void * param1, void * param2)
55    {
56            switch(opt)
57            {
58            case XVID_PLG_INFO :
59            {
60                    xvid_plg_info_t * info = (xvid_plg_info_t*)param1;
61                    info->flags = XVID_REQDQUANTS;
62                    return 0;
63            }
64    
65            case XVID_PLG_CREATE :
66            case XVID_PLG_DESTROY :
67                    return 0;
68    
69    
70            case XVID_PLG_BEFORE :
71            {
72                    xvid_plg_data_t * data = (xvid_plg_data_t*)param1;
73                    data->quant =
74                            adaptive_quantization(data->current.plane[0],
75                                                                      data->current.stride[0],
76                                                                      data->dquant,
77                                                                      data->quant /* framequant*/,
78                                                                      data->quant /* min_quant */,
79                                                                      data->quant*2 /* max_quant */,
80                                                                      data->mb_width,
81                                                                      data->mb_height);
82    
83                    return 0;
84            }
85    
86            case XVID_PLG_AFTER :
87                    return 0;
88            }
89    
90            return XVID_ERR_FAIL;
91    }
92    
93    /*****************************************************************************
94     * Helper functions
95     ****************************************************************************/
96    
97    #define RDIFF(a,b)    ((int)(a+0.5)-(int)(b+0.5))
98    
99    static int
100    normalize_quantizer_field(float *in,
101                                                      int *out,
102                                                      int num,
103                                                      int min_quant,
104                                                      int max_quant)
105    {
106            int i;
107            int finished;
108    
109            do {
110                    finished = 1;
111                    for (i = 1; i < num; i++) {
112                            if (RDIFF(in[i], in[i - 1]) > 2) {
113                                    in[i] -= (float) 0.5;
114                                    finished = 0;
115                            } else if (RDIFF(in[i], in[i - 1]) < -2) {
116                                    in[i - 1] -= (float) 0.5;
117                                    finished = 0;
118                            }
119    
120                            if (in[i] > max_quant) {
121                                    in[i] = (float) max_quant;
122                                    finished = 0;
123                            }
124                            if (in[i] < min_quant) {
125                                    in[i] = (float) min_quant;
126                                    finished = 0;
127                            }
128                            if (in[i - 1] > max_quant) {
129                                    in[i - 1] = (float) max_quant;
130                                    finished = 0;
131                            }
132                            if (in[i - 1] < min_quant) {
133                                    in[i - 1] = (float) min_quant;
134                                    finished = 0;
135                            }
136                    }
137            } while (!finished);
138    
139            out[0] = 0;
140            for (i = 1; i < num; i++)
141                    out[i] = RDIFF(in[i], in[i - 1]);
142    
143            return (int) (in[0] + 0.5);
144    }
145    
146    static int
147    adaptive_quantization(unsigned char *buf,
148                                              int stride,
149                                              int *intquant,
150                                              int framequant,
151                                              int min_quant,
152                                              int max_quant,
153                                              int mb_width,
154                                              int mb_height)        /* no qstride because normalization */
155    {
156            int i, j, k, l;
157    
158            float *quant;
159            unsigned char *ptr;
160            float *val;
161            float global = 0.;
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    
177            if (!(quant = (float *) malloc(mb_width * mb_height * sizeof(float))))
178                    return(-1);
179    
180            if(!(val = (float *) malloc(mb_width * mb_height * sizeof(float))))
181                    return(-1);
182    
183            for (k = 0; k < mb_height; k++) {
184                    for (l = 0; l < mb_width; l++)  /* do this for all macroblocks individually  */
185                    {
186                            quant[k * mb_width + l] = (float) framequant;
187    
188                            /* calculate luminance-masking */
189                            ptr = &buf[16 * k * stride + 16 * l];   /* address of MB */
190    
191                            val[k * mb_width + l] = 0.;
192    
193                            for (i = 0; i < 16; i++)
194                                    for (j = 0; j < 16; j++)
195                                            val[k * mb_width + l] += ptr[i * stride + j];
196                            val[k * mb_width + l] /= 256.;
197                            global +=val[k * mb_width + l];
198    
199                            if ((val[k * mb_width + l] > LowerLimit) &&
200                                    (val[k * mb_width + l] < UpperLimit))
201                                    mid_range++;
202                    }
203            }
204    
205            global /=mb_width * mb_height;
206    
207            if (((global <GlobalBrightThres) &&(global >GlobalDarkThres))
208                    || (mid_range < MidRangeThres)) {
209                    for (k = 0; k < mb_height; k++) {
210                            for (l = 0; l < mb_width; l++)  /* do this for all macroblocks individually */
211                            {
212                                    if (val[k * mb_width + l] < DarkThres)
213                                            quant[k * mb_width + l] +=
214                                                    DarkAmpl * (DarkThres -
215                                                                            val[k * mb_width + l]) / DarkThres;
216                                    else if (val[k * mb_width + l] > BrightThres)
217                                            quant[k * mb_width + l] +=
218                                                    BrightAmpl * (val[k * mb_width + l] -
219                                                                              BrightThres) / (255 - BrightThres);
220                            }
221                    }
222            }
223    
224            i = normalize_quantizer_field(quant, intquant,
225                                                                      mb_width * mb_height,
226                                                                      min_quant, max_quant);
227    
228            free(val);
229            free(quant);
230    
231            return(i);
232    
233    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.4

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