[svn] / branches / dev-api-4 / xvidcore / src / quant / quant_mpeg4.c Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/src/quant/quant_mpeg4.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/xvidcore/src/quant/quant_mpeg4.c revision 3, Fri Mar 8 02:46:11 2002 UTC branches/dev-api-4/xvidcore/src/quant/quant_mpeg4.c revision 1054, Mon Jun 9 13:55:56 2003 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *    XVID MPEG-4 VIDEO CODEC   *    XVID MPEG-4 VIDEO CODEC
4   *    mpeg-4 quantization/dequantization   *  - MPEG4 Quantization related header  -
5   *   *
6   *    This program is an implementation of a part of one or more MPEG-4   *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
  *    Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
  *    to use this software module in hardware or software products are  
  *    advised that its use may infringe existing patents or copyrights, and  
  *    any such use would be at such party's own risk.  The original  
  *    developer of this software module and his/her company, and subsequent  
  *    editors and their companies, will have no liability for use of this  
  *    software or modifications or derivatives thereof.  
7   *   *
8   *    This program is free software; you can redistribute it and/or modify   *    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   *    it under the terms of the GNU General Public License as published by
# Line 24  Line 17 
17   *   *
18   *    You should have received a copy of the GNU General Public License   *    You should have received a copy of the GNU General Public License
19   *    along with this program; if not, write to the Free Software   *    along with this program; if not, write to the Free Software
20   *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21   *   *
22   *************************************************************************/   * $Id: quant_mpeg4.c,v 1.9.2.2 2003-06-09 13:55:25 edgomez Exp $
   
 /**************************************************************************  
  *  
  *    History:  
23   *   *
24   *      26.01.2002    fixed  quant4_intra dcscalar signed/unsigned error   ****************************************************************************/
  *  20.01.2002    increased accuracy of >> divide  
  *  26.12.2001    divide-by-multiplication optimization  
  *  22.12.2001    [-127,127] clamping removed; minor tweaks  
  *      19.11.2001    inital version <pross@cs.rmit.edu.au>  
  *  
  *************************************************************************/  
   
25    
26    #include "../global.h"
27  #include "quant_mpeg4.h"  #include "quant_mpeg4.h"
28    #include "quant_matrix.h"
29    
30    /* function pointers */
   
 // function pointers  
31  quant_intraFuncPtr quant4_intra;  quant_intraFuncPtr quant4_intra;
32  quant_intraFuncPtr dequant4_intra;  quant_intraFuncPtr dequant4_intra;
33  dequant_interFuncPtr dequant4_inter;  dequant_interFuncPtr dequant4_inter;
34  quant_interFuncPtr quant4_inter;  quant_interFuncPtr quant4_inter;
35    
36    
 #define DIV_DIV(A,B)    ( (A) > 0 ? ((A)+((B)>>1))/(B) : ((A)-((B)>>1))/(B) )  
 #define SIGN(A)  ((A)>0?1:-1)  
37  #define VM18P    3  #define VM18P    3
38  #define VM18Q    4  #define VM18Q    4
39    
40    
41  // divide-by-multiply table  /*
42  // need 17 bit shift (16 causes slight errors when q > 19)   * divide-by-multiply table
43     * need 17 bit shift (16 causes slight errors when q > 19)
44     */
45    
46  #define SCALEBITS    17  #define SCALEBITS    17
47  #define FIX(X)        ((1UL << SCALEBITS) / (X) + 1)  #define FIX(X)        ((1UL << SCALEBITS) / (X) + 1)
48    
49  static const uint32_t multipliers[32] =  static const uint32_t multipliers[32] = {
 {  
50      0,          FIX(2),     FIX(4),     FIX(6),      0,          FIX(2),     FIX(4),     FIX(6),
51      FIX(8),     FIX(10),    FIX(12),    FIX(14),      FIX(8),     FIX(10),    FIX(12),    FIX(14),
52      FIX(16),    FIX(18),    FIX(20),    FIX(22),      FIX(16),    FIX(18),    FIX(20),    FIX(22),
# Line 76  Line 57 
57      FIX(56),    FIX(58),    FIX(60),    FIX(62)      FIX(56),    FIX(58),    FIX(60),    FIX(62)
58  };  };
59    
   
 static const int16_t default_intra_matrix[64] = {  
      8,17,18,19,21,23,25,27,  
     17,18,19,21,23,25,27,28,  
     20,21,22,23,24,26,28,30,  
     21,22,23,24,26,28,30,32,  
     22,23,24,26,28,30,32,35,  
     23,24,26,28,30,32,35,38,  
     25,26,28,30,32,35,38,41,  
     27,28,30,32,35,38,41,45  
 };  
   
 static const int16_t default_inter_matrix[64] = {  
     16,17,18,19,20,21,22,23,  
     17,18,19,20,21,22,23,24,  
     18,19,20,21,22,23,24,25,  
     19,20,21,22,23,24,26,27,  
     20,21,22,23,25,26,27,28,  
     21,22,23,24,26,27,28,30,  
     22,23,24,26,27,28,30,31,  
     23,24,25,27,28,30,31,33  
 };  
   
   
