[cvs] / xvidcore / src / quant / quant_mpeg4.c Repository:
ViewVC logotype

Annotation of /xvidcore/src/quant/quant_mpeg4.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (view) (download)

1 : edgomez 1.4 /*****************************************************************************
2 : Isibaar 1.1 *
3 : edgomez 1.4 * XVID MPEG-4 VIDEO CODEC
4 :     * - Mpeg4 quantization/dequantization functions -
5 : Isibaar 1.1 *
6 : suxen_drol 1.5 * Copyright(C) 2002 Peter Ross <pross@xvid.org>
7 : Isibaar 1.1 *
8 : edgomez 1.6 * This file is part of XviD, a free MPEG-4 video encoder/decoder
9 :     *
10 :     * XviD is free software; you can redistribute it and/or modify it
11 :     * under the terms of the GNU General Public License as published by
12 :     * the Free Software Foundation; either version 2 of the License, or
13 : edgomez 1.4 * (at your option) any later version.
14 :     *
15 :     * This program is distributed in the hope that it will be useful,
16 : edgomez 1.6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : edgomez 1.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 :     * GNU General Public License for more details.
19 :     *
20 :     * You should have received a copy of the GNU General Public License
21 : edgomez 1.6 * along with this program; if not, write to the Free Software
22 : edgomez 1.4 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 :     *
24 : edgomez 1.6 * Under section 8 of the GNU General Public License, the copyright
25 :     * holders of XVID explicitly forbid distribution in the following
26 :     * countries:
27 :     *
28 :     * - Japan
29 :     * - United States of America
30 :     *
31 :     * Linking XviD statically or dynamically with other modules is making a
32 :     * combined work based on XviD. Thus, the terms and conditions of the
33 :     * GNU General Public License cover the whole combination.
34 :     *
35 :     * As a special exception, the copyright holders of XviD give you
36 :     * permission to link XviD with independent modules that communicate with
37 :     * XviD solely through the VFW1.1 and DShow interfaces, regardless of the
38 :     * license terms of these independent modules, and to copy and distribute
39 :     * the resulting combined work under terms of your choice, provided that
40 :     * every copy of the combined work is accompanied by a complete copy of
41 :     * the source code of XviD (the version of XviD used to produce the
42 :     * combined work), being distributed under the terms of the GNU General
43 :     * Public License plus this exception. An independent module is a module
44 :     * which is not derived from or based on XviD.
45 :     *
46 :     * Note that people who make modified versions of XviD are not obligated
47 :     * to grant this special exception for their modified versions; it is
48 :     * their choice whether to do so. The GNU General Public License gives
49 :     * permission to release a modified version without this exception; this
50 :     * exception also makes it possible to release a modified version which
51 :     * carries forward this exception.
52 :     *
53 :     * $Id$
54 : edgomez 1.4 *
55 :     ****************************************************************************/
56 : Isibaar 1.1
57 :     #include "quant_mpeg4.h"
58 : Isibaar 1.2 #include "quant_matrix.h"
59 : Isibaar 1.1
60 : edgomez 1.4 /*****************************************************************************
61 :     * Function pointers
62 :     ****************************************************************************/
63 :    
64 : Isibaar 1.1 quant_intraFuncPtr quant4_intra;
65 :     quant_intraFuncPtr dequant4_intra;
66 :     dequant_interFuncPtr dequant4_inter;
67 :     quant_interFuncPtr quant4_inter;
68 :    
69 :    
70 : edgomez 1.4 /*****************************************************************************
71 :     * Local data
72 :     ****************************************************************************/
73 :    
74 : Isibaar 1.1 #define DIV_DIV(A,B) ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )
75 :     #define SIGN(A) ((A)>0?1:-1)
76 :     #define VM18P 3
77 :     #define VM18Q 4
78 :    
79 :    
80 : edgomez 1.4 /*
81 :     * divide-by-multiply table
82 :     * need 17 bit shift (16 causes slight errors when q > 19)
83 :     */
84 : Isibaar 1.1
85 :     #define SCALEBITS 17
86 :     #define FIX(X) ((1UL << SCALEBITS) / (X) + 1)
87 :    
88 : edgomez 1.3 static const uint32_t multipliers[32] = {
89 :     0, FIX(2), FIX(4), FIX(6),
90 :     FIX(8), FIX(10), FIX(12), FIX(14),
91 :     FIX(16), FIX(18), FIX(20), FIX(22),
92 :     FIX(24), FIX(26), FIX(28), FIX(30),
93 :     FIX(32), FIX(34), FIX(36), FIX(38),
94 :     FIX(40), FIX(42), FIX(44), FIX(46),
95 :     FIX(48), FIX(50), FIX(52), FIX(54),
96 :     FIX(56), FIX(58), FIX(60), FIX(62)
97 :     };
98 : edgomez 1.4
99 :     /*****************************************************************************
100 :     * Functions
101 :     ****************************************************************************/
102 : Isibaar 1.1
103 :     /* quantize intra-block
104 :    
105 :     // const int32_t quantd = DIV_DIV(VM18P*quant, VM18Q);
106 :     //
107 :     // level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
108 :     // coeff[i] = (level + quantd) / quant2;
109 :     */
110 :    
111 : edgomez 1.3 void
112 :     quant4_intra_c(int16_t * coeff,
113 :     const int16_t * data,
114 :     const uint32_t quant,
115 :     const uint32_t dcscalar)
116 : Isibaar 1.1 {
117 : edgomez 1.3 const uint32_t quantd = ((VM18P * quant) + (VM18Q / 2)) / VM18Q;
118 :     const uint32_t mult = multipliers[quant];
119 :     uint32_t i;
120 : Isibaar 1.2 int16_t *intra_matrix;
121 :    
122 :     intra_matrix = get_intra_matrix();
123 : Isibaar 1.1
124 : edgomez 1.3 coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);
125 : Isibaar 1.1
126 : edgomez 1.3 for (i = 1; i < 64; i++) {
127 :     if (data[i] < 0) {
128 :     uint32_t level = -data[i];
129 :    
130 :     level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
131 :     level = ((level + quantd) * mult) >> 17;
132 :     coeff[i] = -(int16_t) level;
133 :     } else if (data[i] > 0) {
134 :     uint32_t level = data[i];
135 :    
136 :     level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
137 :     level = ((level + quantd) * mult) >> 17;
138 :     coeff[i] = level;
139 :     } else {
140 :     coeff[i] = 0;
141 :     }
142 :     }
143 : Isibaar 1.1 }
144 :    
145 :    
146 :    
147 :     /* dequantize intra-block & clamp to [-2048,2047]
148 :     // data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;
149 :     */
150 :    
151 : edgomez 1.3 void
152 :     dequant4_intra_c(int16_t * data,
153 :     const int16_t * coeff,
154 :     const uint32_t quant,
155 :     const uint32_t dcscalar)
156 : Isibaar 1.1 {
157 : edgomez 1.3 uint32_t i;
158 : Isibaar 1.2 int16_t *intra_matrix;
159 :    
160 :     intra_matrix = get_intra_matrix();
161 : edgomez 1.3
162 :     data[0] = coeff[0] * dcscalar;
163 :     if (data[0] < -2048) {
164 :     data[0] = -2048;
165 :     } else if (data[0] > 2047) {
166 :     data[0] = 2047;
167 :     }
168 :    
169 :     for (i = 1; i < 64; i++) {
170 :     if (coeff[i] == 0) {
171 :     data[i] = 0;
172 :     } else if (coeff[i] < 0) {
173 :     uint32_t level = -coeff[i];
174 :    
175 :     level = (level * intra_matrix[i] * quant) >> 3;
176 :     data[i] = (level <= 2048 ? -(int16_t) level : -2048);
177 :     } else // if (coeff[i] > 0)
178 :     {
179 :     uint32_t level = coeff[i];
180 :    
181 :     level = (level * intra_matrix[i] * quant) >> 3;
182 :     data[i] = (level <= 2047 ? level : 2047);
183 :     }
184 :     }
185 : Isibaar 1.1 }
186 :    
187 :    
188 :    
189 :     /* quantize inter-block
190 :    
191 :     // level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
192 :     // coeff[i] = (level + quantd) / quant2;
193 :     // sum += abs(level);
194 :     */
195 :    
196 : edgomez 1.3 uint32_t
197 :     quant4_inter_c(int16_t * coeff,
198 :     const int16_t * data,
199 :     const uint32_t quant)
200 : Isibaar 1.1 {
201 : edgomez 1.3 const uint32_t mult = multipliers[quant];
202 :     uint32_t sum = 0;
203 :     uint32_t i;
204 : Isibaar 1.2 int16_t *inter_matrix;
205 :    
206 :     inter_matrix = get_inter_matrix();
207 : edgomez 1.3
208 :     for (i = 0; i < 64; i++) {
209 :     if (data[i] < 0) {
210 :     uint32_t level = -data[i];
211 :    
212 :     level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
213 :     level = (level * mult) >> 17;
214 :     sum += level;
215 :     coeff[i] = -(int16_t) level;
216 :     } else if (data[i] > 0) {
217 :     uint32_t level = data[i];
218 :    
219 :     level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
220 :     level = (level * mult) >> 17;
221 :     sum += level;
222 :     coeff[i] = level;
223 :     } else {
224 :     coeff[i] = 0;
225 :     }
226 :     }
227 :     return sum;
228 : Isibaar 1.1 }
229 :    
230 :    
231 :    
232 :     /* dequantize inter-block & clamp to [-2048,2047]
233 :     data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16
234 :     */
235 :    
236 : edgomez 1.3 void
237 :     dequant4_inter_c(int16_t * data,
238 :     const int16_t * coeff,
239 :     const uint32_t quant)
240 : Isibaar 1.1 {
241 : edgomez 1.3 uint32_t sum = 0;
242 :     uint32_t i;
243 : Isibaar 1.2 int16_t *inter_matrix;
244 :    
245 :     inter_matrix = get_inter_matrix();
246 : edgomez 1.3
247 :     for (i = 0; i < 64; i++) {
248 :     if (coeff[i] == 0) {
249 :     data[i] = 0;
250 :     } else if (coeff[i] < 0) {
251 :     int32_t level = -coeff[i];
252 :    
253 :     level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
254 :     data[i] = (level <= 2048 ? -level : -2048);
255 :     } else // if (coeff[i] > 0)
256 :     {
257 :     uint32_t level = coeff[i];
258 :    
259 :     level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
260 :     data[i] = (level <= 2047 ? level : 2047);
261 :     }
262 :    
263 :     sum ^= data[i];
264 :     }
265 :    
266 :     // mismatch control
267 :    
268 :     if ((sum & 1) == 0) {
269 :     data[63] ^= 1;
270 :     }
271 : Isibaar 1.1 }

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