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

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

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

revision 1382, Mon Mar 22 22:36:25 2004 UTC revision 1531, Tue Aug 10 22:34:32 2004 UTC
# Line 3  Line 3 
3   *  XviD Standard Plugins   *  XviD Standard Plugins
4   *  - single-pass bitrate controller implementation -   *  - single-pass bitrate controller implementation -
5   *   *
6   *  Copyright(C) 2002      Benjamin Lambert <foxer@hotmail.com>   *  Copyright(C) 2002-2004 Benjamin Lambert <foxer@hotmail.com>
7   *               2002-2003 Edouard Gomez <ed.gomez@free.fr>   *               2002-2003 Edouard Gomez <ed.gomez@free.fr>
8   *   *
9   *  This program is free software; you can redistribute it and/or modify   *  This program is free software; you can redistribute it and/or modify
# Line 20  Line 20 
20   *  along with this program; if not, write to the Free Software   *  along with this program; if not, write to the Free Software
21   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22   *   *
23   * $Id: plugin_single.c,v 1.2 2004-03-22 22:36:24 edgomez Exp $   * $Id: plugin_single.c,v 1.3 2004-08-10 22:34:32 edgomez Exp $
24   *   *
25   ****************************************************************************/   ****************************************************************************/
26    
# Line 186  Line 186 
186          rc->time += (double) data->fincr / data->fbase;          rc->time += (double) data->fincr / data->fbase;
187          rc->total_size += data->length;          rc->total_size += data->length;
188    
         if(data->type == XVID_TYPE_BVOP)  
                 return (0);  
   
         rc->rtn_quant = data->quant;  
   
189          /* Compute the deviation from expected total size */          /* Compute the deviation from expected total size */
190          deviation =          deviation =
191                  rc->total_size - rc->bytes_per_sec * rc->time;                  rc->total_size - rc->bytes_per_sec * rc->time;
192    
   
         if (data->quant >= 2) {  
   
193                  averaging_period = (double) rc->averaging_period;                  averaging_period = (double) rc->averaging_period;
194    
195            /* calculate the sequence quality */
196                  rc->sequence_quality -= rc->sequence_quality / averaging_period;                  rc->sequence_quality -= rc->sequence_quality / averaging_period;
197    
198                  rc->sequence_quality +=                  rc->sequence_quality +=
199                          2.0 / (double) data->quant / averaging_period;                          2.0 / (double) data->quant / averaging_period;
200    
201            /* clamp the sequence quality to 10% to 100%
202             * to try to avoid using the highest
203             * and lowest quantizers 'too' much */
204                  if (rc->sequence_quality < 0.1)                  if (rc->sequence_quality < 0.1)
205                          rc->sequence_quality = 0.1;                          rc->sequence_quality = 0.1;
206            else if (rc->sequence_quality > 1.0)
207                    rc->sequence_quality = 1.0;
208    
209            /* factor this frame's size into the average framesize
210             * but skip using ivops as they are usually very large
211             * and as such, usually disrupt quantizer distribution */
212                  if (data->type != XVID_TYPE_IVOP) {                  if (data->type != XVID_TYPE_IVOP) {
213                          reaction_delay_factor = (double) rc->reaction_delay_factor;                          reaction_delay_factor = (double) rc->reaction_delay_factor;
214                          rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;                          rc->avg_framesize -= rc->avg_framesize / reaction_delay_factor;
215                          rc->avg_framesize += data->length / reaction_delay_factor;                          rc->avg_framesize += data->length / reaction_delay_factor;
216                  }                  }
217    
218          }          /* don't change the quantizer between pvops */
219            if (data->type == XVID_TYPE_BVOP)
220                    return (0);
221    
222            /* calculate the quality_scale which will be used
223             * to drag the target quality up or down, depending
224             * on if avg_framesize is >= target_framesize */
225          quality_scale =          quality_scale =
226                  rc->target_framesize / rc->avg_framesize * rc->target_framesize /                  rc->target_framesize / rc->avg_framesize *
227                  rc->avg_framesize;                  rc->target_framesize / rc->avg_framesize;
228    
229            /* use the current sequence_quality as the
230             * base_quality which will be dragged around
231             *
232             * 0.06452 = 6.452% quality (quant:31) */
233          base_quality = rc->sequence_quality;          base_quality = rc->sequence_quality;
234          if (quality_scale >= 1.0) {          if (quality_scale >= 1.0) {
235                  base_quality = 1.0 - (1.0 - base_quality) / quality_scale;                  base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
# Line 229  Line 239 
239    
240          overflow = -((double) deviation / (double) rc->buffer);          overflow = -((double) deviation / (double) rc->buffer);
241    
242            /* clamp overflow to 1 buffer unit to avoid very
243             * large bursts of bitrate following still scenes */
244            if (overflow > rc->target_framesize)
245                    overflow = rc->target_framesize;
246            else if (overflow < -rc->target_framesize)
247                    overflow = -rc->target_framesize;
248    
249            /* apply overflow / buffer to get the target_quality */
250          target_quality =          target_quality =
251                  base_quality + (base_quality -                  base_quality + (base_quality -
252                                                  0.06452) * overflow / rc->target_framesize;                                                  0.06452) * overflow / rc->target_framesize;
253    
254            /* clamp the target_quality to quant 1-31
255             * 2.0 = 200% quality (quant:1) */
256          if (target_quality > 2.0)          if (target_quality > 2.0)
257                  target_quality = 2.0;                  target_quality = 2.0;
258          else if (target_quality < 0.06452)          else if (target_quality < 0.06452)
# Line 240  Line 260 
260    
261          rtn_quant = (int) (2.0 / target_quality);          rtn_quant = (int) (2.0 / target_quality);
262    
263            /* accumulate quant <-> quality error and apply if >= 1.0 */
264          if (rtn_quant > 0 && rtn_quant < 31) {          if (rtn_quant > 0 && rtn_quant < 31) {
265                  rc->quant_error[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;                  rc->quant_error[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;
266                  if (rc->quant_error[rtn_quant - 1] >= 1.0) {                  if (rc->quant_error[rtn_quant - 1] >= 1.0) {
267                          rc->quant_error[rtn_quant - 1] -= 1.0;                          rc->quant_error[rtn_quant - 1] -= 1.0;
268                          rtn_quant++;                          rtn_quant++;
269                            rc->rtn_quant++;
270                  }                  }
271          }          }
272    
273          /* prevent rapid quantization change */          /* prevent rapid quantization change */
274          if (rtn_quant > data->quant + 1)          if (rtn_quant > rc->rtn_quant + 1) {
275                  rtn_quant = data->quant + 1;                  if (rtn_quant > rc->rtn_quant + 3)
276          else if (rtn_quant < data->quant - 1)                          if (rtn_quant > rc->rtn_quant + 5)
277                  rtn_quant = data->quant - 1;                                  rtn_quant = rc->rtn_quant + 3;
278                            else
279                                    rtn_quant = rc->rtn_quant + 2;
280                    else
281                            rtn_quant = rc->rtn_quant + 1;
282            }
283            else if (rtn_quant < rc->rtn_quant - 1) {
284                    if (rtn_quant < rc->rtn_quant - 3)
285                            if (rtn_quant < rc->rtn_quant - 5)
286                                    rtn_quant = rc->rtn_quant - 3;
287                            else
288                                    rtn_quant = rc->rtn_quant - 2;
289                    else
290                            rtn_quant = rc->rtn_quant - 1;
291            }
292    
293          rc->rtn_quant = rtn_quant;          rc->rtn_quant = rtn_quant;
294    

Legend:
Removed from v.1382  
changed lines
  Added in v.1531

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