rate_ctl.c
上传用户:enenge
上传日期:2007-01-08
资源大小:96k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *                                                                        *
  3.  * This code is developed by Adam Li.  This software is an                *
  4.  * implementation of a part of one or more MPEG-4 Video tools as          *
  5.  * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  6.  * software module in hardware or software products are advised that its  *
  7.  * use may infringe existing patents or copyrights, and any such use      *
  8.  * would be at such party's own risk.  The original developer of this     *
  9.  * software module and his/her company, and subsequent editors and their  *
  10.  * companies (including Project Mayo), will have no liability for use of  *
  11.  * this software or modifications or derivatives thereof.                 *
  12.  *                                                                        *
  13.  * Project Mayo gives users of the Codec a license to this software       *
  14.  * module or modifications thereof for use in hardware or software        *
  15.  * products claiming conformance to the MPEG-4 Video Standard as          *
  16.  * described in the Open DivX license.                                    *
  17.  *                                                                        *
  18.  * The complete Open DivX license can be found at                         *
  19.  * http://www.projectmayo.com/opendivx/license.php .                      *
  20.  *                                                                        *
  21.  **************************************************************************/
  22. /**************************************************************************
  23.  *
  24.  *  rate_ctl.c
  25.  *
  26.  *  Copyright (C) 2001  Project Mayo
  27.  *
  28.  *  Adam Li
  29.  *
  30.  *  DivX Advance Research Center <darc@projectmayo.com>
  31.  *
  32.  **************************************************************************/
  33. /* This file contains some functions for rate control of the encoding.    */
  34. #include "stdio.h"
  35. extern FILE *ftrace;
  36. extern int max_quantizer, min_quantizer;
  37. typedef struct _rc_param_ {
  38. double quant;
  39. int rc_period;
  40. double target_rate;
  41. double average_rate;
  42. double reaction_rate;
  43. double average_delta;
  44. double reaction_delta;
  45. double reaction_ratio;
  46. } RC_Param;
  47. static RC_Param rc_param;
  48. void RateCtlInit(double quant, double target_rate, 
  49. long rc_period, long rc_reaction_period, long rc_reaction_ratio)
  50. {
  51. #ifdef _RC_
  52. fprintf(ftrace, "Initializing Rate Control module:n");
  53. fprintf(ftrace, "Initial quantizer is %f.n", quant);
  54. fprintf(ftrace, "Target rate is %f bits per frame.n", target_rate);
  55. fprintf(ftrace, "RC averaging period is %d.n", rc_period);
  56. fprintf(ftrace, "RC reaction period is %d.n", rc_reaction_period);
  57. fprintf(ftrace, "RC reaction ratio is %d.n", rc_reaction_ratio);
  58. #endif
  59. rc_param.quant = quant;
  60. rc_param.rc_period = rc_period;
  61. rc_param.target_rate = target_rate;
  62. rc_param.reaction_ratio = rc_reaction_ratio;
  63. rc_param.average_delta = 1. / rc_period;
  64. rc_param.reaction_delta = 1. / rc_reaction_period;
  65. rc_param.average_rate = target_rate;
  66. rc_param.reaction_rate = target_rate;
  67. return;
  68. }
  69. int RateCtlGetQ(double MAD)
  70. {
  71. double quant;
  72. quant = rc_param.quant;
  73. // if (MAD < 5.) 
  74. // quant = min_quantizer + (quant - min_quantizer) * MAD / 5.;
  75. return (int)(quant + 0.5);
  76. }
  77. void RateCtlUpdate(int current_frame)
  78. {
  79. double rate, delta, decay;
  80. double target, current_target;
  81. double median_quant;
  82. #ifdef _RC_
  83. fprintf(ftrace, "Quantizer is currently %f.n", rc_param.quant);
  84. fprintf(ftrace, "Current frame is %d bits long.n", current_frame);
  85. #endif
  86. rate = rc_param.average_rate;
  87. delta = rc_param.average_delta;
  88. decay = 1 - delta;
  89. rate = rate * decay + current_frame * delta;
  90. rc_param.average_rate = rate;
  91. target = rc_param.target_rate;
  92. if (rate > target) {
  93. current_target = target - (rate - target);
  94. if (current_target < target * 0.75) current_target = target * 0.75;
  95. } else {
  96. current_target = target;
  97. }
  98. #ifdef _RC_
  99. fprintf(ftrace, "Target rate is %f.n", target);
  100. fprintf(ftrace, "Average rate is %f.n", rate);
  101. fprintf(ftrace, "Target rate for current frame is %f.n", current_target);
  102. #endif
  103. rate = rc_param.reaction_rate;
  104. delta = rc_param.reaction_delta;
  105. decay = 1 - delta;
  106. rate = rate * decay + current_frame * delta;
  107. rc_param.reaction_rate = rate;
  108. median_quant = min_quantizer + (max_quantizer - min_quantizer) / 2;
  109. /* reduce quantizer when the reaction rate is low */
  110. if (rate < current_target) rc_param.quant *= 
  111. (1 - rc_param.reaction_delta * ((current_target - rate) / current_target / 0.20) );
  112. if (rc_param.quant < min_quantizer) rc_param.quant = min_quantizer;
  113. /* increase quantizer when the reaction rate is high */
  114. if (rate > current_target) {
  115. /* slower increasement when the quant is higher than median */
  116. if (rc_param.quant > median_quant) 
  117. rc_param.quant *= (1 + rc_param.reaction_delta / rc_param.reaction_ratio);
  118. /* faster increasement when the quant is lower than median */
  119. else if (rate > current_target * 1.20) rc_param.quant *=
  120. (1 + rc_param.reaction_delta);
  121. else rc_param.quant *= 
  122. (1 + rc_param.reaction_delta * ((rate - current_target) / current_target / 0.20) );
  123. }
  124. if (rc_param.quant > max_quantizer) rc_param.quant = max_quantizer;
  125. #ifdef _RC_
  126. fprintf(ftrace, "Reaction rate is %f.n", rate);
  127. fprintf(ftrace, "Quantizer is updated to %f.n", rc_param.quant);
  128. #endif
  129. return;
  130. }