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

Annotation of /branches/dev-api-4/xvidcore/src/plugins/plugin_cbr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 994 - (view) (download)

1 : suxen_drol 938 /*****************************************************************************
2 :     *
3 : edgomez 994 * XviD Standard Plugins
4 : suxen_drol 938 * - CBR/ABR bitrate controller implementation -
5 :     *
6 : edgomez 994 * Copyright(C) 2002 Benjamin Lambert <foxer@hotmail.com>
7 :     * 2002-2003 Edouard Gomez <ed.gomez@free.fr>
8 : suxen_drol 938 *
9 :     * This program is free software; you can redistribute it and/or modify
10 :     * it under the terms of the GNU General Public License as published by
11 :     * the Free Software Foundation; either version 2 of the License, or
12 :     * (at your option) any later version.
13 :     *
14 :     * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 :     *
19 :     * You should have received a copy of the GNU General Public License
20 :     * along with this program; if not, write to the Free Software
21 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     *
23 : edgomez 994 * $Id: plugin_cbr.c,v 1.1.2.3 2003-04-27 15:40:50 edgomez Exp $
24 : suxen_drol 938 *
25 :     ****************************************************************************/
26 :    
27 :    
28 : edgomez 994 #include <limits.h>
29 :    
30 : suxen_drol 938 #include "../xvid.h"
31 :     #include "../image/image.h"
32 :    
33 : edgomez 994 #define DEFAULT_INITIAL_QUANTIZER 5
34 : suxen_drol 938
35 : edgomez 994 #define DEFAULT_BITRATE 900000 /* 900kbps */
36 :     #define DEFAULT_MAX_QUANT 31
37 :     #define DEFAULT_MIN_QUANT 2
38 :     #define DEFAULT_DELAY_FACTOR 16
39 :     #define DEFAULT_AVERAGING_PERIOD 100
40 :     #define DEFAULT_BUFFER 100
41 : suxen_drol 938
42 :     typedef struct
43 :     {
44 : edgomez 994 int max_quantizer;
45 :     int min_quantizer;
46 :     int reaction_delay_factor;
47 :     int averaging_period;
48 :     int buffer;
49 : suxen_drol 938
50 : edgomez 994 int bytes_per_sec;
51 :     double target_framesize;
52 :    
53 :     double time;
54 : suxen_drol 938 int64_t total_size;
55 :     int rtn_quant;
56 :    
57 :    
58 : edgomez 994 double sequence_quality;
59 :     double avg_framesize;
60 :     double quant_error[31];
61 :     }
62 :     rc_cbr_t;
63 : suxen_drol 938
64 :    
65 : edgomez 994 static int
66 :     get_initial_quant(unsigned int bitrate)
67 :     {
68 : suxen_drol 938
69 : edgomez 994 #if 0
70 :     int i;
71 :    
72 :     const unsigned int bitrate_quant[31] = {
73 :     UINT_MAX
74 :     };
75 :    
76 :     for (i = 30; i >= 0; i--) {
77 :     if (bitrate > bitrate_quant[i])
78 :     continue;
79 :     }
80 :    
81 :     return (i + 1);
82 :     #else
83 :     return (DEFAULT_INITIAL_QUANTIZER);
84 :     #endif
85 :     }
86 :    
87 :     static int
88 :     rc_cbr_create(xvid_plg_create_t * create,
89 :     rc_cbr_t ** handle)
90 : suxen_drol 938 {
91 : edgomez 994 xvid_plugin_cbr_t *param = (xvid_plugin_cbr_t *) create->param;
92 :     rc_cbr_t *rc;
93 : suxen_drol 938 int i;
94 :    
95 : edgomez 994 /*
96 :     * CBR needs to caclculate the average frame size. In order to do that,
97 :     * we really need valid fps
98 :     */
99 :     if (create->fincr == 0) {
100 :     return XVID_ERR_FAIL;
101 :     }
102 : suxen_drol 938
103 : edgomez 994 /* Allocate context struct */
104 :     if ((rc = malloc(sizeof(rc_cbr_t))) == NULL)
105 :     return (XVID_ERR_MEMORY);
106 : suxen_drol 938
107 : edgomez 994 /* Constants */
108 :     rc->bytes_per_sec = (param->bitrate > 0) ? param->bitrate / 8 : DEFAULT_BITRATE / 8;
109 :     rc->target_framesize =(double) rc->bytes_per_sec / ((double) create->fbase / create->fincr);
110 :     rc->max_quantizer = (param->max_quantizer > 0) ? param->max_quantizer : DEFAULT_MAX_QUANT;
111 :     rc->min_quantizer = (param->min_quantizer > 0) ? param->min_quantizer : DEFAULT_MIN_QUANT;
112 :     rc->reaction_delay_factor = (param->reaction_delay_factor > 0) ? param->reaction_delay_factor : DEFAULT_DELAY_FACTOR;
113 :     rc->averaging_period = (param->averaging_period > 0) ? param->averaging_period : DEFAULT_AVERAGING_PERIOD;
114 :     rc->buffer = (param->buffer > 0) ? param->buffer : DEFAULT_BUFFER;
115 : suxen_drol 938
116 : edgomez 994 rc->time = 0;
117 :     rc->total_size = 0;
118 :     rc->rtn_quant = get_initial_quant(param->bitrate);
119 : suxen_drol 938
120 :     /* Reset quant error accumulators */
121 :     for (i = 0; i < 31; i++)
122 :     rc->quant_error[i] = 0.0;
123 :    
124 :     /* Last bunch of variables */
125 : edgomez 994 rc->sequence_quality = 2.0 / (double) rc->rtn_quant;
126 : suxen_drol 938 rc->avg_framesize = rc->target_framesize;
127 :    
128 : edgomez 994 /* Bind the RC */
129 :     *handle = rc;
130 :    
131 :     /* A bit of debug info */
132 :     DPRINTF(DPRINTF_RC, "bytes_per_sec: %i\n", rc->bytes_per_sec);
133 :     DPRINTF(DPRINTF_RC, "frame rate : %f\n", (double) create->fbase / create->fincr);
134 :     DPRINTF(DPRINTF_RC, "target_framesize: %f\n", rc->target_framesize);
135 :    
136 :     return (0);
137 : suxen_drol 938 }
138 :    
139 :    
140 : edgomez 994 static int
141 :     rc_cbr_destroy(rc_cbr_t * rc,
142 :     xvid_plg_destroy_t * destroy)
143 : suxen_drol 938 {
144 :     free(rc);
145 : edgomez 994 return (0);
146 : suxen_drol 938 }
147 :    
148 :    
149 : edgomez 994 static int
150 :     rc_cbr_before(rc_cbr_t * rc,
151 :     xvid_plg_data_t * data)
152 : suxen_drol 938 {
153 : edgomez 994 data->quant = rc->rtn_quant;
154 :     data->type = XVID_TYPE_AUTO;
155 :     return 0;
156 : suxen_drol 938 }
157 :    
158 :    
159 : edgomez 994 static int
160 :     rc_cbr_after(rc_cbr_t * rc,
161 :     xvid_plg_data_t * data)
162 : suxen_drol 938 {
163 :     int64_t deviation;
164 :     int rtn_quant;
165 :     double overflow;
166 :     double averaging_period;
167 :     double reaction_delay_factor;
168 :     double quality_scale;
169 :     double base_quality;
170 :     double target_quality;
171 :    
172 : edgomez 994
173 : suxen_drol 938 /* Update internal values */
174 : edgomez 994 rc->time += (double) data->fincr / data->fbase;
175 :     rc->total_size += data->length;
176 : suxen_drol 938
177 :     /* Compute the deviation from expected total size */
178 :     deviation = (int64_t)
179 : edgomez 994 ((double) rc->total_size - (double) rc->bytes_per_sec * rc->time);
180 : suxen_drol 938
181 :    
182 : edgomez 994 if (rc->rtn_quant >= 2) {
183 :    
184 : suxen_drol 938 averaging_period = (double) rc->averaging_period;
185 :    
186 : edgomez 994 rc->sequence_quality -= rc->sequence_quality / averaging_period;
187 : suxen_drol 938
188 :     rc->sequence_quality +=
189 :     2.0 / (double) rc->rtn_quant / averaging_period;
190 :    
191 :     if (rc->sequence_quality < 0.1)
192 :     rc->sequence_quality = 0.1;
193 :    
194 :     if (data->type != XVID_TYPE_IVOP) {
195 :     reaction_delay_factor = (double) rc->reaction_delay_factor;
196 :     rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;
197 :     rc->avg_framesize += data->length / reaction_delay_factor;
198 :     }
199 :    
200 :     }
201 :    
202 :     quality_scale =
203 : edgomez 994 rc->target_framesize / rc->avg_framesize * rc->target_framesize /
204 :     rc->avg_framesize;
205 : suxen_drol 938
206 :     base_quality = rc->sequence_quality;
207 :     if (quality_scale >= 1.0) {
208 :     base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
209 :     } else {
210 :     base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
211 :     }
212 :    
213 :     overflow = -((double) deviation / (double) rc->buffer);
214 :    
215 :     target_quality =
216 : edgomez 994 base_quality + (base_quality -
217 :     0.06452) * overflow / rc->target_framesize;
218 : suxen_drol 938
219 :     if (target_quality > 2.0)
220 :     target_quality = 2.0;
221 :     else if (target_quality < 0.06452)
222 :     target_quality = 0.06452;
223 :    
224 :     rtn_quant = (int) (2.0 / target_quality);
225 :    
226 : edgomez 994 if (rtn_quant > 0 && rtn_quant < 31) {
227 :     rc->quant_error[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;
228 :     if (rc->quant_error[rtn_quant - 1] >= 1.0) {
229 :     rc->quant_error[rtn_quant - 1] -= 1.0;
230 : suxen_drol 938 rtn_quant++;
231 :     }
232 :     }
233 :    
234 :     if (rtn_quant > rc->rtn_quant + 1)
235 :     rtn_quant = rc->rtn_quant + 1;
236 :     else if (rtn_quant < rc->rtn_quant - 1)
237 :     rtn_quant = rc->rtn_quant - 1;
238 :    
239 :     if (rtn_quant > rc->max_quantizer)
240 :     rtn_quant = rc->max_quantizer;
241 :     else if (rtn_quant < rc->min_quantizer)
242 :     rtn_quant = rc->min_quantizer;
243 :    
244 :     rc->rtn_quant = rtn_quant;
245 :    
246 : edgomez 994 return (0);
247 : suxen_drol 938 }
248 :    
249 :    
250 :    
251 : edgomez 994 int
252 :     xvid_plugin_cbr(void *handle,
253 :     int opt,
254 :     void *param1,
255 :     void *param2)
256 : suxen_drol 938 {
257 : edgomez 994 switch (opt) {
258 :     case XVID_PLG_INFO:
259 :     return 0;
260 : suxen_drol 938
261 : edgomez 994 case XVID_PLG_CREATE:
262 :     return rc_cbr_create((xvid_plg_create_t *) param1, param2);
263 : suxen_drol 938
264 : edgomez 994 case XVID_PLG_DESTROY:
265 :     return rc_cbr_destroy((rc_cbr_t *) handle,(xvid_plg_destroy_t *) param1);
266 : suxen_drol 938
267 : edgomez 994 case XVID_PLG_BEFORE:
268 :     return rc_cbr_before((rc_cbr_t *) handle, (xvid_plg_data_t *) param1);
269 : suxen_drol 938
270 : edgomez 994 case XVID_PLG_AFTER:
271 :     return rc_cbr_after((rc_cbr_t *) handle, (xvid_plg_data_t *) param1);
272 :     }
273 : suxen_drol 938
274 : edgomez 994 return XVID_ERR_FAIL;
275 : suxen_drol 938 }

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