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

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

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