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

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