2 /**************************************************************************
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
22 **************************************************************************/
24 /**************************************************************************
28 * Copyright (C) 2001 Project Mayo
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some functions for rate control of the encoding. */
41 extern int max_quantizer
, min_quantizer
;
43 typedef struct _rc_param_
{
50 double reaction_delta
;
51 double reaction_ratio
;
54 static RC_Param rc_param
;
56 void RateCtlInit(double quant
, double target_rate
,
57 long rc_period
, long rc_reaction_period
, long rc_reaction_ratio
)
60 fprintf(ftrace
, "Initializing Rate Control module:\n");
61 fprintf(ftrace
, "Initial quantizer is %f.\n", quant
);
62 fprintf(ftrace
, "Target rate is %f bits per frame.\n", target_rate
);
63 fprintf(ftrace
, "RC averaging period is %d.\n", rc_period
);
64 fprintf(ftrace
, "RC reaction period is %d.\n", rc_reaction_period
);
65 fprintf(ftrace
, "RC reaction ratio is %d.\n", rc_reaction_ratio
);
68 rc_param
.quant
= quant
;
69 rc_param
.rc_period
= rc_period
;
70 rc_param
.target_rate
= target_rate
;
71 rc_param
.reaction_ratio
= rc_reaction_ratio
;
73 rc_param
.average_delta
= 1. / rc_period
;
74 rc_param
.reaction_delta
= 1. / rc_reaction_period
;
75 rc_param
.average_rate
= target_rate
;
76 rc_param
.reaction_rate
= target_rate
;
81 int RateCtlGetQ(double MAD
)
85 quant
= rc_param
.quant
;
88 // quant = min_quantizer + (quant - min_quantizer) * MAD / 5.;
90 return (int)(quant
+ 0.5);
93 void RateCtlUpdate(int current_frame
)
95 double rate
, delta
, decay
;
96 double target
, current_target
;
100 fprintf(ftrace
, "Quantizer is currently %f.\n", rc_param
.quant
);
101 fprintf(ftrace
, "Current frame is %d bits long.\n", current_frame
);
104 rate
= rc_param
.average_rate
;
105 delta
= rc_param
.average_delta
;
107 rate
= rate
* decay
+ current_frame
* delta
;
108 rc_param
.average_rate
= rate
;
110 target
= rc_param
.target_rate
;
112 current_target
= target
- (rate
- target
);
113 if (current_target
< target
* 0.75) current_target
= target
* 0.75;
115 current_target
= target
;
119 fprintf(ftrace
, "Target rate is %f.\n", target
);
120 fprintf(ftrace
, "Average rate is %f.\n", rate
);
121 fprintf(ftrace
, "Target rate for current frame is %f.\n", current_target
);
124 rate
= rc_param
.reaction_rate
;
125 delta
= rc_param
.reaction_delta
;
127 rate
= rate
* decay
+ current_frame
* delta
;
128 rc_param
.reaction_rate
= rate
;
130 median_quant
= min_quantizer
+ (max_quantizer
- min_quantizer
) / 2;
132 /* reduce quantizer when the reaction rate is low */
133 if (rate
< current_target
) rc_param
.quant
*=
134 (1 - rc_param
.reaction_delta
* ((current_target
- rate
) / current_target
/ 0.20) );
135 if (rc_param
.quant
< min_quantizer
) rc_param
.quant
= min_quantizer
;
137 /* increase quantizer when the reaction rate is high */
138 if (rate
> current_target
) {
139 /* slower increasement when the quant is higher than median */
140 if (rc_param
.quant
> median_quant
)
141 rc_param
.quant
*= (1 + rc_param
.reaction_delta
/ rc_param
.reaction_ratio
);
142 /* faster increasement when the quant is lower than median */
143 else if (rate
> current_target
* 1.20) rc_param
.quant
*=
144 (1 + rc_param
.reaction_delta
);
145 else rc_param
.quant
*=
146 (1 + rc_param
.reaction_delta
* ((rate
- current_target
) / current_target
/ 0.20) );
148 if (rc_param
.quant
> max_quantizer
) rc_param
.quant
= max_quantizer
;
151 fprintf(ftrace
, "Reaction rate is %f.\n", rate
);
152 fprintf(ftrace
, "Quantizer is updated to %f.\n", rc_param
.quant
);