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

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

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