r1009: Move the dependencies to newer package names
[cinelerra_cv/mob.git] / quicktime / encore50 / rate_ctl.c
blob62e08ffab560cfb3418483b6441867945983f1ef
2 /**************************************************************************
3 * *
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. *
13 * *
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. *
18 * *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
21 * *
22 **************************************************************************/
24 /**************************************************************************
26 * rate_ctl.c
28 * Copyright (C) 2001 Project Mayo
30 * Adam Li
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some functions for rate control of the encoding. */
38 #include "stdio.h"
40 extern FILE *ftrace;
41 extern int max_quantizer, min_quantizer;
43 typedef struct _rc_param_ {
44 double quant;
45 int rc_period;
46 double target_rate;
47 double average_rate;
48 double reaction_rate;
49 double average_delta;
50 double reaction_delta;
51 double reaction_ratio;
52 } RC_Param;
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)
59 #ifdef _RC_
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);
66 #endif
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;
78 return;
81 int RateCtlGetQ(double MAD)
83 double quant;
85 quant = rc_param.quant;
87 // if (MAD < 5.)
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;
97 double median_quant;
99 #ifdef _RC_
100 fprintf(ftrace, "Quantizer is currently %f.\n", rc_param.quant);
101 fprintf(ftrace, "Current frame is %d bits long.\n", current_frame);
102 #endif
104 rate = rc_param.average_rate;
105 delta = rc_param.average_delta;
106 decay = 1 - delta;
107 rate = rate * decay + current_frame * delta;
108 rc_param.average_rate = rate;
110 target = rc_param.target_rate;
111 if (rate > target) {
112 current_target = target - (rate - target);
113 if (current_target < target * 0.75) current_target = target * 0.75;
114 } else {
115 current_target = target;
118 #ifdef _RC_
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);
122 #endif
124 rate = rc_param.reaction_rate;
125 delta = rc_param.reaction_delta;
126 decay = 1 - 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;
150 #ifdef _RC_
151 fprintf(ftrace, "Reaction rate is %f.\n", rate);
152 fprintf(ftrace, "Quantizer is updated to %f.\n", rc_param.quant);
153 #endif
155 return;