[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.2.2, Sat May 17 13:36:38 2003 UTC revision 1.4, Tue Mar 9 10:00:14 2010 UTC
# Line 1  Line 1 
1  /*****************************************************************************  /*****************************************************************************
2   *   *
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 30  Line 30 
30  #include "../xvid.h"  #include "../xvid.h"
31  #include "../image/image.h"  #include "../image/image.h"
32    
33  #define DEFAULT_INITIAL_QUANTIZER 5  #define DEFAULT_INITIAL_QUANTIZER 8
34    
35  #define DEFAULT_BITRATE 900000  /* 900kbps */  #define DEFAULT_BITRATE 900000  /* 900kbps */
36  #define DEFAULT_DELAY_FACTOR 16  #define DEFAULT_DELAY_FACTOR 16
# Line 153  Line 153 
153              data->quant = (int)rc->fq_error;              data->quant = (int)rc->fq_error;
154              rc->fq_error -= data->quant;              rc->fq_error -= data->quant;
155          }else {          }else {
156                  data->quant = rc->rtn_quant;                          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;          return 0;
# Line 173  Line 182 
182          double base_quality;          double base_quality;
183          double target_quality;          double target_quality;
184    
   
185          /* Update internal values */          /* Update internal values */
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    
189          /* Compute the deviation from expected total size */          /* Compute the deviation from expected total size */
190          deviation = (int64_t)          deviation =
191                  ((double) rc->total_size - (double) rc->bytes_per_sec * rc->time);                  rc->total_size - rc->bytes_per_sec * rc->time;
   
   
         if (data->quant >= 2) {  
192    
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 216  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 227  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      /* limit to min/max range */                                  rtn_quant = rc->rtn_quant + 2;
280          if (rtn_quant > data->max_quant[data->type-1])                  else
281                  rtn_quant = data->max_quant[data->type-1];                          rtn_quant = rc->rtn_quant + 1;
282          else if (rtn_quant < data->min_quant[data->type-1])          }
283                  rtn_quant = data->min_quant[data->type-1];          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    
# Line 262  Line 305 
305  {  {
306          switch (opt) {          switch (opt) {
307          case XVID_PLG_INFO:          case XVID_PLG_INFO:
308            case XVID_PLG_FRAME :
309                  return 0;                  return 0;
310    
311          case XVID_PLG_CREATE:          case XVID_PLG_CREATE:

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.4

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