ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvs/xvidcore/src/quant/quant_h263.c
Revision: 1.7.2.4
Committed: Sun Nov 30 16:13:16 2003 UTC (20 years, 10 months ago) by edgomez
Content type: text/plain
Branch: dev-api-4
Changes since 1.7.2.3: +9 -5 lines
Log Message:
* Thread safe MPEG4 quantization functions.
  Cleaned up version of patch provided by Michael
   - fixed compiling problems on gcc
   - added const qualifiers every where it was possible to help C compiler
     optimization.
   - added the mpeg_quant_matrices param to all ASM function prototype
     in comments (even if it's not used, that shows we do it deliberatly)
   - forces m[intra][0][0] = 8, otherwise XviD could write invalid streams.
* Added real CRC computing in xvid_bench.c

File Contents

# User Rev Content
1 edgomez 1.7.2.2 /*****************************************************************************
2 Isibaar 1.1 *
3 edgomez 1.7.2.2 * XVID MPEG-4 VIDEO CODEC
4     * - MPEG4 Quantization H263 implementation -
5 Isibaar 1.1 *
6 edgomez 1.7.2.2 * Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7 Isibaar 1.1 *
8 edgomez 1.7.2.2 * This program is free software ; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation ; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program ; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     *
22     * $Id$
23     *
24     ****************************************************************************/
25 Isibaar 1.1
26 edgomez 1.7 #include "../global.h"
27 edgomez 1.7.2.2 #include "quant.h"
28 Isibaar 1.1
29 edgomez 1.7.2.2 /*****************************************************************************
30     * Global function pointers
31     ****************************************************************************/
32    
33     /* Quant */
34     quant_intraFuncPtr quant_h263_intra;
35     quant_interFuncPtr quant_h263_inter;
36    
37     /* DeQuant */
38     quant_intraFuncPtr dequant_h263_intra;
39     quant_interFuncPtr dequant_h263_inter;
40    
41     /*****************************************************************************
42     * Local data
43     ****************************************************************************/
44    
45     /* divide-by-multiply table
46     * a 16 bit shiting is enough in this case */
47 Isibaar 1.1
48     #define SCALEBITS 16
49     #define FIX(X) ((1L << SCALEBITS) / (X) + 1)
50    
51 edgomez 1.7.2.2 static const uint32_t multipliers[32] =
52     {
53     0, FIX(2), FIX(4), FIX(6),
54     FIX(8), FIX(10), FIX(12), FIX(14),
55 edgomez 1.2 FIX(16), FIX(18), FIX(20), FIX(22),
56     FIX(24), FIX(26), FIX(28), FIX(30),
57     FIX(32), FIX(34), FIX(36), FIX(38),
58     FIX(40), FIX(42), FIX(44), FIX(46),
59     FIX(48), FIX(50), FIX(52), FIX(54),
60     FIX(56), FIX(58), FIX(60), FIX(62)
61     };
62 Isibaar 1.1
63 edgomez 1.7.2.2 /*****************************************************************************
64     * Function definitions
65     ****************************************************************************/
66 Isibaar 1.1
67     /* quantize intra-block
68 edgomez 1.7.2.2 */
69 Isibaar 1.1
70 edgomez 1.7.2.2 uint32_t
71     quant_h263_intra_c(int16_t * coeff,
72     const int16_t * data,
73     const uint32_t quant,
74 edgomez 1.7.2.4 const uint32_t dcscalar,
75     const uint16_t * mpeg_quant_matrices)
76 Isibaar 1.1 {
77     const uint32_t mult = multipliers[quant];
78 edgomez 1.7 const uint16_t quant_m_2 = quant << 1;
79 edgomez 1.7.2.2 int i;
80 Isibaar 1.1
81 edgomez 1.7 coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);
82 Isibaar 1.1
83     for (i = 1; i < 64; i++) {
84     int16_t acLevel = data[i];
85    
86     if (acLevel < 0) {
87     acLevel = -acLevel;
88     if (acLevel < quant_m_2) {
89     coeff[i] = 0;
90     continue;
91     }
92 edgomez 1.7 acLevel = (acLevel * mult) >> SCALEBITS;
93 Isibaar 1.1 coeff[i] = -acLevel;
94     } else {
95     if (acLevel < quant_m_2) {
96     coeff[i] = 0;
97     continue;
98     }
99 edgomez 1.7 acLevel = (acLevel * mult) >> SCALEBITS;
100 Isibaar 1.1 coeff[i] = acLevel;
101     }
102     }
103 edgomez 1.7.2.2
104 edgomez 1.7.2.3 return(0);
105 Isibaar 1.1 }
106    
107    
108     /* quantize inter-block
109 edgomez 1.7.2.2 */
110 Isibaar 1.1
111 edgomez 1.2 uint32_t
112 edgomez 1.7.2.2 quant_h263_inter_c(int16_t * coeff,
113     const int16_t * data,
114 edgomez 1.7.2.4 const uint32_t quant,
115     const uint16_t * mpeg_quant_matrices)
116 Isibaar 1.1 {
117     const uint32_t mult = multipliers[quant];
118 edgomez 1.7 const uint16_t quant_m_2 = quant << 1;
119     const uint16_t quant_d_2 = quant >> 1;
120 edgomez 1.7.2.2 uint32_t sum = 0;
121 Isibaar 1.1 uint32_t i;
122    
123     for (i = 0; i < 64; i++) {
124     int16_t acLevel = data[i];
125 edgomez 1.2
126 Isibaar 1.1 if (acLevel < 0) {
127     acLevel = (-acLevel) - quant_d_2;
128     if (acLevel < quant_m_2) {
129     coeff[i] = 0;
130     continue;
131     }
132    
133 edgomez 1.7 acLevel = (acLevel * mult) >> SCALEBITS;
134 edgomez 1.7.2.1 sum += acLevel; /* sum += |acLevel| */
135 Isibaar 1.1 coeff[i] = -acLevel;
136     } else {
137     acLevel -= quant_d_2;
138     if (acLevel < quant_m_2) {
139     coeff[i] = 0;
140     continue;
141     }
142 edgomez 1.7 acLevel = (acLevel * mult) >> SCALEBITS;
143 Isibaar 1.1 sum += acLevel;
144     coeff[i] = acLevel;
145     }
146     }
147    
148 edgomez 1.7.2.2 return(sum);
149 Isibaar 1.1 }
150    
151    
152     /* dequantize intra-block & clamp to [-2048,2047]
153 edgomez 1.7.2.2 */
154 Isibaar 1.1
155 edgomez 1.7.2.2 uint32_t
156     dequant_h263_intra_c(int16_t * data,
157     const int16_t * coeff,
158     const uint32_t quant,
159 edgomez 1.7.2.4 const uint32_t dcscalar,
160     const uint16_t * mpeg_quant_matrices)
161 Isibaar 1.1 {
162     const int32_t quant_m_2 = quant << 1;
163     const int32_t quant_add = (quant & 1 ? quant : quant - 1);
164 edgomez 1.7.2.2 int i;
165 Isibaar 1.1
166 edgomez 1.7 data[0] = coeff[0] * dcscalar;
167 edgomez 1.2 if (data[0] < -2048) {
168 Isibaar 1.1 data[0] = -2048;
169 edgomez 1.2 } else if (data[0] > 2047) {
170 Isibaar 1.1 data[0] = 2047;
171     }
172    
173     for (i = 1; i < 64; i++) {
174     int32_t acLevel = coeff[i];
175 edgomez 1.2
176     if (acLevel == 0) {
177 Isibaar 1.1 data[i] = 0;
178 edgomez 1.2 } else if (acLevel < 0) {
179 Isibaar 1.1 acLevel = quant_m_2 * -acLevel + quant_add;
180     data[i] = (acLevel <= 2048 ? -acLevel : -2048);
181 edgomez 1.7.2.2 } else {
182 Isibaar 1.1 acLevel = quant_m_2 * acLevel + quant_add;
183     data[i] = (acLevel <= 2047 ? acLevel : 2047);
184     }
185     }
186 edgomez 1.7.2.2
187     return(0);
188 Isibaar 1.1 }
189    
190    
191    
192     /* dequantize inter-block & clamp to [-2048,2047]
193 edgomez 1.7.2.2 */
194 Isibaar 1.1
195 edgomez 1.7.2.2 uint32_t
196     dequant_h263_inter_c(int16_t * data,
197 edgomez 1.7.2.4 const int16_t * coeff,
198     const uint32_t quant,
199     const uint16_t * mpeg_quant_matrices)
200 Isibaar 1.1 {
201 edgomez 1.7 const uint16_t quant_m_2 = quant << 1;
202     const uint16_t quant_add = (quant & 1 ? quant : quant - 1);
203 edgomez 1.7.2.2 int i;
204 Isibaar 1.1
205     for (i = 0; i < 64; i++) {
206     int16_t acLevel = coeff[i];
207 edgomez 1.2
208     if (acLevel == 0) {
209 Isibaar 1.1 data[i] = 0;
210 edgomez 1.2 } else if (acLevel < 0) {
211 Isibaar 1.1 acLevel = acLevel * quant_m_2 - quant_add;
212     data[i] = (acLevel >= -2048 ? acLevel : -2048);
213 edgomez 1.7.2.2 } else {
214 Isibaar 1.1 acLevel = acLevel * quant_m_2 + quant_add;
215     data[i] = (acLevel <= 2047 ? acLevel : 2047);
216     }
217     }
218 edgomez 1.7.2.2
219     return(0);
220 Isibaar 1.1 }