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

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

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

revision 1.1, Mon May 12 12:33:16 2003 UTC revision 1.1.2.9, Fri Dec 5 14:44:35 2003 UTC
# Line 0  Line 1 
1    /*****************************************************************************
2     *
3     *  XviD Standard Plugins
4     *  - single-pass 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 8
34    
35    #define DEFAULT_BITRATE 900000  /* 900kbps */
36    #define DEFAULT_DELAY_FACTOR 16
37    #define DEFAULT_AVERAGING_PERIOD 100
38    #define DEFAULT_BUFFER 100
39    
40    typedef struct
41    {
42            int reaction_delay_factor;
43            int averaging_period;
44            int buffer;
45    
46            int bytes_per_sec;
47            double target_framesize;
48    
49            double time;
50            int64_t total_size;
51            int rtn_quant;
52    
53            double sequence_quality;
54            double avg_framesize;
55            double quant_error[31];
56    
57            double fq_error;
58    }
59    rc_single_t;
60    
61    
62    static int
63    get_initial_quant(unsigned int bitrate)
64    {
65    
66    #if defined(DEFAULT_INITIAL_QUANTIZER)
67            return (DEFAULT_INITIAL_QUANTIZER);
68    #else
69            int i;
70    
71            const unsigned int bitrate_quant[31] = {
72                    UINT_MAX
73            };
74    
75            for (i = 30; i >= 0; i--) {
76                    if (bitrate > bitrate_quant[i])
77                            continue;
78            }
79    
80            return (i + 1);
81    #endif
82    }
83    
84    static int
85    rc_single_create(xvid_plg_create_t * create,
86                              rc_single_t ** handle)
87    {
88            xvid_plugin_single_t *param = (xvid_plugin_single_t *) create->param;
89            rc_single_t *rc;
90            int i;
91    
92            /*
93             * single needs to caclculate the average frame size. In order to do that,
94             * we really need valid fps
95             */
96            if (create->fincr == 0) {
97                    return XVID_ERR_FAIL;
98            }
99    
100            /* Allocate context struct */
101            if ((rc = malloc(sizeof(rc_single_t))) == NULL)
102                    return (XVID_ERR_MEMORY);
103    
104            /* Constants */
105            rc->bytes_per_sec =     (param->bitrate > 0) ? param->bitrate / 8 : DEFAULT_BITRATE / 8;
106            rc->target_framesize =(double) rc->bytes_per_sec / ((double) create->fbase / create->fincr);
107            rc->reaction_delay_factor =     (param->reaction_delay_factor > 0) ? param->reaction_delay_factor : DEFAULT_DELAY_FACTOR;
108            rc->averaging_period = (param->averaging_period > 0) ? param->averaging_period : DEFAULT_AVERAGING_PERIOD;
109            rc->buffer = (param->buffer > 0) ? param->buffer : DEFAULT_BUFFER;
110    
111            rc->time = 0;
112            rc->total_size = 0;
113            rc->rtn_quant = get_initial_quant(param->bitrate);
114    
115            /* Reset quant error accumulators */
116            for (i = 0; i < 31; i++)
117                    rc->quant_error[i] = 0.0;
118    
119            /* Last bunch of variables */
120            rc->sequence_quality = 2.0 / (double) rc->rtn_quant;
121            rc->avg_framesize = rc->target_framesize;
122    
123            rc->fq_error = 0;
124    
125            /* Bind the RC */
126            *handle = rc;
127    
128            /* A bit of debug info */
129            DPRINTF(XVID_DEBUG_RC, "bytes_per_sec: %i\n", rc->bytes_per_sec);
130            DPRINTF(XVID_DEBUG_RC, "frame rate   : %f\n", (double) create->fbase / create->fincr);
131            DPRINTF(XVID_DEBUG_RC, "target_framesize: %f\n", rc->target_framesize);
132    
133            return (0);
134    }
135    
136    
137    static int
138    rc_single_destroy(rc_single_t * rc,
139                               xvid_plg_destroy_t * destroy)
140    {
141            free(rc);
142            return (0);
143    }
144    
145    
146    static int
147    rc_single_before(rc_single_t * rc,
148                              xvid_plg_data_t * data)
149    {
150             if (data->quant <= 0) {
151                    if (data->zone && data->zone->mode == XVID_ZONE_QUANT) {
152                            rc->fq_error += (double)data->zone->increment / (double)data->zone->base;
153                            data->quant = (int)rc->fq_error;
154                            rc->fq_error -= data->quant;
155                    } else {
156                            int q = rc->rtn_quant;
157                            /* limit to min/max range
158                               we don't know frame type of the next frame, so we just use
159                               P-VOP's range... */
160                            if (q > data->max_quant[XVID_TYPE_PVOP-1])
161                                    q = data->max_quant[XVID_TYPE_PVOP-1];
162                            else if (q < data->min_quant[XVID_TYPE_PVOP-1])
163                                    q = data->min_quant[XVID_TYPE_PVOP-1];
164    
165                            data->quant = q;
166                    }
167            }
168            return 0;
169    }
170    
171    
172    static int
173    rc_single_after(rc_single_t * rc,
174                             xvid_plg_data_t * data)
175    {
176            int64_t deviation;
177            int rtn_quant;
178            double overflow;
179            double averaging_period;
180            double reaction_delay_factor;
181            double quality_scale;
182            double base_quality;
183            double target_quality;
184    
185            /* Update internal values */
186            rc->time += (double) data->fincr / data->fbase;
187            rc->total_size += data->length;
188    
189            if(data->type == XVID_TYPE_BVOP)
190                    return (0);
191    
192            rc->rtn_quant = data->quant;
193    
194            /* Compute the deviation from expected total size */
195            deviation =
196                    rc->total_size - rc->bytes_per_sec * rc->time;
197    
198    
199            if (data->quant >= 2) {
200    
201                    averaging_period = (double) rc->averaging_period;
202    
203                    rc->sequence_quality -= rc->sequence_quality / averaging_period;
204    
205                    rc->sequence_quality +=
206                            2.0 / (double) data->quant / averaging_period;
207    
208                    if (rc->sequence_quality < 0.1)
209                            rc->sequence_quality = 0.1;
210    
211                    if (data->type != XVID_TYPE_IVOP) {
212                            reaction_delay_factor = (double) rc->reaction_delay_factor;
213                            rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;
214                            rc->avg_framesize += data->length / reaction_delay_factor;
215                    }
216    
217            }
218    
219            quality_scale =
220                    rc->target_framesize / rc->avg_framesize * rc->target_framesize /
221                    rc->avg_framesize;
222    
223            base_quality = rc->sequence_quality;
224            if (quality_scale >= 1.0) {
225                    base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
226            } else {
227                    base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
228            }
229    
230            overflow = -((double) deviation / (double) rc->buffer);
231    
232            target_quality =
233                    base_quality + (base_quality -
234                                                    0.06452) * overflow / rc->target_framesize;
235    
236            if (target_quality > 2.0)
237                    target_quality = 2.0;
238            else if (target_quality < 0.06452)
239                    target_quality = 0.06452;
240    
241            rtn_quant = (int) (2.0 / target_quality);
242    
243            if (rtn_quant > 0 && rtn_quant < 31) {
244                    rc->quant_error[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;
245                    if (rc->quant_error[rtn_quant - 1] >= 1.0) {
246                            rc->quant_error[rtn_quant - 1] -= 1.0;
247                            rtn_quant++;
248                    }
249            }
250    
251            /* prevent rapid quantization change */
252            if (rtn_quant > data->quant + 1)
253                    rtn_quant = data->quant + 1;
254            else if (rtn_quant < data->quant - 1)
255                    rtn_quant = data->quant - 1;
256    
257            rc->rtn_quant = rtn_quant;
258    
259            return (0);
260    }
261    
262    
263    
264    int
265    xvid_plugin_single(void *handle,
266                                    int opt,
267                                    void *param1,
268                                    void *param2)
269    {
270            switch (opt) {
271            case XVID_PLG_INFO:
272            case XVID_PLG_FRAME :
273                    return 0;
274    
275            case XVID_PLG_CREATE:
276                    return rc_single_create((xvid_plg_create_t *) param1, param2);
277    
278            case XVID_PLG_DESTROY:
279                    return rc_single_destroy((rc_single_t *) handle,(xvid_plg_destroy_t *) param1);
280    
281            case XVID_PLG_BEFORE:
282                    return rc_single_before((rc_single_t *) handle, (xvid_plg_data_t *) param1);
283    
284            case XVID_PLG_AFTER:
285                    return rc_single_after((rc_single_t *) handle, (xvid_plg_data_t *) param1);
286            }
287    
288            return XVID_ERR_FAIL;
289    }

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

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