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

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

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

revision 1.1, Sun Mar 23 04:03:01 2003 UTC revision 1.1.2.1, Sun Mar 23 04:03:01 2003 UTC
# Line 0  Line 1 
1    /*****************************************************************************
2     *
3     * XviD VBR Library
4     * - CBR/ABR bitrate controller implementation -
5     *
6     * Copyright (C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21     *
22     * $Id$
23     *
24     ****************************************************************************/
25    
26    
27    #include "../xvid.h"
28    #include "../image/image.h"
29    
30    #define INITIAL_QUANT 5
31    
32    
33    typedef struct
34    {
35        int max_quantizer;
36        int min_quantizer;
37        int reaction_delay_factor;
38        int averaging_period;
39        int buffer;
40    
41        int bytes_per_sec;
42            double  target_framesize;
43    
44        double time;
45            int64_t total_size;
46            int rtn_quant;
47    
48    
49            double  sequence_quality;
50            double  avg_framesize;
51            double  quant_error[31];
52    } rc_cbr_t;
53    
54    
55    
56    static int rc_cbr_create(xvid_plg_create_t * create, rc_cbr_t ** handle)
57    {
58        xvid_plugin_cbr_t * param = (xvid_plugin_cbr_t *)create->param;
59            rc_cbr_t * rc;
60            int i;
61    
62        /* cbr need to caclulate the average frame size. in order to do that, we need some fps */
63        if (create->fincr == 0) {
64            return XVID_ERR_FAIL;
65        }
66    
67        /* allocate context struct */
68            if((rc = malloc(sizeof(rc_cbr_t))) == NULL)
69                    return(XVID_ERR_MEMORY);
70    
71            /* constants */
72        rc->bytes_per_sec         = param->bitrate / 8;
73        rc->target_framesize      = (double)rc->bytes_per_sec / ((double)create->fbase / create->fincr);
74        rc->max_quantizer         = param->max_quantizer>0 ? param->max_quantizer : 12;
75            rc->min_quantizer         = param->min_quantizer>0 ? param->min_quantizer : 2;
76        rc->reaction_delay_factor = param->reaction_delay_factor>0 ? param->reaction_delay_factor : 16;
77        rc->averaging_period      = param->averaging_period>0 ? param->averaging_period : 100;
78        rc->buffer                = param->buffer>0 ? param->buffer : 100;
79    
80        rc->time                  = 0;
81        rc->total_size            = 0;
82            rc->rtn_quant             = INITIAL_QUANT;
83    
84            /* Reset quant error accumulators */
85            for (i = 0; i < 31; i++)
86                    rc->quant_error[i] = 0.0;
87    
88            /* Last bunch of variables */
89    
90        printf("bytes_per_sec: %i\n", rc->bytes_per_sec);
91        printf("frame rate   : %f\n", (double)create->fbase / create->fincr);
92        printf("target_framesize: %f\n",rc->target_framesize);
93    
94        rc->sequence_quality = 2.0 / (double) rc->rtn_quant;
95            rc->avg_framesize = rc->target_framesize;
96    
97        *handle = rc;
98            return(0);
99    }
100    
101    
102    static int rc_cbr_destroy(rc_cbr_t * rc, xvid_plg_destroy_t * destroy)
103    {
104            free(rc);
105            return(0);
106    }
107    
108    
109    static int rc_cbr_before(rc_cbr_t * rc, xvid_plg_data_t * data)
110    {
111        data->quant = rc->rtn_quant;
112        data->type = XVID_TYPE_AUTO;
113        return 0;
114    }
115    
116    
117    static int rc_cbr_after(rc_cbr_t * rc, xvid_plg_data_t * data)
118    {
119            int64_t deviation;
120            int rtn_quant;
121            double overflow;
122            double averaging_period;
123            double reaction_delay_factor;
124            double quality_scale;
125            double base_quality;
126            double target_quality;
127    
128    
129            /* Update internal values */
130        rc->time += (double)data->fincr / data->fbase;
131        rc->total_size += data->length;
132    
133            /* Compute the deviation from expected total size */
134            deviation = (int64_t)
135            ((double)rc->total_size - (double)rc->bytes_per_sec*rc->time);
136    
137    
138        if(rc->rtn_quant >= 2) {
139    
140                    averaging_period = (double) rc->averaging_period;
141    
142                    rc->sequence_quality -=
143                            rc->sequence_quality / averaging_period;
144    
145                    rc->sequence_quality +=
146                            2.0 / (double) rc->rtn_quant / averaging_period;
147    
148                    if (rc->sequence_quality < 0.1)
149                            rc->sequence_quality = 0.1;
150    
151                    if (data->type != XVID_TYPE_IVOP) {
152                            reaction_delay_factor = (double) rc->reaction_delay_factor;
153                            rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;
154                            rc->avg_framesize += data->length / reaction_delay_factor;
155                    }
156    
157            }
158    
159            quality_scale =
160                    rc->target_framesize / rc->avg_framesize *
161                    rc->target_framesize / rc->avg_framesize;
162    
163            base_quality = rc->sequence_quality;
164            if (quality_scale >= 1.0) {
165                    base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
166            } else {
167                    base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
168            }
169    
170            overflow = -((double) deviation / (double) rc->buffer);
171    
172            target_quality =
173                    base_quality +
174                    (base_quality - 0.06452) * overflow / rc->target_framesize;
175    
176            if (target_quality > 2.0)
177                    target_quality = 2.0;
178            else if (target_quality < 0.06452)
179                    target_quality = 0.06452;
180    
181            rtn_quant = (int) (2.0 / target_quality);
182    
183            if (rtn_quant < 31) {
184                    rc->quant_error[rtn_quant-1] +=
185                            2.0 / target_quality - rtn_quant;
186                    if (rc->quant_error[rtn_quant-1] >= 1.0) {
187                            rc->quant_error[rtn_quant-1] -= 1.0;
188                            rtn_quant++;
189                    }
190            }
191    
192            if (rtn_quant > rc->rtn_quant + 1)
193                    rtn_quant = rc->rtn_quant + 1;
194            else if (rtn_quant < rc->rtn_quant - 1)
195                    rtn_quant = rc->rtn_quant - 1;
196    
197            if (rtn_quant > rc->max_quantizer)
198                    rtn_quant = rc->max_quantizer;
199            else if (rtn_quant < rc->min_quantizer)
200                    rtn_quant = rc->min_quantizer;
201    
202            rc->rtn_quant = rtn_quant;
203    
204            return(0);
205    }
206    
207    
208    
209    int xvid_plugin_cbr(void * handle, int opt, void * param1, void * param2)
210    {
211        switch(opt)
212        {
213        case XVID_PLG_INFO :
214            return 0;
215    
216        case XVID_PLG_CREATE :
217            return rc_cbr_create((xvid_plg_create_t*)param1, param2);
218    
219        case XVID_PLG_DESTROY :
220            return rc_cbr_destroy((rc_cbr_t*)handle, (xvid_plg_destroy_t*)param1);
221    
222        case XVID_PLG_BEFORE :
223            return rc_cbr_before((rc_cbr_t*)handle, (xvid_plg_data_t*)param1);
224    
225        case XVID_PLG_AFTER :
226            return rc_cbr_after((rc_cbr_t*)handle, (xvid_plg_data_t*)param1);
227        }
228    
229        return XVID_ERR_FAIL;
230    }
231    

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