quant_mpeg4.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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