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

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