[svn] / branches / dev-api-4 / xvidcore / src / plugins / plugin_cbr.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/plugins/plugin_cbr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 938 - (view) (download)

1 : suxen_drol 938 /*****************************************************************************
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: plugin_cbr.c,v 1.1.2.1 2003-03-23 04:03:01 suxen_drol Exp $
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 :    

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