60  /*    quantize intra-block  /*    quantize intra-block
61     *
62      // const int32_t quantd = DIV_DIV(VM18P*quant, VM18Q);   * const int32_t quantd = DIV_DIV(VM18P*quant, VM18Q);
63      //   * level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
64      // level = DIV_DIV(16 * data[i], default_intra_matrix[i]);   * coeff[i] = (level + quantd) / quant2;
     // coeff[i] = (level + quantd) / quant2;  
65  */  */
66    
67  void quant4_intra_c(int16_t * coeff, const int16_t * data, const uint32_t quant, const uint32_t dcscalar)  void
68    quant4_intra_c(int16_t * coeff,
69                               const int16_t * data,
70                               const uint32_t quant,
71                               const uint32_t dcscalar)
72  {  {
73      const uint32_t quantd = ((VM18P*quant) + (VM18Q/2)) / VM18Q;      const uint32_t quantd = ((VM18P*quant) + (VM18Q/2)) / VM18Q;
74      const uint32_t mult = multipliers[quant];      const uint32_t mult = multipliers[quant];
75      uint32_t i;      uint32_t i;
76            int16_t *intra_matrix;
77    
78            intra_matrix = get_intra_matrix();
79    
80      coeff[0] = DIV_DIV(data[0], (int32_t)dcscalar);      coeff[0] = DIV_DIV(data[0], (int32_t)dcscalar);
81    
82      for (i = 1; i < 64; i++)          for (i = 1; i < 64; i++) {
83      {                  if (data[i] < 0) {
         if (data[i] < 0)  
         {  
84              uint32_t level = -data[i];              uint32_t level = -data[i];
85              level = ((level<<4) + (default_intra_matrix[i]>>1)) / default_intra_matrix[i];  
86                            level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
87              level = ((level + quantd) * mult) >> 17;              level = ((level + quantd) * mult) >> 17;
88              coeff[i] = -(int16_t)level;              coeff[i] = -(int16_t)level;
89          }                  } else if (data[i] > 0) {
         else if (data[i] > 0)  
         {  
90              uint32_t level = data[i];              uint32_t level = data[i];
91              level = ((level<<4) + (default_intra_matrix[i]>>1)) / default_intra_matrix[i];  
92                            level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
93              level = ((level + quantd) * mult) >> 17;              level = ((level + quantd) * mult) >> 17;
94              coeff[i] = level;              coeff[i] = level;
95          }                  } else {
         else  
         {  
96              coeff[i] = 0;              coeff[i] = 0;
97          }          }
98      }      }
# Line 141  Line 100 
100    
101    
102    
103  /*    dequantize intra-block & clamp to [-2048,2047]  /*
104      // data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;   * dequantize intra-block & clamp to [-2048,2047]
105     *
106     * data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;
107  */  */
108    
109  void dequant4_intra_c(int16_t *data, const int16_t *coeff, const uint32_t quant, const uint32_t dcscalar)  void
110    dequant4_intra_c(int16_t * data,
111                                     const int16_t * coeff,
112                                     const uint32_t quant,
113                                     const uint32_t dcscalar)
114  {  {
115      uint32_t i;      uint32_t i;
116            int16_t *intra_matrix;
117    
118            intra_matrix = get_intra_matrix();
119    
120      data[0] = coeff[0]  * dcscalar;      data[0] = coeff[0]  * dcscalar;
121      if (data[0] < -2048)          if (data[0] < -2048) {
     {  
122          data[0] = -2048;          data[0] = -2048;
123      }          } else if (data[0] > 2047) {
     else if (data[0] > 2047)  
     {  
124          data[0] = 2047;          data[0] = 2047;
125      }      }
126    
127      for (i = 1; i < 64; i++)          for (i = 1; i < 64; i++) {
128      {                  if (coeff[i] == 0) {
         if (coeff[i] == 0)  
         {  
129              data[i] = 0;              data[i] = 0;
130          }                  } else if (coeff[i] < 0) {
         else if (coeff[i] < 0)  
         {  
131              uint32_t level = -coeff[i];              uint32_t level = -coeff[i];
132              level = (level * default_intra_matrix[i] * quant) >> 3;  
133                            level = (level * intra_matrix[i] * quant) >> 3;
134              data[i] = (level <= 2048 ? -(int16_t)level : -2048);              data[i] = (level <= 2048 ? -(int16_t)level : -2048);
135          }                  } else                                  /* if (coeff[i] > 0) */
         else // if (coeff[i] > 0)  
136          {          {
137              uint32_t level = coeff[i];              uint32_t level = coeff[i];
138              level = (level * default_intra_matrix[i] * quant) >> 3;  
139                            level = (level * intra_matrix[i] * quant) >> 3;
140              data[i] = (level <= 2047 ? level : 2047);              data[i] = (level <= 2047 ? level : 2047);
141          }          }
142      }      }
# Line 183  Line 145 
145    
146    
147  /*    quantize inter-block  /*    quantize inter-block
148     *
149      // level = DIV_DIV(16 * data[i], default_intra_matrix[i]);   * level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
150      // coeff[i] = (level + quantd) / quant2;   * coeff[i] = (level + quantd) / quant2;
151      // sum += abs(level);   * sum += abs(level);
152  */  */
153    
154  uint32_t quant4_inter_c(int16_t * coeff, const int16_t * data, const uint32_t quant)  uint32_t
155    quant4_inter_c(int16_t * coeff,
156                               const int16_t * data,
157                               const uint32_t quant)
158  {  {
159      const uint32_t mult = multipliers[quant];      const uint32_t mult = multipliers[quant];
160      uint32_t sum = 0;      uint32_t sum = 0;
161      uint32_t i;      uint32_t i;
162            int16_t *inter_matrix;
163    
164      for (i = 0; i < 64; i++)          inter_matrix = get_inter_matrix();
165      {  
166          if (data[i] < 0)          for (i = 0; i < 64; i++) {
167          {                  if (data[i] < 0) {
168              uint32_t level = -data[i];              uint32_t level = -data[i];
169              level = ((level<<4) + (default_inter_matrix[i]>>1)) / default_inter_matrix[i];  
170                            level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
171              level = (level * mult) >> 17;              level = (level * mult) >> 17;
172              sum += level;              sum += level;
173              coeff[i] = -(int16_t)level;              coeff[i] = -(int16_t)level;
174          }                  } else if (data[i] > 0) {
         else if (data[i] > 0)  
         {  
175              uint32_t level = data[i];              uint32_t level = data[i];
176              level = ((level<<4) + (default_inter_matrix[i]>>1)) / default_inter_matrix[i];  
177                            level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
178              level = (level * mult) >> 17;              level = (level * mult) >> 17;
179              sum += level;              sum += level;
180              coeff[i] = level;              coeff[i] = level;
181          }                  } else {
         else  
         {  
182              coeff[i] = 0;              coeff[i] = 0;
183          }          }
184      }      }
# Line 227  Line 191 
191    data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16    data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16
192  */  */
193    
194  void dequant4_inter_c(int16_t *data, const int16_t *coeff, const uint32_t quant)  void
195    dequant4_inter_c(int16_t * data,
196                                     const int16_t * coeff,
197                                     const uint32_t quant)
198  {  {
199      uint32_t sum = 0;      uint32_t sum = 0;
200      uint32_t i;      uint32_t i;
201            int16_t *inter_matrix;
202    
203      for (i = 0; i < 64; i++)          inter_matrix = get_inter_matrix();
204      {  
205          if (coeff[i] == 0)          for (i = 0; i < 64; i++) {
206          {                  if (coeff[i] == 0) {
207              data[i] = 0;              data[i] = 0;
208          }                  } else if (coeff[i] < 0) {
         else if (coeff[i] < 0)  
         {  
209              int32_t level = -coeff[i];              int32_t level = -coeff[i];
210              level = ((2 * level + 1) * default_inter_matrix[i] * quant) >> 4;  
211                            level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
212              data[i] = (level <= 2048 ? -level : -2048);              data[i] = (level <= 2048 ? -level : -2048);
213          }                  } else                                  /* if (coeff[i] > 0) */
         else // if (coeff[i] > 0)  
214          {          {
215              uint32_t level = coeff[i];              uint32_t level = coeff[i];
216              level = ((2 * level + 1) * default_inter_matrix[i] * quant) >> 4;  
217                            level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
218              data[i] = (level <= 2047 ? level : 2047);              data[i] = (level <= 2047 ? level : 2047);
219          }          }
220    
221          sum ^= data[i];          sum ^= data[i];
222      }      }
223    
224      // mismatch control          /*  mismatch control */
225    
226      if ((sum & 1) == 0)          if ((sum & 1) == 0) {
     {  
227          data[63] ^= 1;          data[63] ^= 1;
228      }      }
229  }  }

Legend:
Removed from v.3  
changed lines
  Added in v.1054

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