[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 1041 - (view) (download)

1 : suxen_drol 942 /******************************************************************************
2 :     *
3 :     * XviD Bit Rate Controller Library
4 :     * - VBR 2 pass bitrate controler implementation -
5 :     *
6 : edgomez 1037 * Copyright (C) 2002 Foxer <email?>
7 :     * 2002 Dirk Knop <dknop@gwdg.de>
8 :     * 2002-2003 Edouard Gomez <ed.gomez@free.fr>
9 :     * 2003 Pete Ross <pross@xvid.org>
10 : suxen_drol 942 *
11 : edgomez 1037 * This curve treatment algorithm is the one originally implemented by Foxer
12 :     * and tuned by Dirk Knop for the XviD vfw frontend.
13 : suxen_drol 942 *
14 :     * This program is free software; you can redistribute it and/or modify
15 :     * it under the terms of the GNU General Public License as published by
16 :     * the Free Software Foundation; either version 2 of the License, or
17 :     * (at your option) any later version.
18 :     *
19 :     * This program is distributed in the hope that it will be useful,
20 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 :     * GNU General Public License for more details.
23 :     *
24 :     * You should have received a copy of the GNU General Public License
25 :     * along with this program; if not, write to the Free Software
26 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 :     *
28 : edgomez 1041 * $Id: plugin_2pass2.c,v 1.1.2.10 2003-05-22 22:56:22 edgomez Exp $
29 : suxen_drol 942 *
30 :     *****************************************************************************/
31 :    
32 :     #include <stdio.h>
33 :     #include <math.h>
34 : edgomez 1040 #include <limits.h>
35 : suxen_drol 942
36 :     #define RAD2DEG 57.295779513082320876798154814105
37 :     #define DEG2RAD 0.017453292519943295769236907684886
38 :    
39 :     #include "../xvid.h"
40 :     #include "../image/image.h"
41 :    
42 :     typedef struct {
43 :     int type; /* first pass type */
44 :     int quant; /* first pass quant */
45 : suxen_drol 977 int blks[3]; /* k,m,y blks */
46 : suxen_drol 942 int length; /* first pass length */
47 : suxen_drol 1030 int scaled_length; /* scaled length */
48 :     int desired_length; /* desired length; calcuated during encoding */
49 :    
50 :     int zone_mode; /* XVID_ZONE_xxx */
51 :     double weight;
52 : suxen_drol 942 } stat_t;
53 :    
54 :    
55 :    
56 :    
57 :     /* context struct */
58 :     typedef struct
59 :     {
60 :     xvid_plugin_2pass2_t param;
61 :    
62 :     /* constant statistical data */
63 : suxen_drol 977 int num_frames;
64 : suxen_drol 942 int num_keyframes;
65 : suxen_drol 1030 uint64_t target; /* target filesize */
66 : suxen_drol 977
67 : suxen_drol 942 int count[3]; /* count of each frame types */
68 :     uint64_t tot_length[3]; /* total length of each frame types */
69 :     double avg_length[3]; /* avg */
70 :     int min_length[3]; /* min frame length of each frame types */
71 :     uint64_t tot_scaled_length[3]; /* total scaled length of each frame type */
72 :     int max_length; /* max frame size */
73 : suxen_drol 1030
74 :     /* zone statistical data */
75 :     double avg_weight; /* average weight */
76 :     int64_t tot_quant; /* total length used by XVID_ZONE_QUANT zones */
77 :    
78 :    
79 : suxen_drol 942 double curve_comp_scale;
80 :     double movie_curve;
81 :    
82 :     double alt_curve_low;
83 :     double alt_curve_high;
84 :     double alt_curve_low_diff;
85 :     double alt_curve_high_diff;
86 :     double alt_curve_curve_bias_bonus;
87 :     double alt_curve_mid_qual;
88 :     double alt_curve_qual_dev;
89 :    
90 :     /* dynamic */
91 :    
92 :     int * keyframe_locations;
93 :     stat_t * stats;
94 :    
95 :     double pquant_error[32];
96 :     double bquant_error[32];
97 :     int quant_count[32];
98 :     int last_quant[3];
99 :    
100 :     double curve_comp_error;
101 :     int overflow;
102 :     int KFoverflow;
103 :     int KFoverflow_partial;
104 :     int KF_idx;
105 : suxen_drol 1030
106 :     double fq_error;
107 : suxen_drol 942 } rc_2pass2_t;
108 :    
109 :    
110 :    
111 :     #define BUF_SZ 1024
112 :     #define MAX_COLS 5
113 :    
114 :    
115 :     /* open stats file, and count num frames */
116 :    
117 :     static int det_stats_length(rc_2pass2_t * rc, char * filename)
118 :     {
119 :     FILE * f;
120 :     int n, ignore;
121 :     char type;
122 :    
123 :     rc->num_frames = 0;
124 :     rc->num_keyframes = 0;
125 :    
126 :     if ((f = fopen(filename, "rt")) == NULL)
127 :     return 0;
128 :    
129 : suxen_drol 977 while((n = fscanf(f, "%c %d %d %d %d %d %d\n",
130 :     &type, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore)) != EOF) {
131 : suxen_drol 942 if (type == 'i') {
132 :     rc->num_frames++;
133 :     rc->num_keyframes++;
134 :     }else if (type == 'p' || type == 'b' || type == 's') {
135 :     rc->num_frames++;
136 :     }
137 :     }
138 :    
139 :     fclose(f);
140 :    
141 :     return 1;
142 :     }
143 :    
144 :    
145 :    
146 : suxen_drol 977 /* open stats file(s) and read into rc->stats array */
147 : suxen_drol 942
148 : suxen_drol 977 static int load_stats(rc_2pass2_t *rc, char * filename)
149 :     {
150 :     FILE * f;
151 :     int i, not_scaled;
152 :    
153 :    
154 :     if ((f = fopen(filename, "rt"))==NULL)
155 :     return 0;
156 :    
157 :     i = 0;
158 :     not_scaled = 0;
159 :     while(i < rc->num_frames) {
160 :     stat_t * s = &rc->stats[i];
161 :     int n;
162 :     char type;
163 :    
164 :     s->scaled_length = 0;
165 :     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);
166 :     if (n == EOF) break;
167 :     if (n < 7) {
168 :     not_scaled = 1;
169 :     }
170 :    
171 :     if (type == 'i') {
172 :     s->type = XVID_TYPE_IVOP;
173 :     }else if (type == 'p' || type == 's') {
174 :     s->type = XVID_TYPE_PVOP;
175 :     }else if (type == 'b') {
176 :     s->type = XVID_TYPE_BVOP;
177 :     }else{ /* unknown type */
178 : edgomez 1038 DPRINTF(XVID_DEBUG_RC, "unknown stats frame type; assuming pvop\n");
179 : suxen_drol 1032 s->type = XVID_TYPE_PVOP;
180 : suxen_drol 977 }
181 :    
182 :     i++;
183 :     }
184 : edgomez 1037
185 : suxen_drol 977 rc->num_frames = i;
186 :    
187 : edgomez 1037 fclose(f);
188 :    
189 : suxen_drol 977 return 1;
190 :     }
191 :    
192 :    
193 :    
194 : edgomez 1036 #if 0
195 : suxen_drol 942 static void print_stats(rc_2pass2_t * rc)
196 :     {
197 :     int i;
198 : edgomez 1040 DPRINTF(XVID_DEBUG_RC, "type quant length scaled_length\n");
199 :     for (i = 0; i < rc->num_frames; i++) {
200 : suxen_drol 942 stat_t * s = &rc->stats[i];
201 : edgomez 1040 DPRINTF(XVID_DEBUG_RC, "%d %d %d %d\n", s->type, s->quant, s->length, s->scaled_length);
202 : suxen_drol 942 }
203 :     }
204 : edgomez 1036 #endif
205 : suxen_drol 942
206 :     /* pre-process the statistics data
207 : suxen_drol 1030 - for each type, count, tot_length, min_length, max_length
208 :     - set keyframes_locations
209 : suxen_drol 942 */
210 :    
211 : edgomez 1040 static void
212 :     pre_process0(rc_2pass2_t * rc)
213 : suxen_drol 942 {
214 :     int i,j;
215 :    
216 :     for (i=0; i<3; i++) {
217 :     rc->count[i]=0;
218 :     rc->tot_length[i] = 0;
219 :     rc->last_quant[i] = 0;
220 : edgomez 1040 rc->min_length[i] = INT_MAX;
221 : suxen_drol 942 }
222 :    
223 : edgomez 1040 rc->max_length = INT_MIN;
224 :    
225 : suxen_drol 942 for (i=j=0; i<rc->num_frames; i++) {
226 :     stat_t * s = &rc->stats[i];
227 :    
228 :     rc->count[s->type-1]++;
229 :     rc->tot_length[s->type-1] += s->length;
230 :    
231 : edgomez 1040 if (s->length < rc->min_length[s->type-1]) {
232 : suxen_drol 942 rc->min_length[s->type-1] = s->length;
233 :     }
234 :    
235 : edgomez 1040 if (s->length > rc->max_length) {
236 : suxen_drol 942 rc->max_length = s->length;
237 :     }
238 :    
239 :     if (s->type == XVID_TYPE_IVOP) {
240 :     rc->keyframe_locations[j] = i;
241 :     j++;
242 :     }
243 :     }
244 : edgomez 1037
245 :     /*
246 :     * The "per sequence" overflow system considers a natural sequence to be
247 :     * formed by all frames between two iframes, so if we want to make sure
248 :     * the system does not go nuts during last sequence, we force the last
249 :     * frame to appear in the keyframe locations array.
250 :     */
251 : suxen_drol 942 rc->keyframe_locations[j] = i;
252 : edgomez 1040
253 :     DPRINTF(XVID_DEBUG_RC, "Min 1st pass IFrame length: %d\n", rc->min_length[0]);
254 :     DPRINTF(XVID_DEBUG_RC, "Min 1st pass PFrame length: %d\n", rc->min_length[1]);
255 :     DPRINTF(XVID_DEBUG_RC, "Min 1st pass BFrame length: %d\n", rc->min_length[2]);
256 : suxen_drol 977 }
257 : suxen_drol 942
258 : suxen_drol 1030
259 :     /* calculate zone weight "center" */
260 : suxen_drol 977
261 : edgomez 1040 static void
262 :     zone_process(rc_2pass2_t *rc, const xvid_plg_create_t * create)
263 : suxen_drol 1030 {
264 :     int i,j;
265 :     int n = 0;
266 : suxen_drol 977
267 : suxen_drol 1030 rc->avg_weight = 0.0;
268 :     rc->tot_quant = 0;
269 :    
270 :    
271 :     if (create->num_zones == 0) {
272 :     for (j = 0; j < rc->num_frames; j++) {
273 :     rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;
274 :     rc->stats[j].weight = 1.0;
275 :     }
276 :     rc->avg_weight += rc->num_frames * 1.0;
277 :     n += rc->num_frames;
278 :     }
279 :    
280 :    
281 :     for(i=0; i < create->num_zones; i++) {
282 :    
283 :     int next = (i+1<create->num_zones) ? create->zones[i+1].frame : rc->num_frames;
284 :    
285 :     if (i==0 && create->zones[i].frame > 0) {
286 :     for (j = 0; j < create->zones[i].frame && j < rc->num_frames; j++) {
287 :     rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;
288 :     rc->stats[j].weight = 1.0;
289 :     }
290 :     rc->avg_weight += create->zones[i].frame * 1.0;
291 :     n += create->zones[i].frame;
292 :     }
293 :    
294 :     if (create->zones[i].mode == XVID_ZONE_WEIGHT) {
295 :     for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {
296 :     rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;
297 :     rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;
298 :     }
299 :     next -= create->zones[i].frame;
300 :     rc->avg_weight += (double)(next * create->zones[i].increment) / (double)create->zones[i].base;
301 :     n += next;
302 :     }else{ // XVID_ZONE_QUANT
303 :     for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {
304 :     rc->stats[j].zone_mode = XVID_ZONE_QUANT;
305 :     rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;
306 :     rc->tot_quant += rc->stats[j].length;
307 :     }
308 :     }
309 :     }
310 :     rc->avg_weight = n>0 ? rc->avg_weight/n : 1.0;
311 :    
312 : suxen_drol 1032 DPRINTF(XVID_DEBUG_RC, "center_weight: %f (for %i frames); fixed_bytes: %i\n", rc->avg_weight, n, rc->tot_quant);
313 : suxen_drol 1030 }
314 :    
315 :    
316 :     /* scale the curve */
317 :    
318 : edgomez 1040 static void
319 :     internal_scale(rc_2pass2_t *rc)
320 : suxen_drol 1030 {
321 :     int64_t target = rc->target - rc->tot_quant;
322 :     int64_t pass1_length = rc->tot_length[0] + rc->tot_length[1] + rc->tot_length[2] - rc->tot_quant;
323 :     int min_size[3];
324 :     double scaler;
325 :     int i;
326 :    
327 :    
328 : edgomez 1040 /*
329 :     * Perform an initial scale pass.
330 :     * if a frame size is scaled underneath our hardcoded minimums, then we
331 :     * force the frame size to the minimum, and deduct the original & scaled
332 :     * frame length from the original and target total lengths
333 :     */
334 : suxen_drol 1030
335 :     min_size[0] = ((rc->stats[0].blks[0]*22) + 240) / 8;
336 :     min_size[1] = (rc->stats[0].blks[0] + 88) / 8;
337 :     min_size[2] = 8;
338 :    
339 :     scaler = (double)target / (double)pass1_length;
340 :    
341 : suxen_drol 1032 if (target <= 0 || pass1_length <= 0 || target >= pass1_length) {
342 :     DPRINTF(XVID_DEBUG_RC, "undersize warning\n");
343 :     scaler = 1.0;
344 :     }
345 :    
346 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,
347 :     "Before any correction: target=%i, tot_length=%i, scaler=%f\n",
348 :     (int)target, (int)pass1_length, scaler);
349 : suxen_drol 1032
350 : suxen_drol 1030 for (i=0; i<rc->num_frames; i++) {
351 :     stat_t * s = &rc->stats[i];
352 :     int len;
353 :    
354 :     if (s->zone_mode == XVID_ZONE_QUANT) {
355 :     s->scaled_length = s->length;
356 :     }else {
357 :     len = (int)((double)s->length * scaler * s->weight / rc->avg_weight);
358 : edgomez 1036 if (len < min_size[s->type-1]) { /* force frame size */
359 :     s->scaled_length = min_size[s->type-1];
360 : suxen_drol 1030 target -= s->scaled_length;
361 :     pass1_length -= s->length;
362 :     }else{
363 :     s->scaled_length = 0;
364 :     }
365 :     }
366 :     }
367 :    
368 : suxen_drol 1032 scaler = (double)target / (double)pass1_length;
369 :     if (target <= 0 || pass1_length <= 0 || target >= pass1_length) {
370 :     DPRINTF(XVID_DEBUG_RC,"undersize warning\n");
371 :     scaler = 1.0;
372 : suxen_drol 1030 }
373 :    
374 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,
375 :     "After correction: target=%i, tot_length=%i, scaler=%f\n",
376 :     (int)target, (int)pass1_length, scaler);
377 : suxen_drol 1030
378 :     for (i=0; i<rc->num_frames; i++) {
379 :     stat_t * s = &rc->stats[i];
380 :    
381 :     if (s->scaled_length==0) { /* ignore frame with forced frame sizes */
382 :     s->scaled_length = (int)((double)s->length * scaler * s->weight / rc->avg_weight);
383 :     }
384 :     }
385 :     }
386 :    
387 :    
388 :    
389 :    
390 : edgomez 1040 static void
391 :     pre_process1(rc_2pass2_t * rc)
392 : suxen_drol 977 {
393 :     int i;
394 :     double total1, total2;
395 :     uint64_t ivop_boost_total;
396 :    
397 :     ivop_boost_total = 0;
398 :     rc->curve_comp_error = 0;
399 :    
400 :     for (i=0; i<3; i++) {
401 :     rc->tot_scaled_length[i] = 0;
402 :     }
403 :    
404 :     for (i=0; i<rc->num_frames; i++) {
405 :     stat_t * s = &rc->stats[i];
406 :    
407 :     rc->tot_scaled_length[s->type-1] += s->scaled_length;
408 :    
409 :     if (s->type == XVID_TYPE_IVOP) {
410 :     ivop_boost_total += s->scaled_length * rc->param.keyframe_boost / 100;
411 :     }
412 :     }
413 :    
414 : 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) /
415 :     (rc->tot_scaled_length[XVID_TYPE_PVOP-1] + rc->tot_scaled_length[XVID_TYPE_BVOP-1]));
416 :    
417 :     for(i=0; i<3; i++) {
418 :     if (rc->count[i] == 0 || rc->movie_curve == 0) {
419 :     rc->avg_length[i] = 1;
420 :     }else{
421 :     rc->avg_length[i] = rc->tot_scaled_length[i] / rc->count[i] / rc->movie_curve;
422 :     }
423 :     }
424 :    
425 :     /* alt curve stuff here */
426 :    
427 :     if (rc->param.use_alt_curve) {
428 :     const double avg_pvop = rc->avg_length[XVID_TYPE_PVOP-1];
429 :     const uint64_t tot_pvop = rc->tot_length[XVID_TYPE_PVOP-1];
430 :     const uint64_t tot_bvop = rc->tot_length[XVID_TYPE_BVOP-1];
431 :     const uint64_t tot_scaled_pvop = rc->tot_scaled_length[XVID_TYPE_PVOP-1];
432 :     const uint64_t tot_scaled_bvop = rc->tot_scaled_length[XVID_TYPE_BVOP-1];
433 :    
434 :     rc->alt_curve_low = avg_pvop - avg_pvop * (double)rc->param.alt_curve_low_dist / 100.0;
435 :     rc->alt_curve_low_diff = avg_pvop - rc->alt_curve_low;
436 :     rc->alt_curve_high = avg_pvop + avg_pvop * (double)rc->param.alt_curve_high_dist / 100.0;
437 :     rc->alt_curve_high_diff = rc->alt_curve_high - avg_pvop;
438 :    
439 :     if (rc->param.alt_curve_use_auto) {
440 :     if (tot_bvop + tot_pvop > tot_scaled_bvop + tot_scaled_pvop) {
441 :     rc->param.alt_curve_min_rel_qual = (int)(100.0 - (100.0 - 100.0 /
442 :     ((double)(tot_pvop + tot_bvop) / (double)(tot_scaled_pvop + tot_scaled_bvop))) * (double)rc->param.alt_curve_auto_str / 100.0);
443 :    
444 :     if (rc->param.alt_curve_min_rel_qual < 20)
445 :     rc->param.alt_curve_min_rel_qual = 20;
446 :     }else{
447 :     rc->param.alt_curve_min_rel_qual = 100;
448 :     }
449 :     }
450 :     rc->alt_curve_mid_qual = (1.0 + (double)rc->param.alt_curve_min_rel_qual / 100.0) / 2.0;
451 :     rc->alt_curve_qual_dev = 1.0 - rc->alt_curve_mid_qual;
452 :    
453 :     if (rc->param.alt_curve_low_dist > 100) {
454 :     switch(rc->param.alt_curve_type) {
455 :     case XVID_CURVE_SINE: // Sine Curve (high aggressiveness)
456 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff)));
457 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * sin(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff));
458 :     break;
459 :     case XVID_CURVE_LINEAR: // Linear (medium aggressiveness)
460 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + avg_pvop / rc->alt_curve_low_diff);
461 :     rc->alt_curve_mid_qual = 1.0 - rc->alt_curve_qual_dev * avg_pvop / rc->alt_curve_low_diff;
462 :     break;
463 :     case XVID_CURVE_COSINE: // Cosine Curve (low aggressiveness)
464 :     rc->alt_curve_qual_dev *= 2.0 / (1.0 + (1.0 - cos(DEG2RAD * (avg_pvop * 90.0 / rc->alt_curve_low_diff))));
465 :     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)));
466 :     }
467 :     }
468 :     }
469 :     /* --- */
470 :    
471 :    
472 :     total1=total2=0;
473 : suxen_drol 977 for (i=0; i<rc->num_frames; i++) {
474 : suxen_drol 942 stat_t * s = &rc->stats[i];
475 :    
476 :     if (s->type != XVID_TYPE_IVOP) {
477 :     double dbytes,dbytes2;
478 :    
479 :     dbytes = s->scaled_length / rc->movie_curve;
480 :     dbytes2 = 0; /* XXX: warning */
481 :     total1 += dbytes;
482 :     if (s->type == XVID_TYPE_BVOP)
483 :     dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];
484 :    
485 :     if (rc->param.use_alt_curve) {
486 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
487 :    
488 :     if (dbytes >= rc->alt_curve_high) {
489 :     dbytes2 = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
490 :     }else{
491 :     switch(rc->param.alt_curve_type) {
492 :     case XVID_CURVE_SINE :
493 :     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)));
494 :     break;
495 :     case XVID_CURVE_LINEAR :
496 :     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);
497 :     break;
498 :     case XVID_CURVE_COSINE :
499 :     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))));
500 :     }
501 :     }
502 :     }else{
503 :     if (dbytes <= rc->alt_curve_low) {
504 :     dbytes2 = dbytes;
505 :     }else{
506 :     switch(rc->param.alt_curve_type) {
507 :     case XVID_CURVE_SINE :
508 :     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)));
509 :     break;
510 :     case XVID_CURVE_LINEAR :
511 :     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);
512 :     break;
513 :     case XVID_CURVE_COSINE :
514 :     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))));
515 :     }
516 :     }
517 :    
518 :     }
519 :    
520 :    
521 :     }else{
522 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
523 :     dbytes2=((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0);
524 :     }else{
525 :     dbytes2 = ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);
526 :     }
527 :     }
528 :    
529 :     if (s->type == XVID_TYPE_BVOP) {
530 :     dbytes2 *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
531 :     if (dbytes2 < rc->min_length[XVID_TYPE_BVOP-1])
532 :     dbytes2 = rc->min_length[XVID_TYPE_BVOP-1];
533 :     }else{
534 :     if (dbytes2 < rc->min_length[XVID_TYPE_PVOP-1])
535 :     dbytes2 = rc->min_length[XVID_TYPE_PVOP-1];
536 :     }
537 :     total2 += dbytes2;
538 :     }
539 :     }
540 :    
541 :     rc->curve_comp_scale = total1 / total2;
542 :    
543 :     if (!rc->param.use_alt_curve) {
544 : suxen_drol 1032 DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: %i\n",
545 : suxen_drol 942 (int)(rc->avg_length[XVID_TYPE_PVOP-1] * rc->curve_comp_scale));
546 :     }
547 :    
548 :     if (rc->param.use_alt_curve) {
549 :     int bonus_bias = rc->param.alt_curve_bonus_bias;
550 :     int oldquant = 1;
551 :    
552 :     if (rc->param.alt_curve_use_auto_bonus_bias)
553 :     bonus_bias = rc->param.alt_curve_min_rel_qual;
554 :    
555 :     rc->alt_curve_curve_bias_bonus = (total1 - total2) * (double)bonus_bias / 100.0 / (double)(rc->num_frames /* - credits_frames */ - rc->num_keyframes);
556 :     rc->curve_comp_scale = ((total1 - total2) * (1.0 - (double)bonus_bias / 100.0) + total2) / total2;
557 :    
558 :    
559 :     /* special info for alt curve: bias bonus and quantizer thresholds */
560 :    
561 : edgomez 1038 DPRINTF(XVID_DEBUG_RC, "avg scaled framesize:%i\n", (int)rc->avg_length[XVID_TYPE_PVOP-1]);
562 :     DPRINTF(XVID_DEBUG_RC, "bias bonus:%i bytes\n", (int)rc->alt_curve_curve_bias_bonus);
563 : suxen_drol 942
564 :     for (i=1; i <= (int)(rc->alt_curve_high*2)+1; i++) {
565 :     double curve_temp, dbytes;
566 :     int newquant;
567 :    
568 :     dbytes = i;
569 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
570 :     if (dbytes >= rc->alt_curve_high) {
571 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
572 :     }else{
573 :     switch(rc->param.alt_curve_type)
574 :     {
575 :     case XVID_CURVE_SINE :
576 :     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)));
577 :     break;
578 :     case XVID_CURVE_LINEAR :
579 :     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);
580 :     break;
581 :     case XVID_CURVE_COSINE :
582 :     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))));
583 :     }
584 :     }
585 :     }else{
586 :     if (dbytes <= rc->alt_curve_low) {
587 :     curve_temp = dbytes;
588 :     }else{
589 :     switch(rc->param.alt_curve_type)
590 :     {
591 :     case XVID_CURVE_SINE :
592 :     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)));
593 :     break;
594 :     case XVID_CURVE_LINEAR :
595 :     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);
596 :     break;
597 :     case XVID_CURVE_COSINE :
598 :     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))));
599 :     }
600 :     }
601 :     }
602 :    
603 :     if (rc->movie_curve > 1.0)
604 :     dbytes *= rc->movie_curve;
605 :    
606 :     newquant = (int)(dbytes * 2.0 / (curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus));
607 :     if (newquant > 1) {
608 :     if (newquant != oldquant) {
609 :     int percent = (int)((i - rc->avg_length[XVID_TYPE_PVOP-1]) * 100.0 / rc->avg_length[XVID_TYPE_PVOP-1]);
610 :     oldquant = newquant;
611 : edgomez 1038 DPRINTF(XVID_DEBUG_RC, "quant:%i threshold at %i : %i percent\n", newquant, i, percent);
612 : suxen_drol 942 }
613 :     }
614 :     }
615 :    
616 :     }
617 :    
618 :     rc->overflow = 0;
619 :     rc->KFoverflow = 0;
620 :     rc->KFoverflow_partial = 0;
621 :     rc->KF_idx = 1;
622 :     }
623 :    
624 :    
625 :    
626 :    
627 :     static int rc_2pass2_create(xvid_plg_create_t * create, rc_2pass2_t ** handle)
628 :     {
629 :     xvid_plugin_2pass2_t * param = (xvid_plugin_2pass2_t *)create->param;
630 :     rc_2pass2_t * rc;
631 : suxen_drol 1030 int i;
632 : suxen_drol 942
633 :     rc = malloc(sizeof(rc_2pass2_t));
634 :     if (rc == NULL)
635 :     return XVID_ERR_MEMORY;
636 :    
637 :     rc->param = *param;
638 :    
639 :     if (rc->param.keyframe_boost <= 0) rc->param.keyframe_boost = 0;
640 :     if (rc->param.payback_method <= 0) rc->param.payback_method = XVID_PAYBACK_PROP;
641 :     if (rc->param.bitrate_payback_delay <= 0) rc->param.bitrate_payback_delay = 250;
642 :     if (rc->param.curve_compression_high <= 0) rc->param.curve_compression_high = 0;
643 :     if (rc->param.curve_compression_low <= 0) rc->param.curve_compression_low = 0;
644 :     if (rc->param.max_overflow_improvement <= 0) rc->param.max_overflow_improvement = 60;
645 :     if (rc->param.max_overflow_degradation <= 0) rc->param.max_overflow_degradation = 60;
646 :    
647 :     if (rc->param.use_alt_curve <= 0) rc->param.use_alt_curve = 0;
648 :     if (rc->param.alt_curve_high_dist <= 0) rc->param.alt_curve_high_dist = 500;
649 :     if (rc->param.alt_curve_low_dist <= 0) rc->param.alt_curve_low_dist = 90;
650 :     if (rc->param.alt_curve_use_auto <= 0) rc->param.alt_curve_use_auto = 1;
651 :     if (rc->param.alt_curve_auto_str <= 0) rc->param.alt_curve_auto_str = 30;
652 :     if (rc->param.alt_curve_type <= 0) rc->param.alt_curve_type = XVID_CURVE_LINEAR;
653 :     if (rc->param.alt_curve_min_rel_qual <= 0) rc->param.alt_curve_min_rel_qual = 50;
654 :     if (rc->param.alt_curve_use_auto_bonus_bias <= 0) rc->param.alt_curve_use_auto_bonus_bias = 1;
655 :     if (rc->param.alt_curve_bonus_bias <= 0) rc->param.alt_curve_bonus_bias = 50;
656 :    
657 :     if (rc->param.kftreshold <= 0) rc->param.kftreshold = 10;
658 :     if (rc->param.kfreduction <= 0) rc->param.kfreduction = 20;
659 :     if (rc->param.min_key_interval <= 0) rc->param.min_key_interval = 300;
660 :    
661 : suxen_drol 977 if (!det_stats_length(rc, param->filename)){
662 : suxen_drol 1032 DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename);
663 : suxen_drol 942 free(rc);
664 :     return XVID_ERR_FAIL;
665 :     }
666 :    
667 :     if ((rc->stats = malloc(rc->num_frames * sizeof(stat_t))) == NULL) {
668 :     free(rc);
669 :     return XVID_ERR_MEMORY;
670 :     }
671 :    
672 : edgomez 1037 /*
673 :     * We need an extra location because we do as if the last frame were an
674 :     * IFrame. This is needed because our code consider that frames between
675 :     * 2 IFrames form a natural sequence. So we store last frame as a
676 :     * keyframe location.
677 :     */
678 : suxen_drol 942 if ((rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int))) == NULL) {
679 :     free(rc->stats);
680 :     free(rc);
681 :     return XVID_ERR_MEMORY;
682 :     }
683 :    
684 : suxen_drol 977 if (!load_stats(rc, param->filename)) {
685 : suxen_drol 1032 DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename);
686 : suxen_drol 942 free(rc->keyframe_locations);
687 :     free(rc->stats);
688 :     free(rc);
689 :     return XVID_ERR_FAIL;
690 :     }
691 :    
692 :     /* pre-process our stats */
693 : suxen_drol 977
694 : suxen_drol 1030 if (rc->num_frames < create->fbase/create->fincr) {
695 :     rc->target = rc->param.bitrate / 8; /* one second */
696 :     }else{
697 : edgomez 1040 rc->target =
698 :     ((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * (uint64_t)create->fincr) / \
699 :     ((uint64_t)create->fbase * 8);
700 : suxen_drol 977 }
701 : suxen_drol 1030
702 : edgomez 1040 DPRINTF(XVID_DEBUG_RC, "Number of frames: %d\n", rc->num_frames);
703 :     DPRINTF(XVID_DEBUG_RC, "Frame rate: %d/%d\n", create->fbase, create->fincr);
704 :     DPRINTF(XVID_DEBUG_RC, "Target bitrate: %ld\n", rc->param.bitrate);
705 :     DPRINTF(XVID_DEBUG_RC, "Target filesize: %lld\n", rc->target);
706 : suxen_drol 1032
707 : edgomez 1041 /* Compensate the mean frame overhead caused by the container */
708 :     rc->target -= rc->num_frames*rc->param.container_frame_overhead;
709 :     DPRINTF(XVID_DEBUG_RC, "Container Frame overhead: %d\n", rc->param.container_frame_overhead);
710 :     DPRINTF(XVID_DEBUG_RC, "Target filesize (after container compensation): %lld\n", rc->target);
711 : suxen_drol 977
712 :     pre_process0(rc);
713 : edgomez 1036
714 : suxen_drol 977 if (rc->param.bitrate) {
715 : suxen_drol 1030 zone_process(rc, create);
716 : suxen_drol 977 internal_scale(rc);
717 : suxen_drol 1030 }else{
718 :     /* external scaler: ignore zone */
719 :     for (i=0;i<rc->num_frames;i++) {
720 :     rc->stats[i].zone_mode = XVID_ZONE_WEIGHT;
721 :     rc->stats[i].weight = 1.0;
722 :     }
723 :     rc->avg_weight = 1.0;
724 :     rc->tot_quant = 0;
725 :     }
726 :     pre_process1(rc);
727 :    
728 :     for (i=0; i<32;i++) {
729 :     rc->pquant_error[i] = 0;
730 :     rc->bquant_error[i] = 0;
731 :     rc->quant_count[i] = 0;
732 :     }
733 :    
734 :     rc->fq_error = 0;
735 : suxen_drol 977
736 : suxen_drol 942 *handle = rc;
737 :     return(0);
738 :     }
739 :    
740 :    
741 :     static int rc_2pass2_destroy(rc_2pass2_t * rc, xvid_plg_destroy_t * destroy)
742 :     {
743 :     free(rc->keyframe_locations);
744 :     free(rc->stats);
745 :     free(rc);
746 :     return(0);
747 :     }
748 :    
749 :    
750 :    
751 :     static int rc_2pass2_before(rc_2pass2_t * rc, xvid_plg_data_t * data)
752 :     {
753 :     stat_t * s = &rc->stats[data->frame_num];
754 :     int overflow;
755 :     int desired;
756 :     double dbytes;
757 :     double curve_temp;
758 :     int capped_to_max_framesize = 0;
759 :    
760 : edgomez 1037 /*
761 :     * This function is quite long but easy to understand. In order to simplify
762 :     * the code path (a bit), we treat 3 cases that can return immediatly.
763 :     */
764 : suxen_drol 942
765 : edgomez 1037 /* First case: Another plugin has already set a quantizer */
766 :     if (data->quant > 0)
767 :     return(0);
768 : suxen_drol 942
769 : edgomez 1037 /* Second case: We are in a Quant zone */
770 :     if (s->zone_mode == XVID_ZONE_QUANT) {
771 : suxen_drol 942
772 : edgomez 1037 rc->fq_error += s->weight;
773 :     data->quant = (int)rc->fq_error;
774 :     rc->fq_error -= data->quant;
775 :    
776 :     s->desired_length = s->length;
777 : suxen_drol 1032
778 : edgomez 1037 return(0);
779 : suxen_drol 942
780 : edgomez 1037 }
781 : suxen_drol 977
782 : edgomez 1037 /* Third case: insufficent stats data */
783 :     if (data->frame_num >= rc->num_frames)
784 :     return 0;
785 : suxen_drol 942
786 : edgomez 1037 /*
787 :     * The last case is the one every normal minded developer should fear to
788 :     * maintain in a project :-)
789 :     */
790 : suxen_drol 942
791 : edgomez 1037 /* XXX: why by 8 */
792 :     overflow = rc->overflow / 8;
793 : suxen_drol 942
794 : edgomez 1037 /*
795 :     * The rc->overflow field represents the overflow in current scene (between two
796 :     * IFrames) so we must not forget to reset it if we are enetring a new scene
797 :     */
798 :     if (s->type == XVID_TYPE_IVOP) {
799 :     overflow = 0;
800 :     }
801 : suxen_drol 942
802 : edgomez 1037 desired = s->scaled_length;
803 : suxen_drol 942
804 : edgomez 1037 dbytes = desired;
805 :     if (s->type == XVID_TYPE_IVOP) {
806 :     dbytes += desired * rc->param.keyframe_boost / 100;
807 :     }
808 :     dbytes /= rc->movie_curve;
809 : suxen_drol 942
810 : edgomez 1037 /*
811 :     * We are now entering in the hard part of the algo, it was first designed
812 :     * to work with i/pframes only streams, so the way it computes things is
813 :     * adapted to pframes only. However we can use it if we just take care to
814 :     * scale the bframes sizes to pframes sizes using the ratio avg_p/avg_p and
815 :     * then before really using values depending on frame sizes, scaling the
816 :     * value again with the inverse ratio
817 :     */
818 :     if (s->type == XVID_TYPE_BVOP) {
819 :     dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];
820 :     }
821 : suxen_drol 942
822 : edgomez 1037 /*
823 :     * Apply user's choosen Payback method. Payback helps bitrate to follow the
824 :     * scaled curve "paying back" past errors in curve previsions.
825 :     */
826 :     if (rc->param.payback_method == XVID_PAYBACK_BIAS) {
827 :     desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay);
828 :     }else{
829 :     desired = (int)(rc->curve_comp_error * dbytes /
830 :     rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay);
831 : suxen_drol 942
832 : edgomez 1037 if (labs(desired) > fabs(rc->curve_comp_error)) {
833 :     desired = (int)rc->curve_comp_error;
834 :     }
835 :     }
836 : suxen_drol 942
837 : edgomez 1037 rc->curve_comp_error -= desired;
838 : suxen_drol 942
839 : edgomez 1037 /*
840 :     * Alt curve treatment is not that hard to understand though the formulas
841 :     * seem to be huge. Alt treatment is basically a way to soft/harden the
842 :     * curve flux applying sine/linear/cosine ratios
843 :     */
844 : suxen_drol 942
845 : edgomez 1037 /* XXX: warning */
846 :     curve_temp = 0;
847 : suxen_drol 942
848 : edgomez 1037 if (rc->param.use_alt_curve) {
849 :     if (s->type != XVID_TYPE_IVOP) {
850 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
851 :     if (dbytes >= rc->alt_curve_high) {
852 :     curve_temp = dbytes * (rc->alt_curve_mid_qual - rc->alt_curve_qual_dev);
853 :     } else {
854 :     switch(rc->param.alt_curve_type) {
855 :     case XVID_CURVE_SINE :
856 :     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)));
857 :     break;
858 :     case XVID_CURVE_LINEAR :
859 :     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);
860 :     break;
861 :     case XVID_CURVE_COSINE :
862 :     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))));
863 :     }
864 :     }
865 :     } else {
866 :     if (dbytes <= rc->alt_curve_low){
867 :     curve_temp = dbytes;
868 :     } else {
869 :     switch(rc->param.alt_curve_type) {
870 :     case XVID_CURVE_SINE :
871 :     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)));
872 :     break;
873 :     case XVID_CURVE_LINEAR :
874 :     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);
875 :     break;
876 :     case XVID_CURVE_COSINE :
877 :     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))));
878 :     }
879 :     }
880 :     }
881 : suxen_drol 942
882 : edgomez 1037 /*
883 :     * End of code path for curve_temp, as told earlier, we are now
884 :     * obliged to scale the value to a bframe one using the inverse
885 :     * ratio applied earlier
886 :     */
887 :     if (s->type == XVID_TYPE_BVOP)
888 :     curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
889 : suxen_drol 942
890 : edgomez 1037 curve_temp = curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus;
891 : suxen_drol 942
892 : edgomez 1037 desired += ((int)curve_temp);
893 :     rc->curve_comp_error += curve_temp - (int)curve_temp;
894 :     } else {
895 :     /*
896 :     * End of code path for dbytes, as told earlier, we are now
897 :     * obliged to scale the value to a bframe one using the inverse
898 :     * ratio applied earlier
899 :     */
900 :     if (s->type == XVID_TYPE_BVOP)
901 :     dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
902 : suxen_drol 1030
903 : edgomez 1037 desired += ((int)dbytes);
904 :     rc->curve_comp_error += dbytes - (int)dbytes;
905 :     }
906 : suxen_drol 1030
907 : edgomez 1037 } else if ((rc->param.curve_compression_high + rc->param.curve_compression_low) && s->type != XVID_TYPE_IVOP) {
908 : suxen_drol 1030
909 : edgomez 1037 curve_temp = rc->curve_comp_scale;
910 :     if (dbytes > rc->avg_length[XVID_TYPE_PVOP-1]) {
911 :     curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_high / 100.0);
912 :     } else {
913 :     curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);
914 :     }
915 : suxen_drol 942
916 : edgomez 1037 /*
917 :     * End of code path for curve_temp, as told earlier, we are now
918 :     * obliged to scale the value to a bframe one using the inverse
919 :     * ratio applied earlier
920 :     */
921 :     if (s->type == XVID_TYPE_BVOP)
922 :     curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
923 : suxen_drol 1032
924 : edgomez 1037 desired += (int)curve_temp;
925 :     rc->curve_comp_error += curve_temp - (int)curve_temp;
926 :     } else {
927 :     /*
928 :     * End of code path for dbytes, as told earlier, we are now
929 :     * obliged to scale the value to a bframe one using the inverse
930 :     * ratio applied earlier
931 :     */
932 :     if (s->type == XVID_TYPE_BVOP){
933 :     dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
934 :     }
935 : suxen_drol 942
936 : edgomez 1037 desired += (int)dbytes;
937 :     rc->curve_comp_error += dbytes - (int)dbytes;
938 :     }
939 : suxen_drol 942
940 :    
941 : edgomez 1037 /*
942 :     * We can't do bigger frames than first pass, this would be stupid as first
943 :     * pass is quant=2 and that reaching quant=1 is not worth it. We would lose
944 :     * many bytes and we would not not gain much quality.
945 :     */
946 :     if (desired > s->length) {
947 :     rc->curve_comp_error += desired - s->length;
948 :     desired = s->length;
949 :     }else{
950 :     if (desired < rc->min_length[s->type-1]) {
951 :     if (s->type == XVID_TYPE_IVOP){
952 :     rc->curve_comp_error -= rc->min_length[XVID_TYPE_IVOP-1] - desired;
953 :     }
954 :     desired = rc->min_length[s->type-1];
955 :     }
956 :     }
957 : suxen_drol 942
958 : edgomez 1037 s->desired_length = desired;
959 : suxen_drol 942
960 : edgomez 1037
961 :     /* if this keyframe is too close to the next, reduce it's byte allotment
962 :     XXX: why do we do this after setting the desired length */
963 : suxen_drol 942
964 : edgomez 1037 if (s->type == XVID_TYPE_IVOP) {
965 :     int KFdistance = rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1];
966 : suxen_drol 942
967 : edgomez 1037 if (KFdistance < rc->param.kftreshold) {
968 :    
969 :     KFdistance = KFdistance - rc->param.min_key_interval;
970 : suxen_drol 942
971 : edgomez 1037 if (KFdistance >= 0) {
972 :     int KF_min_size;
973 : suxen_drol 942
974 : edgomez 1037 KF_min_size = desired * (100 - rc->param.kfreduction) / 100;
975 :     if (KF_min_size < 1)
976 :     KF_min_size = 1;
977 : suxen_drol 942
978 : edgomez 1037 desired = KF_min_size + (desired - KF_min_size) * KFdistance /
979 :     (rc->param.kftreshold - rc->param.min_key_interval);
980 : suxen_drol 942
981 : edgomez 1037 if (desired < 1)
982 :     desired = 1;
983 :     }
984 :     }
985 :     }
986 : suxen_drol 942
987 : edgomez 1037 overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]);
988 : suxen_drol 942
989 : edgomez 1037 /* Reign in overflow with huge frames */
990 :     if (labs(overflow) > labs(rc->overflow)) {
991 :     overflow = rc->overflow;
992 :     }
993 : suxen_drol 942
994 : edgomez 1037 /* Make sure overflow doesn't run away */
995 :     if (overflow > desired * rc->param.max_overflow_improvement / 100) {
996 :     desired += (overflow <= desired) ? desired * rc->param.max_overflow_improvement / 100 :
997 :     overflow * rc->param.max_overflow_improvement / 100;
998 :     } else if (overflow < desired * rc->param.max_overflow_degradation / -100){
999 :     desired += desired * rc->param.max_overflow_degradation / -100;
1000 :     } else {
1001 :     desired += overflow;
1002 :     }
1003 : suxen_drol 942
1004 : edgomez 1037 /* Make sure we are not higher than desired frame size */
1005 :     if (desired > rc->max_length) {
1006 :     capped_to_max_framesize = 1;
1007 :     desired = rc->max_length;
1008 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,"[%i] Capped to maximum frame size\n",
1009 :     data->frame_num);
1010 : edgomez 1037 }
1011 : suxen_drol 942
1012 : edgomez 1037 /* Make sure to not scale below the minimum framesize */
1013 : edgomez 1040 if (desired < rc->min_length[s->type-1]) {
1014 : edgomez 1037 desired = rc->min_length[s->type-1];
1015 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,"[%i] Capped to minimum frame size\n",
1016 :     data->frame_num);
1017 :     }
1018 : suxen_drol 942
1019 : edgomez 1037 /*
1020 :     * Don't laugh at this very 'simple' quant<->filesize relationship, it
1021 :     * proves to be acurate enough for our algorithm
1022 :     */
1023 :     data->quant= (s->quant * s->length) / desired;
1024 : suxen_drol 942
1025 : edgomez 1037 /* Let's clip the computed quantizer, if needed */
1026 :     if (data->quant < 1) {
1027 :     data->quant = 1;
1028 :     } else if (data->quant > 31) {
1029 :     data->quant = 31;
1030 :     } else if (s->type != XVID_TYPE_IVOP) {
1031 : suxen_drol 942
1032 : edgomez 1037 /*
1033 :     * The frame quantizer has not been clipped, this appear to be a good
1034 :     * computed quantizer, however past frames give us some info about how
1035 :     * this quantizer performs against the algo prevision. Let's use this
1036 :     * prevision to increase the quantizer when we observe a too big
1037 :     * accumulated error
1038 :     */
1039 :     if (s->type== XVID_TYPE_BVOP) {
1040 :     rc->bquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;
1041 : suxen_drol 942
1042 : edgomez 1037 if (rc->bquant_error[data->quant] >= 1.0) {
1043 :     rc->bquant_error[data->quant] -= 1.0;
1044 :     data->quant++;
1045 :     }
1046 :     } else {
1047 :     rc->pquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;
1048 : suxen_drol 942
1049 : edgomez 1037 if (rc->pquant_error[data->quant] >= 1.0) {
1050 :     rc->pquant_error[data->quant] -= 1.0;
1051 :     ++data->quant;
1052 :     }
1053 :     }
1054 :     }
1055 : suxen_drol 942
1056 : edgomez 1037 /*
1057 :     * Now we have a computed quant that is in the right quante range, with a
1058 :     * possible +1 correction due to cumulated error. We can now safely clip
1059 :     * the quantizer again with user's quant ranges. "Safely" means the Rate
1060 :     * Control could learn more about this quantizer, this knowledge is useful
1061 :     * for future frames even if it this quantizer won't be really used atm,
1062 :     * that's why we don't perform this clipping earlier.
1063 :     */
1064 :     if (data->quant < data->min_quant[s->type-1]) {
1065 :     data->quant = data->min_quant[s->type-1];
1066 :     } else if (data->quant > data->max_quant[s->type-1]) {
1067 :     data->quant = data->max_quant[s->type-1];
1068 :     }
1069 : suxen_drol 942
1070 : edgomez 1037 /*
1071 :     * To avoid big quality jumps from frame to frame, we apply a "security"
1072 :     * rule that makes |last_quant - new_quant| <= 2. This rule only applies
1073 :     * to predicted frames (P and B)
1074 :     */
1075 :     if (s->type != XVID_TYPE_IVOP && rc->last_quant[s->type-1] && capped_to_max_framesize == 0) {
1076 : suxen_drol 942
1077 : edgomez 1037 if (data->quant > rc->last_quant[s->type-1] + 2) {
1078 :     data->quant = rc->last_quant[s->type-1] + 2;
1079 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,
1080 :     "[%i] p/b-frame quantizer prevented from rising too steeply\n",
1081 :     data->frame_num);
1082 : edgomez 1037 }
1083 :     if (data->quant < rc->last_quant[s->type-1] - 2) {
1084 :     data->quant = rc->last_quant[s->type-1] - 2;
1085 : edgomez 1040 DPRINTF(XVID_DEBUG_RC,
1086 :     "[%i] p/b-frame quantizer prevented from falling too steeply\n",
1087 :     data->frame_num);
1088 : edgomez 1037 }
1089 :     }
1090 : suxen_drol 1030
1091 : edgomez 1037 /*
1092 :     * We don't want to pollute the RC history results when our computed quant
1093 :     * has been computed from a capped frame size
1094 :     */
1095 :     if (capped_to_max_framesize == 0) {
1096 :     rc->last_quant[s->type-1] = data->quant;
1097 :     }
1098 : suxen_drol 1030
1099 : edgomez 1037 return 0;
1100 : suxen_drol 942 }
1101 :    
1102 :    
1103 :    
1104 :     static int rc_2pass2_after(rc_2pass2_t * rc, xvid_plg_data_t * data)
1105 :     {
1106 :     stat_t * s = &rc->stats[data->frame_num];
1107 :    
1108 : edgomez 1037 /* Insufficent stats data */
1109 :     if (data->frame_num >= rc->num_frames)
1110 : suxen_drol 942 return 0;
1111 :    
1112 :     rc->quant_count[data->quant]++;
1113 :    
1114 :     if (data->type == XVID_TYPE_IVOP) {
1115 :     int kfdiff = (rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1]);
1116 :    
1117 :     rc->overflow += rc->KFoverflow;
1118 :     rc->KFoverflow = s->desired_length - data->length;
1119 :    
1120 :     if (kfdiff > 1) { // non-consecutive keyframes
1121 :     rc->KFoverflow_partial = rc->KFoverflow / (kfdiff - 1);
1122 :     }else{ // consecutive keyframes
1123 :     rc->overflow += rc->KFoverflow;
1124 :     rc->KFoverflow = 0;
1125 :     rc->KFoverflow_partial = 0;
1126 :     }
1127 :     rc->KF_idx++;
1128 :     }else{
1129 :     // distribute part of the keyframe overflow
1130 :     rc->overflow += s->desired_length - data->length + rc->KFoverflow_partial;
1131 :     rc->KFoverflow -= rc->KFoverflow_partial;
1132 :     }
1133 :    
1134 : suxen_drol 1032 DPRINTF(XVID_DEBUG_RC, "[%i] quant:%i stats1:%i scaled:%i actual:%i overflow:%i\n",
1135 : suxen_drol 942 data->frame_num,
1136 :     data->quant,
1137 :     s->length,
1138 :     s->scaled_length,
1139 :     data->length,
1140 :     rc->overflow);
1141 :    
1142 :     return(0);
1143 :     }
1144 :    
1145 :    
1146 :    
1147 :     int xvid_plugin_2pass2(void * handle, int opt, void * param1, void * param2)
1148 :     {
1149 :     switch(opt)
1150 :     {
1151 :     case XVID_PLG_INFO :
1152 :     return 0;
1153 :    
1154 :     case XVID_PLG_CREATE :
1155 :     return rc_2pass2_create((xvid_plg_create_t*)param1, param2);
1156 :    
1157 :     case XVID_PLG_DESTROY :
1158 :     return rc_2pass2_destroy((rc_2pass2_t*)handle, (xvid_plg_destroy_t*)param1);
1159 :    
1160 :     case XVID_PLG_BEFORE :
1161 :     return rc_2pass2_before((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);
1162 :    
1163 :     case XVID_PLG_AFTER :
1164 :     return rc_2pass2_after((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);
1165 :     }
1166 :    
1167 :     return XVID_ERR_FAIL;
1168 :     }

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