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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 977 - (view) (download)

1 : suxen_drol 942 /******************************************************************************
2 :     *
3 :     * XviD Bit Rate Controller Library
4 :     * - VBR 2 pass bitrate controler implementation -
5 :     *
6 :     * Copyright (C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>
7 :     *
8 :     * The curve treatment algorithm is the one implemented by Foxer <email?> and
9 :     * Dirk Knop <dknop@gwdg.de> for the XviD vfw dynamic library.
10 :     *
11 :     * This program is free software; you can redistribute it and/or modify
12 :     * it under the terms of the GNU General Public License as published by
13 :     * the Free Software Foundation; either version 2 of the License, or
14 :     * (at your option) any later version.
15 :     *
16 :     * This program is distributed in the hope that it will be useful,
17 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 :     * GNU General Public License for more details.
20 :     *
21 :     * You should have received a copy of the GNU General Public License
22 :     * along with this program; if not, write to the Free Software
23 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 :     *
25 : suxen_drol 977 * $Id: plugin_2pass2.c,v 1.1.2.2 2003-04-08 14:01:09 suxen_drol Exp $
26 : suxen_drol 942 *
27 :     *****************************************************************************/
28 :    
29 :     #include <stdio.h>
30 :     #include <math.h>
31 :    
32 :     #define RAD2DEG 57.295779513082320876798154814105
33 :     #define DEG2RAD 0.017453292519943295769236907684886
34 :    
35 :     #include "../xvid.h"
36 :     #include "../image/image.h"
37 :    
38 :     typedef struct {
39 :     int type; /* first pass type */
40 :     int quant; /* first pass quant */
41 : suxen_drol 977 int blks[3]; /* k,m,y blks */
42 : suxen_drol 942 int length; /* first pass length */
43 :     int scaled_length; /* scaled length */
44 :     int desired_length;
45 :     } stat_t;
46 :    
47 :    
48 :    
49 :    
50 :     /* context struct */
51 :     typedef struct
52 :     {
53 :     xvid_plugin_2pass2_t param;
54 :    
55 :     /* constant statistical data */
56 : suxen_drol 977 int num_frames;
57 : suxen_drol 942 int num_keyframes;
58 : suxen_drol 977 uint64_t target; /* target bitrate */
59 :    
60 : suxen_drol 942 int count[3]; /* count of each frame types */
61 :     uint64_t tot_length[3]; /* total length of each frame types */
62 :     double avg_length[3]; /* avg */
63 :     int min_length[3]; /* min frame length of each frame types */
64 :     uint64_t tot_scaled_length[3]; /* total scaled length of each frame type */
65 :     int max_length; /* max frame size */
66 :    
67 :     double curve_comp_scale;
68 :     double movie_curve;
69 :    
70 :     double alt_curve_low;
71 :     double alt_curve_high;
72 :     double alt_curve_low_diff;
73 :     double alt_curve_high_diff;
74 :     double alt_curve_curve_bias_bonus;
75 :     double alt_curve_mid_qual;
76 :     double alt_curve_qual_dev;
77 :    
78 :     /* dynamic */
79 :    
80 :     int * keyframe_locations;
81 :     stat_t * stats;
82 :    
83 :     double pquant_error[32];
84 :     double bquant_error[32];
85 :     int quant_count[32];
86 :     int last_quant[3];
87 :    
88 :     double curve_comp_error;
89 :     int overflow;
90 :     int KFoverflow;
91 :     int KFoverflow_partial;
92 :     int KF_idx;
93 :     } rc_2pass2_t;
94 :    
95 :    
96 :    
97 :     #define BUF_SZ 1024
98 :     #define MAX_COLS 5
99 :    
100 :    
101 :     /* open stats file, and count num frames */
102 :    
103 :     static int det_stats_length(rc_2pass2_t * rc, char * filename)
104 :     {
105 :     FILE * f;
106 :     int n, ignore;
107 :     char type;
108 :    
109 :     rc->num_frames = 0;
110 :     rc->num_keyframes = 0;
111 :    
112 :     if ((f = fopen(filename, "rt")) == NULL)
113 :     return 0;
114 :    
115 : suxen_drol 977 while((n = fscanf(f, "%c %d %d %d %d %d %d\n",
116 :     &type, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore)) != EOF) {
117 : suxen_drol 942 if (type == 'i') {
118 :     rc->num_frames++;
119 :     rc->num_keyframes++;
120 :     }else if (type == 'p' || type == 'b' || type == 's') {
121 :     rc->num_frames++;
122 :     }
123 :     }
124 :    
125 :     fclose(f);
126 :    
127 :     return 1;
128 :     }
129 :    
130 :    
131 : suxen_drol 977 /* scale the curve */
132 : suxen_drol 942
133 : suxen_drol 977 static void internal_scale(rc_2pass2_t *rc)
134 : suxen_drol 942 {
135 : suxen_drol 977 int64_t target = rc->target;
136 :     int64_t tot_length = rc->tot_length[0] + rc->tot_length[1] + rc->tot_length[2];
137 :     int min_size[3];
138 :     double scaler;
139 :     int i;
140 :    
141 :     if (target <= 0 || target >= tot_length) {
142 :     printf("undersize warning\n");
143 :     }
144 : suxen_drol 942
145 : suxen_drol 977 /* perform an initial scale pass.
146 :     if a frame size is scaled underneath our hardcoded minimums, then we force the
147 :     frame size to the minimum, and deduct the original & scaled frmae length from the
148 :     original and target total lengths */
149 : suxen_drol 942
150 : suxen_drol 977 min_size[0] = ((rc->stats[0].blks[0]*22) + 240) / 8;
151 :     min_size[1] = (rc->stats[0].blks[0] + 88) / 8;
152 :     min_size[2] = 8;
153 : suxen_drol 942
154 :    
155 : suxen_drol 977 scaler = (double)target / (double)tot_length;
156 :     //printf("target=%i, tot_length=%i, scaler=%f\n", (int)target, (int)tot_length, scaler);
157 : suxen_drol 942
158 : suxen_drol 977 for (i=0; i<rc->num_frames; i++) {
159 :     stat_t * s = &rc->stats[i];
160 :     int len;
161 :    
162 :     len = (int)((double)s->length * scaler);
163 :     if (len < min_size[s->type]) { /* force frame size */
164 :     s->scaled_length = min_size[s->type];
165 :     target -= s->scaled_length;
166 :     tot_length -= s->length;
167 :     }else{
168 :     s->scaled_length = 0;
169 :     }
170 :     }
171 : suxen_drol 942
172 : suxen_drol 977 if (target <= 0 || target >= tot_length) {
173 :     printf("undersize warning\n");
174 :     return;
175 :     }
176 : suxen_drol 942
177 : suxen_drol 977 scaler = (double)target / (double)tot_length;
178 :     //printf("target=%i, tot_length=%i, scaler=%f\n", (int)target, (int)tot_length, scaler);
179 : suxen_drol 942
180 : suxen_drol 977 for (i=0; i<rc->num_frames; i++) {
181 :     stat_t * s = &rc->stats[i];
182 :    
183 :     if (s->scaled_length==0) { /* ignore frame with forced frame sizes */
184 :     s->scaled_length = (int)((double)s->length * scaler);
185 :     }
186 :     }
187 :    
188 : suxen_drol 942 }
189 :    
190 :    
191 : suxen_drol 977
192 :    
193 :    
194 :     /* static void internal_scale(rc_2pass2_t *rc)
195 : suxen_drol 942 {
196 :     const double avg_pvop = rc->avg_length[XVID_TYPE_PVOP-1];
197 :     const double avg_bvop = rc->avg_length[XVID_TYPE_BVOP-1];
198 :     const uint64_t tot_pvop = rc->tot_length[XVID_TYPE_PVOP-1];
199 :     const uint64_t tot_bvop = rc->tot_length[XVID_TYPE_BVOP-1];
200 :     uint64_t i_total = 0;
201 :     double total1,total2;
202 :     int i;
203 :    
204 :     for (i=0; i<rc->num_frames; i++) {
205 :     stat_t * s = &rc->stats[i];
206 :    
207 :     if (s->type == XVID_TYPE_IVOP) {
208 :     i_total += s->length + s->length * rc->param.keyframe_boost / 100;
209 :     }
210 :     }
211 :    
212 :     // compensate for avi frame overhead
213 :     rc->target_size -= rc->num_frames * 24;
214 :    
215 :     // perform prepass to compensate for over/undersizing
216 :    
217 :     if (rc->param.use_alt_curve) {
218 :    
219 :     rc->alt_curve_low = avg_pvop - avg_pvop * (double)rc->param.alt_curve_low_dist / 100.0;
220 :     rc->alt_curve_low_diff = avg_pvop - rc->alt_curve_low;
221 :     rc->alt_curve_high = avg_pvop + avg_pvop * (double)rc->param.alt_curve_high_dist / 100.0;
222 :     rc->alt_curve_high_diff = rc->alt_curve_high - avg_pvop;
223 :     if (rc->alt_curve_use_auto) {
224 :     if (rc->movie_curve > 1.0) {
225 :     rc->param.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 / rc->movie_curve) * (double)rc->param.alt_curve_auto_str / 100.0);
226 :     if (rc->param.alt_curve_min_rel_qual < 20)
227 :     rc->param.alt_curve_min_rel_qual = 20;
228 :     }else{
229 :     rc->param.alt_curve_min_rel_qual = 100;
230 :     }
231 :     }
232 :     rc->alt_curve_mid_qual = (1.0 + (double)rc->param.alt_curve_min_rel_qual / 100.0) / 2.0;
233 :     rc->alt_curve_qual_dev = 1.0 - rc->alt_curve_mid_qual;
234 :    
235 :     if (rc->param.alt_curve_low_dist > 100) {
236 :     switch(rc->param.alt_curve_type) {
237 :     case XVID_CURVE_SINE : // Sine Curve (high aggressiveness)
238 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)));
239 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff));
240 :     break;
241 :     case XVID_CURVE_LINEAR : // Linear (medium aggressiveness)
242 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + avg_pvop / rc->alt_curve_low_diff);
243 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * avg_pvop / rc->alt_curve_low_diff;
244 :     break;
245 :     case XVID_CURVE_COSINE : // Cosine Curve (low aggressiveness)
246 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff))));
247 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)));
248 :     }
249 :     }
250 :     }
251 :    
252 :     total1 = 0;
253 :     total2 = 0;
254 :    
255 :     for (i=0; i<rc->num_frames; i++) {
256 :     stat_t * s = &rc->stats[i];
257 :    
258 :     if (s->type != XVID_TYPE_IVOP) {
259 :    
260 :     double dbytes = s->length / rc->movie_curve;
261 :     double dbytes2;
262 :     total1 += dbytes;
263 :    
264 :     if (s->type == XVID_TYPE_BVOP)
265 :     dbytes *= avg_pvop / avg_bvop;
266 :    
267 :     if (rc->param.use_alt_curve) {
268 :     if (dbytes > avg_pvop) {
269 :     if (dbytes >= rc->alt_curve_high) {
270 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
271 :     }else{
272 :     switch(rc->param.alt_curve_type){
273 :     case XVID_CURVE_SINE :
274 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - avg_pvop) * 90.0 / rc->alt_curve_high_diff)));
275 :     break;
276 :     case XVID_CURVE_LINEAR :
277 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - avg_pvop) / rc->alt_curve_high_diff);
278 :     break;
279 :     case XVID_CURVE_COSINE :
280 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - avg_pvop) * 90.0 / rc->alt_curve_high_diff))));
281 :     }
282 :     }
283 :     }else{
284 :     if (dbytes <= rc->alt_curve_low){
285 :     dbytes2 = dbytes;
286 :     }else{
287 :     switch(rc->param.alt_curve_type){
288 :     case XVID_CURVE_SINE :
289 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - avg_pvop) * 90.0 / rc->alt_curve_low_diff)));
290 :     break;
291 :     case XVID_CURVE_LINEAR :
292 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - avg_pvop) / rc->alt_curve_low_diff);
293 :     break;
294 :     case XVID_CURVE_COSINE :
295 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - avg_pvop) * 90.0 / rc->alt_curve_low_diff))));
296 :     }
297 :     }
298 :     }
299 :     }else{
300 :     if (dbytes > avg_pvop) {
301 :     dbytes2 = ((double)dbytes + (avg_pvop - dbytes) *
302 :     rc->param.curve_compression_high / 100.0);
303 :     }else{
304 :     dbytes2 = ((double)dbytes + (avg_pvop - dbytes) *
305 :     rc->param.curve_compression_low / 100.0);
306 :     }
307 :     }
308 :    
309 :     if (s->type == XVID_TYPE_BVOP) {
310 :     dbytes2 *= avg_bvop / avg_pvop;
311 :     }
312 :    
313 :     if (dbytes2 < rc->min_length[s->type-1]) {
314 :     dbytes = rc->min_length[s->type-1];
315 :     }
316 :    
317 :     total2 += dbytes2;
318 :     }
319 :     }
320 :    
321 :     rc->curve_comp_scale = total1 / total2;
322 :    
323 :     if (!rc->param.use_alt_curve) {
324 :     printf("middle frame size for asymmetric curve compression: %i",
325 :     (int)(avg_pvop * rc->curve_comp_scale));
326 :     }
327 :     }*/
328 :    
329 :    
330 :    
331 : suxen_drol 977 /* open stats file(s) and read into rc->stats array */
332 : suxen_drol 942
333 : suxen_drol 977 static int load_stats(rc_2pass2_t *rc, char * filename)
334 :     {
335 :     FILE * f;
336 :     int i, not_scaled;
337 :    
338 :    
339 :     if ((f = fopen(filename, "rt"))==NULL)
340 :     return 0;
341 :    
342 :     i = 0;
343 :     not_scaled = 0;
344 :     while(i < rc->num_frames) {
345 :     stat_t * s = &rc->stats[i];
346 :     int n;
347 :     char type;
348 :    
349 :     s->scaled_length = 0;
350 :     n = fscanf(f, "%c %d %d %d %d %d %d\n", &type, &s->quant, &s->blks[0], &s->blks[1], &s->blks[2], &s->length, &s->scaled_length);
351 :     if (n == EOF) break;
352 :     if (n < 7) {
353 :     not_scaled = 1;
354 :     }
355 :    
356 :     if (type == 'i') {
357 :     s->type = XVID_TYPE_IVOP;
358 :     }else if (type == 'p' || type == 's') {
359 :     s->type = XVID_TYPE_PVOP;
360 :     }else if (type == 'b') {
361 :     s->type = XVID_TYPE_BVOP;
362 :     }else{ /* unknown type */
363 :     printf("unk\n");
364 :     continue;
365 :     }
366 :    
367 :     i++;
368 :     }
369 :     rc->num_frames = i;
370 :    
371 :     fclose(f);
372 :    
373 :     return 1;
374 :     }
375 :    
376 :    
377 :    
378 :    
379 :    
380 : suxen_drol 942 static void print_stats(rc_2pass2_t * rc)
381 :     {
382 :     int i;
383 :     for (i = 0; i < rc->num_frames; i++) {
384 :     stat_t * s = &rc->stats[i];
385 :     printf("%i %i %i %i\n", s->type, s->quant, s->length, s->scaled_length);
386 :    
387 :     }
388 :     }
389 :    
390 :    
391 :     /* pre-process the statistics data
392 :     this is a clone of vfw/src/2pass.c:codec_2pass_init minus file reading, alt_curve, internal scale
393 :     */
394 :    
395 : suxen_drol 977 void pre_process0(rc_2pass2_t * rc)
396 : suxen_drol 942 {
397 :     int i,j;
398 :    
399 :     for (i=0; i<3; i++) {
400 :     rc->count[i]=0;
401 :     rc->tot_length[i] = 0;
402 :     rc->last_quant[i] = 0;
403 :     }
404 :    
405 :     for (i=0; i<32;i++) {
406 :     rc->pquant_error[i] = 0;
407 :     rc->bquant_error[i] = 0;
408 :     rc->quant_count[i] = 0;
409 :     }
410 :    
411 :     for (i=j=0; i<rc->num_frames; i++) {
412 :     stat_t * s = &rc->stats[i];
413 :    
414 :     rc->count[s->type-1]++;
415 :     rc->tot_length[s->type-1] += s->length;
416 :    
417 :     if (i == 0 || s->length < rc->min_length[s->type-1]) {
418 :     rc->min_length[s->type-1] = s->length;
419 :     }
420 :    
421 :     if (i == 0 || s->length > rc->max_length) {
422 :     rc->max_length = s->length;
423 :     }
424 :    
425 :     if (s->type == XVID_TYPE_IVOP) {
426 :     rc->keyframe_locations[j] = i;
427 :     j++;
428 :     }
429 :     }
430 :     rc->keyframe_locations[j] = i;
431 : suxen_drol 977 }
432 : suxen_drol 942
433 : suxen_drol 977
434 :    
435 :     void pre_process1(rc_2pass2_t * rc)
436 :     {
437 :     int i;
438 :     double total1, total2;
439 :     uint64_t ivop_boost_total;
440 :    
441 :     ivop_boost_total = 0;
442 :     rc->curve_comp_error = 0;
443 :    
444 :     for (i=0; i<3; i++) {
445 :     rc->tot_scaled_length[i] = 0;
446 :     }
447 :    
448 :     for (i=0; i<rc->num_frames; i++) {
449 :     stat_t * s = &rc->stats[i];
450 :    
451 :     rc->tot_scaled_length[s->type-1] += s->scaled_length;
452 :    
453 :     if (s->type == XVID_TYPE_IVOP) {
454 :     ivop_boost_total += s->scaled_length * rc->param.keyframe_boost / 100;
455 :     }
456 :     }
457 :    
458 : suxen_drol 942 rc->movie_curve = ((double)(rc->tot_scaled_length[XVID_TYPE_PVOP-1] + rc->tot_scaled_length[XVID_TYPE_BVOP-1] + ivop_boost_total) /
459 :     (rc->tot_scaled_length[XVID_TYPE_PVOP-1] + rc->tot_scaled_length[XVID_TYPE_BVOP-1]));
460 :    
461 :     for(i=0; i<3; i++) {
462 :     if (rc->count[i] == 0 || rc->movie_curve == 0) {
463 :     rc->avg_length[i] = 1;
464 :     }else{
465 :     rc->avg_length[i] = rc->tot_scaled_length[i] / rc->count[i] / rc->movie_curve;
466 :     }
467 :     }
468 :    
469 :     /* alt curve stuff here */
470 :    
471 :     if (rc->param.use_alt_curve) {
472 :     const double avg_pvop = rc->avg_length[XVID_TYPE_PVOP-1];
473 :     const uint64_t tot_pvop = rc->tot_length[XVID_TYPE_PVOP-1];
474 :     const uint64_t tot_bvop = rc->tot_length[XVID_TYPE_BVOP-1];
475 :     const uint64_t tot_scaled_pvop = rc->tot_scaled_length[XVID_TYPE_PVOP-1];
476 :     const uint64_t tot_scaled_bvop = rc->tot_scaled_length[XVID_TYPE_BVOP-1];
477 :    
478 :     rc->alt_curve_low = avg_pvop - avg_pvop * (double)rc->param.alt_curve_low_dist / 100.0;
479 :     rc->alt_curve_low_diff = avg_pvop - rc->alt_curve_low;
480 :     rc->alt_curve_high = avg_pvop + avg_pvop * (double)rc->param.alt_curve_high_dist / 100.0;
481 :     rc->alt_curve_high_diff = rc->alt_curve_high - avg_pvop;
482 :    
483 :     if (rc->param.alt_curve_use_auto) {
484 :     if (tot_bvop + tot_pvop > tot_scaled_bvop + tot_scaled_pvop) {
485 :     rc->param.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 /
486 :     ((double)(tot_pvop + tot_bvop) / (double)(tot_scaled_pvop + tot_scaled_bvop))) * (double)rc->param.alt_curve_auto_str / 100.0);
487 :    
488 :     if (rc->param.alt_curve_min_rel_qual < 20)
489 :     rc->param.alt_curve_min_rel_qual = 20;
490 :     }else{
491 :     rc->param.alt_curve_min_rel_qual = 100;
492 :     }
493 :     }
494 :     rc->alt_curve_mid_qual = (1.0 + (double)rc->param.alt_curve_min_rel_qual / 100.0) / 2.0;
495 :     rc->alt_curve_qual_dev = 1.0 - rc->alt_curve_mid_qual;
496 :    
497 :     if (rc->param.alt_curve_low_dist > 100) {
498 :     switch(rc->param.alt_curve_type) {
499 :     case XVID_CURVE_SINE: // Sine Curve (high aggressiveness)
500 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)));
501 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff));
502 :     break;
503 :     case XVID_CURVE_LINEAR: // Linear (medium aggressiveness)
504 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + avg_pvop / rc->alt_curve_low_diff);
505 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * avg_pvop / rc->alt_curve_low_diff;
506 :     break;
507 :     case XVID_CURVE_COSINE: // Cosine Curve (low aggressiveness)
508 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff))));
509 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)));
510 :     }
511 :     }
512 :     }
513 :     /* --- */
514 :    
515 :    
516 :     total1=total2=0;
517 : suxen_drol 977 for (i=0; i<rc->num_frames; i++) {
518 : suxen_drol 942 stat_t * s = &rc->stats[i];
519 :    
520 :     if (s->type != XVID_TYPE_IVOP) {
521 :     double dbytes,dbytes2;
522 :    
523 :     dbytes = s->scaled_length / rc->movie_curve;
524 :     dbytes2 = 0; /* XXX: warning */
525 :     total1 += dbytes;
526 :     if (s->type == XVID_TYPE_BVOP)
527 :     dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];
528 :    
529 :     if (rc->param.use_alt_curve) {
530 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
531 :    
532 :     if (dbytes >= rc->alt_curve_high) {
533 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
534 :     }else{
535 :     switch(rc->param.alt_curve_type) {
536 :     case XVID_CURVE_SINE :
537 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)));
538 :     break;
539 :     case XVID_CURVE_LINEAR :
540 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff);
541 :     break;
542 :     case XVID_CURVE_COSINE :
543 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))));
544 :     }
545 :     }
546 :     }else{
547 :     if (dbytes <= rc->alt_curve_low) {
548 :     dbytes2 = dbytes;
549 :     }else{
550 :     switch(rc->param.alt_curve_type) {
551 :     case XVID_CURVE_SINE :
552 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)));
553 :     break;
554 :     case XVID_CURVE_LINEAR :
555 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff);
556 :     break;
557 :     case XVID_CURVE_COSINE :
558 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))));
559 :     }
560 :     }
561 :    
562 :     }
563 :    
564 :    
565 :     }else{
566 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
567 :     dbytes2=((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0);
568 :     }else{
569 :     dbytes2 = ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);
570 :     }
571 :     }
572 :    
573 :     if (s->type == XVID_TYPE_BVOP) {
574 :     dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
575 :     if (dbytes2 < rc->min_length[XVID_TYPE_BVOP-1])
576 :     dbytes2 = rc->min_length[XVID_TYPE_BVOP-1];
577 :     }else{
578 :     if (dbytes2 < rc->min_length[XVID_TYPE_PVOP-1])
579 :     dbytes2 = rc->min_length[XVID_TYPE_PVOP-1];
580 :     }
581 :     total2 += dbytes2;
582 :     }
583 :     }
584 :    
585 :     rc->curve_comp_scale = total1 / total2;
586 :    
587 :     if (!rc->param.use_alt_curve) {
588 :     printf("middle frame size for asymmetric curve compression: %i\n",
589 :     (int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale));
590 :     }
591 :    
592 :     if (rc->param.use_alt_curve) {
593 :     int bonus_bias = rc->param.alt_curve_bonus_bias;
594 :     int oldquant = 1;
595 :    
596 :     if (rc->param.alt_curve_use_auto_bonus_bias)
597 :     bonus_bias = rc->param.alt_curve_min_rel_qual;
598 :    
599 :     rc->alt_curve_curve_bias_bonus = (total1 - total2) * (double)bonus_bias / 100.0 / (double)(rc->num_frames /* - credits_frames */ - rc->num_keyframes);
600 :     rc->curve_comp_scale = ((total1 - total2) * (1.0 - (double)bonus_bias / 100.0) + total2) / total2;
601 :    
602 :    
603 :     /* special info for alt curve: bias bonus and quantizer thresholds */
604 :    
605 :     printf("avg scaled framesize:%i", (int)rc->avg_length[XVID_TYPE_PVOP-1]);
606 :     printf("bias bonus:%i bytes", (int)rc->alt_curve_curve_bias_bonus);
607 :    
608 :     for (i=1; i <= (int)(rc->alt_curve_high*2)+1; i++) {
609 :     double curve_temp, dbytes;
610 :     int newquant;
611 :    
612 :     dbytes = i;
613 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
614 :     if (dbytes >= rc->alt_curve_high) {
615 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
616 :     }else{
617 :     switch(rc->param.alt_curve_type)
618 :     {
619 :     case XVID_CURVE_SINE :
620 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)));
621 :     break;
622 :     case XVID_CURVE_LINEAR :
623 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff);
624 :     break;
625 :     case XVID_CURVE_COSINE :
626 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))));
627 :     }
628 :     }
629 :     }else{
630 :     if (dbytes <= rc->alt_curve_low) {
631 :     curve_temp = dbytes;
632 :     }else{
633 :     switch(rc->param.alt_curve_type)
634 :     {
635 :     case XVID_CURVE_SINE :
636 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)));
637 :     break;
638 :     case XVID_CURVE_LINEAR :
639 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff);
640 :     break;
641 :     case XVID_CURVE_COSINE :
642 :     curve_temp = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))));
643 :     }
644 :     }
645 :     }
646 :    
647 :     if (rc->movie_curve > 1.0)
648 :     dbytes *= rc->movie_curve;
649 :    
650 :     newquant = (int)(dbytes * 2.0 / (curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus));
651 :     if (newquant > 1) {
652 :     if (newquant != oldquant) {
653 :     int percent = (int)((i - rc->avg_length[XVID_TYPE_PVOP-1]) * 100.0 / rc->avg_length[XVID_TYPE_PVOP-1]);
654 :     oldquant = newquant;
655 :     printf("quant:%i threshold at %i : %i percent", newquant, i, percent);
656 :     }
657 :     }
658 :     }
659 :    
660 :     }
661 :    
662 :     rc->overflow = 0;
663 :     rc->KFoverflow = 0;
664 :     rc->KFoverflow_partial = 0;
665 :     rc->KF_idx = 1;
666 :     }
667 :    
668 :    
669 :    
670 :    
671 :     static int rc_2pass2_create(xvid_plg_create_t * create, rc_2pass2_t ** handle)
672 :     {
673 :     xvid_plugin_2pass2_t * param = (xvid_plugin_2pass2_t *)create->param;
674 :     rc_2pass2_t * rc;
675 :    
676 :     rc = malloc(sizeof(rc_2pass2_t));
677 :     if (rc == NULL)
678 :     return XVID_ERR_MEMORY;
679 :    
680 :     rc->param = *param;
681 :    
682 :     if (rc->param.keyframe_boost <= 0) rc->param.keyframe_boost = 0;
683 :     if (rc->param.payback_method <= 0) rc->param.payback_method = XVID_PAYBACK_PROP;
684 :     if (rc->param.bitrate_payback_delay <= 0) rc->param.bitrate_payback_delay = 250;
685 :     if (rc->param.curve_compression_high <= 0) rc->param.curve_compression_high = 0;
686 :     if (rc->param.curve_compression_low <= 0) rc->param.curve_compression_low = 0;
687 :     if (rc->param.max_overflow_improvement <= 0) rc->param.max_overflow_improvement = 60;
688 :     if (rc->param.max_overflow_degradation <= 0) rc->param.max_overflow_degradation = 60;
689 :     if (rc->param.min_quant[0] <= 0) rc->param.min_quant[0] = 2;
690 :     if (rc->param.max_quant[0] <= 0) rc->param.max_quant[0] = 31;
691 :     if (rc->param.min_quant[1] <= 0) rc->param.min_quant[1] = 2;
692 :     if (rc->param.max_quant[1] <= 0) rc->param.max_quant[1] = 31;
693 :     if (rc->param.min_quant[2] <= 0) rc->param.min_quant[2] = 2;
694 :     if (rc->param.max_quant[2] <= 0) rc->param.max_quant[2] = 31;
695 :    
696 :     if (rc->param.use_alt_curve <= 0) rc->param.use_alt_curve = 0;
697 :     if (rc->param.alt_curve_high_dist <= 0) rc->param.alt_curve_high_dist = 500;
698 :     if (rc->param.alt_curve_low_dist <= 0) rc->param.alt_curve_low_dist = 90;
699 :     if (rc->param.alt_curve_use_auto <= 0) rc->param.alt_curve_use_auto = 1;
700 :     if (rc->param.alt_curve_auto_str <= 0) rc->param.alt_curve_auto_str = 30;
701 :     if (rc->param.alt_curve_type <= 0) rc->param.alt_curve_type = XVID_CURVE_LINEAR;
702 :     if (rc->param.alt_curve_min_rel_qual <= 0) rc->param.alt_curve_min_rel_qual = 50;
703 :     if (rc->param.alt_curve_use_auto_bonus_bias <= 0) rc->param.alt_curve_use_auto_bonus_bias = 1;
704 :     if (rc->param.alt_curve_bonus_bias <= 0) rc->param.alt_curve_bonus_bias = 50;
705 :    
706 :     if (rc->param.kftreshold <= 0) rc->param.kftreshold = 10;
707 :     if (rc->param.kfreduction <= 0) rc->param.kfreduction = 20;
708 :     if (rc->param.min_key_interval <= 0) rc->param.min_key_interval = 300;
709 :    
710 : suxen_drol 977 if (!det_stats_length(rc, param->filename)){
711 :     DPRINTF(DPRINTF_RC,"fopen %s failed\n", param->filename);
712 : suxen_drol 942 free(rc);
713 :     return XVID_ERR_FAIL;
714 :     }
715 :    
716 :     if ((rc->stats = malloc(rc->num_frames * sizeof(stat_t))) == NULL) {
717 :     free(rc);
718 :     return XVID_ERR_MEMORY;
719 :     }
720 :    
721 :     /* XXX: do we need an addition location */
722 :     if ((rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int))) == NULL) {
723 :     free(rc->stats);
724 :     free(rc);
725 :     return XVID_ERR_MEMORY;
726 :     }
727 :    
728 : suxen_drol 977 if (!load_stats(rc, param->filename)) {
729 :     DPRINTF(DPRINTF_RC,"fopen %s failed\n", param->filename);
730 : suxen_drol 942 free(rc->keyframe_locations);
731 :     free(rc->stats);
732 :     free(rc);
733 :     return XVID_ERR_FAIL;
734 :     }
735 :    
736 :     /* pre-process our stats */
737 : suxen_drol 977
738 :     {
739 :     if (rc->num_frames < create->fbase/create->fincr) {
740 :     rc->target = rc->param.bitrate / 8; /* one second */
741 :     }else{
742 :     rc->target = (rc->param.bitrate * rc->num_frames * create->fincr) / (create->fbase * 8);
743 :     }
744 :    
745 :    
746 :     rc->target -= rc->num_frames*24; /* avi file header */
747 :    
748 :     }
749 : suxen_drol 942
750 : suxen_drol 977
751 :     pre_process0(rc);
752 :     if (rc->param.bitrate) {
753 :     internal_scale(rc);
754 :     }
755 :     pre_process1(rc);pre_process1(rc);pre_process1(rc);
756 :    
757 : suxen_drol 942 *handle = rc;
758 :     return(0);
759 :     }
760 :    
761 :    
762 :     static int rc_2pass2_destroy(rc_2pass2_t * rc, xvid_plg_destroy_t * destroy)
763 :     {
764 :     free(rc->keyframe_locations);
765 :     free(rc->stats);
766 :     free(rc);
767 :     return(0);
768 :     }
769 :    
770 :    
771 :    
772 :     static int rc_2pass2_before(rc_2pass2_t * rc, xvid_plg_data_t * data)
773 :     {
774 :     stat_t * s = &rc->stats[data->frame_num];
775 :     int overflow;
776 :     int desired;
777 :     double dbytes;
778 :     double curve_temp;
779 :     int capped_to_max_framesize = 0;
780 :    
781 :     if (data->frame_num >= rc->num_frames) {
782 :     /* insufficent stats data */
783 :     return 0;
784 :     }
785 :    
786 :     overflow = rc->overflow / 8; /* XXX: why by 8 */
787 :    
788 :     if (s->type == XVID_TYPE_IVOP) { /* XXX: why */
789 :     overflow = 0;
790 :     }
791 :    
792 :     desired = s->scaled_length;
793 :    
794 :     dbytes = desired;
795 :     if (s->type == XVID_TYPE_IVOP) {
796 :     dbytes += desired * rc->param.keyframe_boost / 100;
797 :     }
798 :     dbytes /= rc->movie_curve;
799 : suxen_drol 977
800 : suxen_drol 942 if (s->type == XVID_TYPE_BVOP) {
801 :     dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];
802 :     }
803 :    
804 :     if (rc->param.payback_method == XVID_PAYBACK_BIAS) {
805 :     desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay);
806 :     }else{
807 : suxen_drol 977 //printf("desired=%i, dbytes=%i\n", desired,dbytes);
808 : suxen_drol 942 desired = (int)(rc->curve_comp_error * dbytes /
809 :     rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay);
810 : suxen_drol 977 //printf("desired=%i\n", desired);
811 : suxen_drol 942
812 :     if (labs(desired) > fabs(rc->curve_comp_error)) {
813 :     desired = (int)rc->curve_comp_error;
814 :     }
815 :     }
816 :    
817 :     rc->curve_comp_error -= desired;
818 :    
819 :     /* alt curve */
820 :    
821 :     curve_temp = 0; /* XXX: warning */
822 :    
823 :     if (rc->param.use_alt_curve) {
824 :     if (s->type != XVID_TYPE_IVOP) {
825 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
826 :     if (dbytes >= rc->alt_curve_high) {
827 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
828 :     }else{
829 :     switch(rc->param.alt_curve_type) {
830 :     case XVID_CURVE_SINE :
831 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff)));
832 :     break;
833 :     case XVID_CURVE_LINEAR :
834 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_high_diff);
835 :     break;
836 :     case XVID_CURVE_COSINE :
837 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_high_diff))));
838 :     }
839 :     }
840 :     }else{
841 :     if (dbytes <= rc->alt_curve_low){
842 :     curve_temp = dbytes;
843 :     }else{
844 :     switch(rc->param.alt_curve_type) {
845 :     case XVID_CURVE_SINE :
846 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff)));
847 :     break;
848 :     case XVID_CURVE_LINEAR :
849 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev * (dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) / rc->alt_curve_low_diff);
850 :     break;
851 :     case XVID_CURVE_COSINE :
852 :     curve_temp = dbytes * (rc->alt_curve_mid_qual + rc->alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - rc->avg_length[XVID_TYPE_PVOP-1]) * 90.0 / rc->alt_curve_low_diff))));
853 :     }
854 :     }
855 :     }
856 :     if (s->type == XVID_TYPE_BVOP)
857 :     curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
858 :    
859 :     curve_temp = curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus;
860 :    
861 :     desired += ((int)curve_temp);
862 :     rc->curve_comp_error += curve_temp - (int)curve_temp;
863 :     }else{
864 :     if (s->type == XVID_TYPE_BVOP)
865 :     dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
866 :    
867 :     desired += ((int)dbytes);
868 :     rc->curve_comp_error += dbytes - (int)dbytes;
869 :     }
870 :    
871 :     }else if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) {
872 :    
873 :     curve_temp = rc->curve_comp_scale;
874 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
875 :     curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0);
876 :     } else {
877 :     curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);
878 :     }
879 :    
880 :     if (s->type == XVID_TYPE_BVOP){
881 :     curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
882 :     }
883 :    
884 :     desired += (int)curve_temp;
885 :     rc->curve_comp_error += curve_temp - (int)curve_temp;
886 :     }else{
887 :     if (s->type == XVID_TYPE_BVOP){
888 :     dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
889 :     }
890 :    
891 :     desired += (int)dbytes;
892 :     rc->curve_comp_error += dbytes - (int)dbytes;
893 :     }
894 :    
895 :     if (desired > s->length){
896 :     rc->curve_comp_error += desired - s->length;
897 :     desired = s->length;
898 :     }else{
899 :     if (desired < rc->min_length[s->type-1]) {
900 :     if (s->type == XVID_TYPE_IVOP){
901 :     rc->curve_comp_error -= rc->min_length[XVID_TYPE_IVOP-1] - desired;
902 :     }
903 :     desired = rc->min_length[s->type-1];
904 :     }
905 :     }
906 :    
907 :     s->desired_length = desired;
908 :    
909 :    
910 :     /* if this keyframe is too close to the next, reduce it's byte allotment
911 :     XXX: why do we do this after setting the desired length */
912 :    
913 :     if (s->type == XVID_TYPE_IVOP) {
914 :     int KFdistance = rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1];
915 :    
916 :     if (KFdistance < rc->param.kftreshold) {
917 :    
918 :     KFdistance = KFdistance - rc->param.min_key_interval;
919 :    
920 :     if (KFdistance >= 0) {
921 :     int KF_min_size;
922 :    
923 :     KF_min_size = desired * (100 - rc->param.kfreduction) / 100;
924 :     if (KF_min_size < 1)
925 :     KF_min_size = 1;
926 :    
927 :     desired = KF_min_size + (desired - KF_min_size) * KFdistance /
928 :     (rc->param.kftreshold - rc->param.min_key_interval);
929 :    
930 :     if (desired < 1)
931 :     desired = 1;
932 :     }
933 :     }
934 :     }
935 :    
936 :     overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]);
937 :    
938 :     // Foxer: reign in overflow with huge frames
939 :     if (labs(overflow) > labs(rc->overflow)) {
940 :     overflow = rc->overflow;
941 :     }
942 :    
943 :     // Foxer: make sure overflow doesn't run away
944 :    
945 :     if (overflow > desired * rc->param.max_overflow_improvement / 100) {
946 :     desired += (overflow <= desired) ? desired * rc->param.max_overflow_improvement / 100 :
947 :     overflow * rc->param.max_overflow_improvement / 100;
948 :     }else if (overflow < desired * rc->param.max_overflow_degradation / -100){
949 :     desired += desired * rc->param.max_overflow_degradation / -100;
950 :     }else{
951 :     desired += overflow;
952 :     }
953 :    
954 :     if (desired > rc->max_length) {
955 :     capped_to_max_framesize = 1;
956 :     desired = rc->max_length;
957 :     }
958 :    
959 :     // make sure to not scale below the minimum framesize
960 :     if (desired < rc->min_length[s->type-1]) {
961 :     desired = rc->min_length[s->type-1];
962 :     }
963 :    
964 :    
965 :     // very 'simple' quant<->filesize relationship
966 :     data->quant= (s->quant * s->length) / desired;
967 :    
968 :     if (data->quant < 1) {
969 :     data->quant = 1;
970 :     } else if (data->quant > 31) {
971 :     data->quant = 31;
972 :     }
973 :     else if (s->type != XVID_TYPE_IVOP)
974 :     {
975 :     // Foxer: aid desired quantizer precision by accumulating decision error
976 :     if (s->type== XVID_TYPE_BVOP) {
977 :     rc->bquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;
978 :    
979 :     if (rc->bquant_error[data->quant] >= 1.0) {
980 :     rc->bquant_error[data->quant] -= 1.0;
981 :     data->quant++;
982 :     }
983 :     }else{
984 :     rc->pquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;
985 :    
986 :     if (rc->pquant_error[data->quant] >= 1.0) {
987 :     rc->pquant_error[data->quant] -= 1.0;
988 :     ++data->quant;
989 :     }
990 :     }
991 :     }
992 :    
993 :     /* cap to min/max quant */
994 :    
995 :     if (data->quant < rc->param.min_quant[s->type-1]) {
996 :     data->quant = rc->param.min_quant[s->type-1];
997 :     }else if (data->quant > rc->param.max_quant[s->type-1]) {
998 :     data->quant = rc->param.max_quant[s->type-1];
999 :     }
1000 :    
1001 :     /* subsequent p/b frame quants can only be +- 2 */
1002 :     if (s->type != XVID_TYPE_IVOP && rc->last_quant[s->type-1] && capped_to_max_framesize == 0) {
1003 :    
1004 :     if (data->quant > rc->last_quant[s->type-1] + 2) {
1005 :     data->quant = rc->last_quant[s->type-1] + 2;
1006 :     DPRINTF(DPRINTF_RC, "p/b-frame quantizer prevented from rising too steeply");
1007 :     }
1008 :     if (data->quant < rc->last_quant[s->type-1] - 2) {
1009 :     data->quant = rc->last_quant[s->type-1] - 2;
1010 :     DPRINTF(DPRINTF_RC, "p/b-frame quantizer prevented from falling too steeply");
1011 :     }
1012 :     }
1013 :    
1014 :     if (capped_to_max_framesize == 0) {
1015 :     rc->last_quant[s->type-1] = data->quant;
1016 :     }
1017 :    
1018 :     return 0;
1019 :     }
1020 :    
1021 :    
1022 :    
1023 :     static int rc_2pass2_after(rc_2pass2_t * rc, xvid_plg_data_t * data)
1024 :     {
1025 :     stat_t * s = &rc->stats[data->frame_num];
1026 :    
1027 :     if (data->frame_num >= rc->num_frames) {
1028 :     /* insufficent stats data */
1029 :     return 0;
1030 :     }
1031 :    
1032 :     rc->quant_count[data->quant]++;
1033 :    
1034 :     if (data->type == XVID_TYPE_IVOP) {
1035 :     int kfdiff = (rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1]);
1036 :    
1037 :     rc->overflow += rc->KFoverflow;
1038 :     rc->KFoverflow = s->desired_length - data->length;
1039 :    
1040 :     if (kfdiff > 1) { // non-consecutive keyframes
1041 :     rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1);
1042 :     }else{ // consecutive keyframes
1043 :     rc->overflow += rc->KFoverflow;
1044 :     rc->KFoverflow = 0;
1045 :     rc->KFoverflow_partial = 0;
1046 :     }
1047 :     rc->KF_idx++;
1048 :     }else{
1049 :     // distribute part of the keyframe overflow
1050 :     rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial;
1051 :     rc->KFoverflow -= rc->KFoverflow_partial;
1052 :     }
1053 :    
1054 :     printf("[%i] quant:%i stats1:%i scaled:%i actual:%i overflow:%i\n",
1055 :     data->frame_num,
1056 :     data->quant,
1057 :     s->length,
1058 :     s->scaled_length,
1059 :     data->length,
1060 :     rc->overflow);
1061 :    
1062 :     return(0);
1063 :     }
1064 :    
1065 :    
1066 :    
1067 :     int xvid_plugin_2pass2(void * handle, int opt, void * param1, void * param2)
1068 :     {
1069 :     switch(opt)
1070 :     {
1071 :     case XVID_PLG_INFO :
1072 :     return 0;
1073 :    
1074 :     case XVID_PLG_CREATE :
1075 :     return rc_2pass2_create((xvid_plg_create_t*)param1, param2);
1076 :    
1077 :     case XVID_PLG_DESTROY :
1078 :     return rc_2pass2_destroy((rc_2pass2_t*)handle, (xvid_plg_destroy_t*)param1);
1079 :    
1080 :     case XVID_PLG_BEFORE :
1081 :     return rc_2pass2_before((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);
1082 :    
1083 :     case XVID_PLG_AFTER :
1084 :     return rc_2pass2_after((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);
1085 :     }
1086 :    
1087 :     return XVID_ERR_FAIL;
1088 :     }

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