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

Diff of /xvidcore/src/plugins/plugin_2pass2.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Tue Mar 25 10:58:33 2003 UTC revision 1.1.2.8, Thu May 22 16:36:07 2003 UTC
# Line 0  Line 1 
1    /******************************************************************************
2     *
3     * XviD Bit Rate Controller Library
4     * - VBR 2 pass bitrate controler implementation -
5     *
6     * 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     *
11     * This curve treatment algorithm is the one originally implemented by Foxer
12     * and tuned by Dirk Knop for the XviD vfw frontend.
13     *
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     * $Id$
29     *
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            int blks[3];                    /* k,m,y blks */
45        int length;             /* first pass length */
46        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    } 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            int num_frames;
63        int num_keyframes;
64        uint64_t target;    /* target filesize */
65    
66        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    
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        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    
105        double fq_error;
106    } 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        while((n = fscanf(f, "%c %d %d %d %d %d %d\n",
129            &type, &ignore, &ignore, &ignore, &ignore, &ignore, &ignore)) != EOF) {
130            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    /* open stats file(s) and read into rc->stats array */
146    
147    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                DPRINTF(XVID_DEBUG_RC, "unknown stats frame type; assuming pvop\n");
178                s->type = XVID_TYPE_PVOP;
179            }
180    
181            i++;
182        }
183    
184        rc->num_frames = i;
185    
186            fclose(f);
187    
188        return 1;
189    }
190    
191    
192    
193    #if 0
194    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            DPRINTF(XVID_DEBUG_RC, "%i %i %i %i\n", s->type, s->quant, s->length, s->scaled_length);
200        }
201    }
202    #endif
203    
204    /* pre-process the statistics data
205        - for each type, count, tot_length, min_length, max_length
206        - set keyframes_locations
207    */
208    
209    void pre_process0(rc_2pass2_t * rc)
210    {
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    
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        rc->keyframe_locations[j] = i;
246    }
247    
248    
249    /* calculate zone weight "center" */
250    
251    static void zone_process(rc_2pass2_t *rc, const xvid_plg_create_t * create)
252    {
253        int i,j;
254        int n = 0;
255    
256        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        DPRINTF(XVID_DEBUG_RC, "center_weight: %f (for %i frames);   fixed_bytes: %i\n", rc->avg_weight, n, rc->tot_quant);
302    }
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            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            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                        if (len < min_size[s->type-1]) {            /* force frame size */
343                                s->scaled_length = min_size[s->type-1];
344                                target -= s->scaled_length;
345                                pass1_length -= s->length;
346                        }else{
347                                s->scaled_length = 0;
348                        }
349            }
350            }
351    
352        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            }
357    
358            DPRINTF(XVID_DEBUG_RC, "target=%i, tot_length=%i, scaler=%f\n", (int)target, (int)pass1_length, scaler);
359    
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    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        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        for (i=0; i<rc->num_frames; i++) {
455            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            DPRINTF(XVID_DEBUG_RC, "middle frame size for asymmetric curve compression: %i\n",
526                (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                    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    
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                                            DPRINTF(XVID_DEBUG_RC, "quant:%i threshold at %i : %i percent\n", newquant, i, percent);
593                                    }
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        int i;
613    
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        if (!det_stats_length(rc, param->filename)){
643            DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename);
644            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        /*
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        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        if (!load_stats(rc, param->filename)) {
666            DPRINTF(XVID_DEBUG_RC,"fopen %s failed\n", param->filename);
667            free(rc->keyframe_locations);
668            free(rc->stats);
669            free(rc);
670            return XVID_ERR_FAIL;
671        }
672    
673        /* pre-process our stats */
674    
675            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            }
680    
681        DPRINTF(XVID_DEBUG_RC, "rc->target : %i\n", rc->target);
682    
683    #if 0
684            rc->target -= rc->num_frames*24;        /* avi file header */
685    #endif
686    
687    
688            pre_process0(rc);
689    
690            if (rc->param.bitrate) {
691            zone_process(rc, create);
692                    internal_scale(rc);
693        }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    
712        *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            /*
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    
741            /* First case: Another plugin has already set a quantizer */
742        if (data->quant > 0)
743                    return(0);
744    
745            /* Second case: We are in a Quant zone */
746            if (s->zone_mode == XVID_ZONE_QUANT) {
747    
748                    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    
754                    return(0);
755    
756            }
757    
758            /* Third case: insufficent stats data */
759            if (data->frame_num >= rc->num_frames)
760                    return 0;
761    
762            /*
763             * The last case is the one every normal minded developer should fear to
764             * maintain in a project :-)
765             */
766    
767            /* XXX: why by 8 */
768            overflow = rc->overflow / 8;
769    
770            /*
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    
778            desired = s->scaled_length;
779    
780            dbytes = desired;
781            if (s->type == XVID_TYPE_IVOP) {
782                    dbytes += desired * rc->param.keyframe_boost / 100;
783            }
784            dbytes /= rc->movie_curve;
785    
786            /*
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    
798            /*
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    
808                    if (labs(desired) > fabs(rc->curve_comp_error)) {
809                            desired = (int)rc->curve_comp_error;
810                    }
811            }
812    
813            rc->curve_comp_error -= desired;
814    
815            /*
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    
821            /* XXX: warning */
822            curve_temp = 0;
823    
824            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    
858                            /*
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    
866                            curve_temp = curve_temp * rc->curve_comp_scale + rc->alt_curve_curve_bias_bonus;
867    
868                            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    
879                            desired += ((int)dbytes);
880                            rc->curve_comp_error += dbytes - (int)dbytes;
881                    }
882    
883            } else if ((rc->param.curve_compression_high + rc->param.curve_compression_low) &&      s->type != XVID_TYPE_IVOP) {
884    
885                    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    
892                    /*
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    
900                    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    
912                    desired += (int)dbytes;
913                    rc->curve_comp_error += dbytes - (int)dbytes;
914            }
915    
916    
917            /*
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    
934            s->desired_length = desired;
935    
936    
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    
940            if (s->type == XVID_TYPE_IVOP) {
941                    int KFdistance = rc->keyframe_locations[rc->KF_idx] - rc->keyframe_locations[rc->KF_idx - 1];
942    
943                    if (KFdistance < rc->param.kftreshold) {
944    
945                            KFdistance = KFdistance - rc->param.min_key_interval;
946    
947                            if (KFdistance >= 0) {
948                                    int KF_min_size;
949    
950                                    KF_min_size = desired * (100 - rc->param.kfreduction) / 100;
951                                    if (KF_min_size < 1)
952                                            KF_min_size = 1;
953    
954                                    desired = KF_min_size + (desired - KF_min_size) * KFdistance /
955                                            (rc->param.kftreshold - rc->param.min_key_interval);
956    
957                                    if (desired < 1)
958                                            desired = 1;
959                            }
960                    }
961            }
962    
963            overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]);
964    
965            /* Reign in overflow with huge frames */
966            if (labs(overflow) > labs(rc->overflow)) {
967                    overflow = rc->overflow;
968            }
969    
970            /* 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    
980            /* 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    
986            /* 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    
990            /*
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    
996            /* 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    
1003                    /*
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    
1013                            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    
1020                            if (rc->pquant_error[data->quant] >= 1.0) {
1021                                    rc->pquant_error[data->quant] -= 1.0;
1022                                    ++data->quant;
1023                            }
1024                    }
1025            }
1026    
1027            /*
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    
1041            /*
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    
1048                    if (data->quant > rc->last_quant[s->type-1] + 2) {
1049                            data->quant = rc->last_quant[s->type-1] + 2;
1050                            DPRINTF(XVID_DEBUG_RC, "p/b-frame quantizer prevented from rising too steeply\n");
1051                    }
1052                    if (data->quant < rc->last_quant[s->type-1] - 2) {
1053                            data->quant = rc->last_quant[s->type-1] - 2;
1054                            DPRINTF(XVID_DEBUG_RC, "p/b-frame quantizer prevented from falling too steeply\n");
1055                    }
1056            }
1057    
1058            /*
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    
1066            return 0;
1067    }
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            /* Insufficent stats data */
1076        if (data->frame_num >= rc->num_frames)
1077            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        DPRINTF(XVID_DEBUG_RC, "[%i] quant:%i stats1:%i scaled:%i actual:%i overflow:%i\n",
1102            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    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.8

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