[cvs] / xvidcore / src / plugins / plugin_single.c Repository:
ViewVC logotype

Annotation of /xvidcore/src/plugins/plugin_single.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (view) (download)

1 : edgomez 1.2 /*****************************************************************************
2 :     *
3 : Isibaar 1.4 * Xvid Standard Plugins
4 : edgomez 1.2 * - single-pass bitrate controller implementation -
5 :     *
6 : edgomez 1.3 * Copyright(C) 2002-2004 Benjamin Lambert <foxer@hotmail.com>
7 : edgomez 1.2 * 2002-2003 Edouard Gomez <ed.gomez@free.fr>
8 :     *
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 : Isibaar 1.5 * $Id: plugin_single.c,v 1.4 2010/03/09 10:00:14 Isibaar Exp $
24 : edgomez 1.2 *
25 :     ****************************************************************************/
26 :    
27 :    
28 :     #include <limits.h>
29 :    
30 :     #include "../xvid.h"
31 :     #include "../image/image.h"
32 :    
33 : Isibaar 1.4 #define DEFAULT_INITIAL_QUANTIZER 8
34 : edgomez 1.2
35 :     #define DEFAULT_BITRATE 900000 /* 900kbps */
36 :     #define DEFAULT_DELAY_FACTOR 16
37 :     #define DEFAULT_AVERAGING_PERIOD 100
38 :     #define DEFAULT_BUFFER 100
39 :    
40 :     typedef struct
41 :     {
42 :     int reaction_delay_factor;
43 :     int averaging_period;
44 :     int buffer;
45 :    
46 :     int bytes_per_sec;
47 :     double target_framesize;
48 :    
49 :     double time;
50 :     int64_t total_size;
51 :     int rtn_quant;
52 :    
53 :     double sequence_quality;
54 :     double avg_framesize;
55 :     double quant_error[31];
56 :    
57 :     double fq_error;
58 :     }
59 :     rc_single_t;
60 :    
61 :    
62 :     static int
63 :     get_initial_quant(unsigned int bitrate)
64 :     {
65 :    
66 :     #if defined(DEFAULT_INITIAL_QUANTIZER)
67 :     return (DEFAULT_INITIAL_QUANTIZER);
68 :     #else
69 :     int i;
70 :    
71 :     const unsigned int bitrate_quant[31] = {
72 :     UINT_MAX
73 :     };
74 :    
75 :     for (i = 30; i >= 0; i--) {
76 :     if (bitrate > bitrate_quant[i])
77 :     continue;
78 :     }
79 :    
80 :     return (i + 1);
81 :     #endif
82 :     }
83 :    
84 :     static int
85 :     rc_single_create(xvid_plg_create_t * create,
86 :     rc_single_t ** handle)
87 :     {
88 :     xvid_plugin_single_t *param = (xvid_plugin_single_t *) create->param;
89 :     rc_single_t *rc;
90 :     int i;
91 :    
92 :     /*
93 :     * single needs to caclculate the average frame size. In order to do that,
94 :     * we really need valid fps
95 :     */
96 :     if (create->fincr == 0) {
97 :     return XVID_ERR_FAIL;
98 :     }
99 :    
100 :     /* Allocate context struct */
101 :     if ((rc = malloc(sizeof(rc_single_t))) == NULL)
102 :     return (XVID_ERR_MEMORY);
103 :    
104 :     /* Constants */
105 :     rc->bytes_per_sec = (param->bitrate > 0) ? param->bitrate / 8 : DEFAULT_BITRATE / 8;
106 :     rc->target_framesize =(double) rc->bytes_per_sec / ((double) create->fbase / create->fincr);
107 :     rc->reaction_delay_factor = (param->reaction_delay_factor > 0) ? param->reaction_delay_factor : DEFAULT_DELAY_FACTOR;
108 :     rc->averaging_period = (param->averaging_period > 0) ? param->averaging_period : DEFAULT_AVERAGING_PERIOD;
109 :     rc->buffer = (param->buffer > 0) ? param->buffer : DEFAULT_BUFFER;
110 :    
111 :     rc->time = 0;
112 :     rc->total_size = 0;
113 :     rc->rtn_quant = get_initial_quant(param->bitrate);
114 :    
115 :     /* Reset quant error accumulators */
116 :     for (i = 0; i < 31; i++)
117 :     rc->quant_error[i] = 0.0;
118 :    
119 :     /* Last bunch of variables */
120 :     rc->sequence_quality = 2.0 / (double) rc->rtn_quant;
121 :     rc->avg_framesize = rc->target_framesize;
122 :    
123 :     rc->fq_error = 0;
124 :    
125 :     /* Bind the RC */
126 :     *handle = rc;
127 :    
128 :     /* A bit of debug info */
129 :     DPRINTF(XVID_DEBUG_RC, "bytes_per_sec: %i\n", rc->bytes_per_sec);
130 :     DPRINTF(XVID_DEBUG_RC, "frame rate : %f\n", (double) create->fbase / create->fincr);
131 :     DPRINTF(XVID_DEBUG_RC, "target_framesize: %f\n", rc->target_framesize);
132 :    
133 :     return (0);
134 :     }
135 :    
136 :    
137 :     static int
138 :     rc_single_destroy(rc_single_t * rc,
139 :     xvid_plg_destroy_t * destroy)
140 :     {
141 :     free(rc);
142 :     return (0);
143 :     }
144 :    
145 :    
146 :     static int
147 :     rc_single_before(rc_single_t * rc,
148 :     xvid_plg_data_t * data)
149 :     {
150 :     if (data->quant <= 0) {
151 :     if (data->zone && data->zone->mode == XVID_ZONE_QUANT) {
152 :     rc->fq_error += (double)data->zone->increment / (double)data->zone->base;
153 :     data->quant = (int)rc->fq_error;
154 :     rc->fq_error -= data->quant;
155 :     } else {
156 :     int q = rc->rtn_quant;
157 :     /* limit to min/max range
158 :     we don't know frame type of the next frame, so we just use
159 :     P-VOP's range... */
160 :     if (q > data->max_quant[XVID_TYPE_PVOP-1])
161 :     q = data->max_quant[XVID_TYPE_PVOP-1];
162 :     else if (q < data->min_quant[XVID_TYPE_PVOP-1])
163 :     q = data->min_quant[XVID_TYPE_PVOP-1];
164 :    
165 :     data->quant = q;
166 :     }
167 :     }
168 :     return 0;
169 :     }
170 :    
171 :    
172 :     static int
173 :     rc_single_after(rc_single_t * rc,
174 :     xvid_plg_data_t * data)
175 :     {
176 :     int64_t deviation;
177 :     int rtn_quant;
178 :     double overflow;
179 :     double averaging_period;
180 :     double reaction_delay_factor;
181 :     double quality_scale;
182 :     double base_quality;
183 :     double target_quality;
184 :    
185 :     /* Update internal values */
186 :     rc->time += (double) data->fincr / data->fbase;
187 :     rc->total_size += data->length;
188 :    
189 :     /* Compute the deviation from expected total size */
190 : Isibaar 1.5 deviation = (int64_t)
191 :     (rc->total_size - rc->bytes_per_sec * rc->time);
192 : edgomez 1.2
193 : edgomez 1.3 averaging_period = (double) rc->averaging_period;
194 : edgomez 1.2
195 : edgomez 1.3 /* calculate the sequence quality */
196 :     rc->sequence_quality -= rc->sequence_quality / averaging_period;
197 : edgomez 1.2
198 : edgomez 1.3 rc->sequence_quality +=
199 :     2.0 / (double) data->quant / averaging_period;
200 : edgomez 1.2
201 : edgomez 1.3 /* clamp the sequence quality to 10% to 100%
202 :     * to try to avoid using the highest
203 :     * and lowest quantizers 'too' much */
204 :     if (rc->sequence_quality < 0.1)
205 :     rc->sequence_quality = 0.1;
206 :     else if (rc->sequence_quality > 1.0)
207 :     rc->sequence_quality = 1.0;
208 :    
209 :     /* factor this frame's size into the average framesize
210 :     * but skip using ivops as they are usually very large
211 :     * and as such, usually disrupt quantizer distribution */
212 :     if (data->type != XVID_TYPE_IVOP) {
213 :     reaction_delay_factor = (double) rc->reaction_delay_factor;
214 :     rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;
215 :     rc->avg_framesize += data->length / reaction_delay_factor;
216 :     }
217 : edgomez 1.2
218 : edgomez 1.3 /* don't change the quantizer between pvops */
219 :     if (data->type == XVID_TYPE_BVOP)
220 :     return (0);
221 : edgomez 1.2
222 : edgomez 1.3 /* calculate the quality_scale which will be used
223 :     * to drag the target quality up or down, depending
224 :     * on if avg_framesize is >= target_framesize */
225 : edgomez 1.2 quality_scale =
226 : edgomez 1.3 rc->target_framesize / rc->avg_framesize *
227 :     rc->target_framesize / rc->avg_framesize;
228 : edgomez 1.2
229 : edgomez 1.3 /* use the current sequence_quality as the
230 :     * base_quality which will be dragged around
231 :     *
232 :     * 0.06452 = 6.452% quality (quant:31) */
233 : edgomez 1.2 base_quality = rc->sequence_quality;
234 :     if (quality_scale >= 1.0) {
235 :     base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
236 :     } else {
237 :     base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
238 :     }
239 :    
240 :     overflow = -((double) deviation / (double) rc->buffer);
241 :    
242 : edgomez 1.3 /* clamp overflow to 1 buffer unit to avoid very
243 :     * large bursts of bitrate following still scenes */
244 :     if (overflow > rc->target_framesize)
245 :     overflow = rc->target_framesize;
246 :     else if (overflow < -rc->target_framesize)
247 :     overflow = -rc->target_framesize;
248 :    
249 :     /* apply overflow / buffer to get the target_quality */
250 : edgomez 1.2 target_quality =
251 :     base_quality + (base_quality -
252 :     0.06452) * overflow / rc->target_framesize;
253 :    
254 : edgomez 1.3 /* clamp the target_quality to quant 1-31
255 :     * 2.0 = 200% quality (quant:1) */
256 : edgomez 1.2 if (target_quality > 2.0)
257 :     target_quality = 2.0;
258 :     else if (target_quality < 0.06452)
259 :     target_quality = 0.06452;
260 :    
261 :     rtn_quant = (int) (2.0 / target_quality);
262 :    
263 : edgomez 1.3 /* accumulate quant <-> quality error and apply if >= 1.0 */
264 : edgomez 1.2 if (rtn_quant > 0 && rtn_quant < 31) {
265 :     rc->quant_error[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;
266 :     if (rc->quant_error[rtn_quant - 1] >= 1.0) {
267 :     rc->quant_error[rtn_quant - 1] -= 1.0;
268 :     rtn_quant++;
269 : edgomez 1.3 rc->rtn_quant++;
270 : edgomez 1.2 }
271 :     }
272 :    
273 :     /* prevent rapid quantization change */
274 : edgomez 1.3 if (rtn_quant > rc->rtn_quant + 1) {
275 :     if (rtn_quant > rc->rtn_quant + 3)
276 :     if (rtn_quant > rc->rtn_quant + 5)
277 :     rtn_quant = rc->rtn_quant + 3;
278 :     else
279 :     rtn_quant = rc->rtn_quant + 2;
280 :     else
281 :     rtn_quant = rc->rtn_quant + 1;
282 :     }
283 :     else if (rtn_quant < rc->rtn_quant - 1) {
284 :     if (rtn_quant < rc->rtn_quant - 3)
285 :     if (rtn_quant < rc->rtn_quant - 5)
286 :     rtn_quant = rc->rtn_quant - 3;
287 :     else
288 :     rtn_quant = rc->rtn_quant - 2;
289 :     else
290 :     rtn_quant = rc->rtn_quant - 1;
291 :     }
292 : edgomez 1.2
293 :     rc->rtn_quant = rtn_quant;
294 :    
295 :     return (0);
296 :     }
297 :    
298 :    
299 :    
300 :     int
301 :     xvid_plugin_single(void *handle,
302 :     int opt,
303 :     void *param1,
304 :     void *param2)
305 :     {
306 :     switch (opt) {
307 :     case XVID_PLG_INFO:
308 :     case XVID_PLG_FRAME :
309 :     return 0;
310 :    
311 :     case XVID_PLG_CREATE:
312 :     return rc_single_create((xvid_plg_create_t *) param1, param2);
313 :    
314 :     case XVID_PLG_DESTROY:
315 :     return rc_single_destroy((rc_single_t *) handle,(xvid_plg_destroy_t *) param1);
316 :    
317 :     case XVID_PLG_BEFORE:
318 :     return rc_single_before((rc_single_t *) handle, (xvid_plg_data_t *) param1);
319 :    
320 :     case XVID_PLG_AFTER:
321 :     return rc_single_after((rc_single_t *) handle, (xvid_plg_data_t *) param1);
322 :     }
323 :    
324 :     return XVID_ERR_FAIL;
325 :     }

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