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

Diff of /branches/dev-api-4/xvidcore/src/plugins/plugin_2pass2.c

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

revision 1036, Tue May 20 17:28:25 2003 UTC revision 1037, Thu May 22 10:57:33 2003 UTC
# Line 3  Line 3 
3   * XviD Bit Rate Controller Library   * XviD Bit Rate Controller Library
4   * - VBR 2 pass bitrate controler implementation -   * - VBR 2 pass bitrate controler implementation -
5   *   *
6   * Copyright (C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr>   * Copyright (C)      2002 Foxer <email?>
7     *                    2002 Dirk Knop <dknop@gwdg.de>
8     *               2002-2003 Edouard Gomez <ed.gomez@free.fr>
9     *                    2003 Pete Ross <pross@xvid.org>
10   *   *
11   * The curve treatment algorithm is the one implemented by Foxer <email?> and   * This curve treatment algorithm is the one originally implemented by Foxer
12   * Dirk Knop <dknop@gwdg.de> for the XviD vfw dynamic library.   * and tuned by Dirk Knop for the XviD vfw frontend.
13   *   *
14   * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
15   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
# Line 22  Line 25 
25   * along with this program; if not, write to the Free Software   * along with this program; if not, write to the Free Software
26   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27   *   *
28   * $Id: plugin_2pass2.c,v 1.1.2.6 2003-05-20 17:28:25 edgomez Exp $   * $Id: plugin_2pass2.c,v 1.1.2.7 2003-05-22 10:57:33 edgomez Exp $
29   *   *
30   *****************************************************************************/   *****************************************************************************/
31    
# Line 177  Line 180 
180    
181          i++;          i++;
182      }      }
183    
184      rc->num_frames = i;      rc->num_frames = i;
185    
186      fclose(f);      fclose(f);
# Line 231  Line 235 
235              j++;              j++;
236          }          }
237      }      }
238    
239            /*
240             * The "per sequence" overflow system considers a natural sequence to be
241             * formed by all frames between two iframes, so if we want to make sure
242             * the system does not go nuts during last sequence, we force the last
243             * frame to appear in the keyframe locations array.
244             */
245      rc->keyframe_locations[j] = i;      rc->keyframe_locations[j] = i;
246  }  }
247    
# Line 639  Line 650 
650          return XVID_ERR_MEMORY;          return XVID_ERR_MEMORY;
651      }      }
652    
653      /* XXX: do we need an addition location */      /*
654             * We need an extra location because we do as if the last frame were an
655             * IFrame. This is needed because our code consider that frames between
656             * 2 IFrames form a natural sequence. So we store last frame as a
657             * keyframe location.
658             */
659      if ((rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int))) == NULL) {      if ((rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int))) == NULL) {
660          free(rc->stats);          free(rc->stats);
661          free(rc);          free(rc);
# Line 664  Line 680 
680    
681      DPRINTF(XVID_DEBUG_RC, "rc->target : %i\n", rc->target);      DPRINTF(XVID_DEBUG_RC, "rc->target : %i\n", rc->target);
682    
683    #if 0
684          rc->target -= rc->num_frames*24;        /* avi file header */          rc->target -= rc->num_frames*24;        /* avi file header */
685    #endif
686    
687    
688          pre_process0(rc);          pre_process0(rc);
# Line 715  Line 733 
733      double curve_temp;      double curve_temp;
734      int capped_to_max_framesize = 0;      int capped_to_max_framesize = 0;
735    
736      if (data->quant <= 0) {          /*
737             * This function is quite long but easy to understand. In order to simplify
738             * the code path (a bit), we treat 3 cases that can return immediatly.
739             */
740    
741            /* First case: Another plugin has already set a quantizer */
742        if (data->quant > 0)
743                    return(0);
744    
745            /* Second case: We are in a Quant zone */
746          if (s->zone_mode == XVID_ZONE_QUANT) {          if (s->zone_mode == XVID_ZONE_QUANT) {
747    
748              rc->fq_error += s->weight;              rc->fq_error += s->weight;
# Line 725  Line 751 
751    
752              s->desired_length = s->length;              s->desired_length = s->length;
753    
754          }else { /* XVID_ZONE_WEIGHT */                  return(0);
755    
             if (data->frame_num >= rc->num_frames) {  
                 /* insufficent stats data */  
                 return 0;  
756              }              }
757    
758              overflow = rc->overflow / 8;        /* XXX: why by 8 */          /* Third case: insufficent stats data */
759            if (data->frame_num >= rc->num_frames)
760                    return 0;
761    
762            /*
763             * The last case is the one every normal minded developer should fear to
764             * maintain in a project :-)
765             */
766    
767            /* XXX: why by 8 */
768            overflow = rc->overflow / 8;
769    
770              if (s->type == XVID_TYPE_IVOP) {        /* XXX: why */          /*
771             * The rc->overflow field represents the overflow in current scene (between two
772             * IFrames) so we must not forget to reset it if we are enetring a new scene
773             */
774            if (s->type == XVID_TYPE_IVOP) {
775                  overflow = 0;                  overflow = 0;
776              }              }
777    
# Line 746  Line 783 
783              }              }
784              dbytes /= rc->movie_curve;              dbytes /= rc->movie_curve;
785    
786            /*
787             * We are now entering in the hard part of the algo, it was first designed
788             * to work with i/pframes only streams, so the way it computes things is
789             * adapted to pframes only. However we can use it if we just take care to
790             * scale the bframes sizes to pframes sizes using the ratio avg_p/avg_p and
791             * then before really using values depending on frame sizes, scaling the
792             * value again with the inverse ratio
793             */
794              if (s->type == XVID_TYPE_BVOP) {              if (s->type == XVID_TYPE_BVOP) {
795                  dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];                  dbytes *= rc->avg_length[XVID_TYPE_PVOP-1] / rc->avg_length[XVID_TYPE_BVOP-1];
796              }              }
797    
798            /*
799             * Apply user's choosen Payback method. Payback helps bitrate to follow the
800             * scaled curve "paying back" past errors in curve previsions.
801             */
802              if (rc->param.payback_method == XVID_PAYBACK_BIAS) {              if (rc->param.payback_method == XVID_PAYBACK_BIAS) {
803                  desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay);                  desired =(int)(rc->curve_comp_error / rc->param.bitrate_payback_delay);
804              }else{              }else{
                         //printf("desired=%i, dbytes=%i\n", desired,dbytes);  
805                          desired = (int)(rc->curve_comp_error * dbytes /                          desired = (int)(rc->curve_comp_error * dbytes /
806                                  rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay);                                  rc->avg_length[XVID_TYPE_PVOP-1] / rc->param.bitrate_payback_delay);
                         //printf("desired=%i\n", desired);  
807    
808                          if (labs(desired) > fabs(rc->curve_comp_error)) {                          if (labs(desired) > fabs(rc->curve_comp_error)) {
809                                  desired = (int)rc->curve_comp_error;                                  desired = (int)rc->curve_comp_error;
# Line 765  Line 812 
812    
813              rc->curve_comp_error -= desired;              rc->curve_comp_error -= desired;
814    
815              /* alt curve */          /*
816             * Alt curve treatment is not that hard to understand though the formulas
817             * seem to be huge. Alt treatment is basically a way to soft/harden the
818             * curve flux applying sine/linear/cosine ratios
819             */
820    
821              curve_temp = 0; /* XXX: warning */          /* XXX: warning */
822            curve_temp = 0;
823    
824              if (rc->param.use_alt_curve) {              if (rc->param.use_alt_curve) {
825                  if (s->type != XVID_TYPE_IVOP)  {                  if (s->type != XVID_TYPE_IVOP)  {
# Line 802  Line 854 
854                              }                              }
855                                          }                                          }
856                                  }                                  }
857    
858                            /*
859                             * End of code path for curve_temp, as told earlier, we are now
860                             * obliged to scale the value to a bframe one using the inverse
861                             * ratio applied earlier
862                             */
863                                  if (s->type == XVID_TYPE_BVOP)                                  if (s->type == XVID_TYPE_BVOP)
864                                          curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];                                          curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
865    
# Line 810  Line 868 
868                                  desired += ((int)curve_temp);                                  desired += ((int)curve_temp);
869                                  rc->curve_comp_error += curve_temp - (int)curve_temp;                                  rc->curve_comp_error += curve_temp - (int)curve_temp;
870                          }else{                          }else{
871                            /*
872                             * End of code path for dbytes, as told earlier, we are now
873                             * obliged to scale the value to a bframe one using the inverse
874                             * ratio applied earlier
875                             */
876                                  if (s->type == XVID_TYPE_BVOP)                                  if (s->type == XVID_TYPE_BVOP)
877                                          dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];                                          dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
878    
# Line 826  Line 889 
889                      curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);                      curve_temp *= ((double)dbytes + (rc->avg_length[XVID_TYPE_PVOP-1] - dbytes) * rc->param.curve_compression_low / 100.0);
890                  }                  }
891    
892                  if (s->type == XVID_TYPE_BVOP){                  /*
893                     * End of code path for curve_temp, as told earlier, we are now
894                     * obliged to scale the value to a bframe one using the inverse
895                     * ratio applied earlier
896                     */
897                    if (s->type == XVID_TYPE_BVOP)
898                      curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];                      curve_temp *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
                 }  
899    
900                  desired += (int)curve_temp;                  desired += (int)curve_temp;
901                  rc->curve_comp_error += curve_temp - (int)curve_temp;                  rc->curve_comp_error += curve_temp - (int)curve_temp;
902              }else{              }else{
903                    /*
904                     * End of code path for dbytes, as told earlier, we are now
905                     * obliged to scale the value to a bframe one using the inverse
906                     * ratio applied earlier
907                     */
908                  if (s->type == XVID_TYPE_BVOP){                  if (s->type == XVID_TYPE_BVOP){
909                                  dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];                                  dbytes *= rc->avg_length[XVID_TYPE_BVOP-1] / rc->avg_length[XVID_TYPE_PVOP-1];
910                  }                  }
# Line 842  Line 914 
914              }              }
915    
916    
917                  if (desired > s->length) {  /* if desired length exceeds the pass1 length.. */          /*
918             * We can't do bigger frames than first pass, this would be stupid as first
919             * pass is quant=2 and that reaching quant=1 is not worth it. We would lose
920             * many bytes and we would not not gain much quality.
921             */
922            if (desired > s->length) {
923                          rc->curve_comp_error += desired - s->length;                          rc->curve_comp_error += desired - s->length;
924                          desired = s->length;                          desired = s->length;
925                  }else{                  }else{
# Line 885  Line 962 
962    
963              overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]);              overflow = (int)((double)overflow * desired / rc->avg_length[XVID_TYPE_PVOP-1]);
964    
965                  // Foxer: reign in overflow with huge frames          /* Reign in overflow with huge frames */
966                  if (labs(overflow) > labs(rc->overflow)) {                  if (labs(overflow) > labs(rc->overflow)) {
967                          overflow = rc->overflow;                          overflow = rc->overflow;
968                  }                  }
969    
970              // Foxer: make sure overflow doesn't run away          /* Make sure overflow doesn't run away */
   
971                  if (overflow > desired * rc->param.max_overflow_improvement / 100) {                  if (overflow > desired * rc->param.max_overflow_improvement / 100) {
972                          desired += (overflow <= desired) ? desired * rc->param.max_overflow_improvement / 100 :                          desired += (overflow <= desired) ? desired * rc->param.max_overflow_improvement / 100 :
973                                  overflow * rc->param.max_overflow_improvement / 100;                                  overflow * rc->param.max_overflow_improvement / 100;
# Line 901  Line 977 
977                          desired += overflow;                          desired += overflow;
978                  }                  }
979    
980            /* Make sure we are not higher than desired frame size */
981              if (desired > rc->max_length) {              if (desired > rc->max_length) {
982                          capped_to_max_framesize = 1;                          capped_to_max_framesize = 1;
983                          desired = rc->max_length;                          desired = rc->max_length;
984                  }                  }
985    
986              // make sure to not scale below the minimum framesize          /* Make sure to not scale below the minimum framesize */
987              if (desired < rc->min_length[s->type-1]) {          if (desired < rc->min_length[s->type-1])
988                  desired = rc->min_length[s->type-1];                  desired = rc->min_length[s->type-1];
             }  
   
989    
990              // very 'simple' quant<->filesize relationship          /*
991             * Don't laugh at this very 'simple' quant<->filesize relationship, it
992             * proves to be acurate enough for our algorithm
993             */
994              data->quant= (s->quant * s->length) / desired;              data->quant= (s->quant * s->length) / desired;
995    
996            /* Let's clip the computed quantizer, if needed */
997                  if (data->quant < 1) {                  if (data->quant < 1) {
998                          data->quant = 1;                          data->quant = 1;
999              } else if (data->quant > 31) {              } else if (data->quant > 31) {
1000                          data->quant = 31;                          data->quant = 31;
1001                  }          } else if (s->type != XVID_TYPE_IVOP) {
1002                  else if (s->type != XVID_TYPE_IVOP)  
1003                  {                  /*
1004                          // Foxer: aid desired quantizer precision by accumulating decision error                   * The frame quantizer has not been clipped, this appear to be a good
1005                     * computed quantizer, however past frames give us some info about how
1006                     * this quantizer performs against the algo prevision. Let's use this
1007                     * prevision to increase the quantizer when we observe a too big
1008                     * accumulated error
1009                     */
1010                          if (s->type== XVID_TYPE_BVOP) {                          if (s->type== XVID_TYPE_BVOP) {
1011                                  rc->bquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;                                  rc->bquant_error[data->quant] += ((double)(s->quant * s->length) / desired) - data->quant;
1012    
# Line 940  Line 1024 
1024                          }                          }
1025                  }                  }
1026    
1027              /* cap to min/max quant */          /*
1028             * Now we have a computed quant that is in the right quante range, with a
1029             * possible +1 correction due to cumulated error. We can now safely clip
1030             * the quantizer again with user's quant ranges. "Safely" means the Rate
1031             * Control could learn more about this quantizer, this knowledge is useful
1032             * for future frames even if it this quantizer won't be really used atm,
1033             * that's why we don't perform this clipping earlier.
1034             */
1035              if (data->quant < data->min_quant[s->type-1]) {              if (data->quant < data->min_quant[s->type-1]) {
1036                  data->quant = data->min_quant[s->type-1];                  data->quant = data->min_quant[s->type-1];
1037              }else if (data->quant > data->max_quant[s->type-1]) {              }else if (data->quant > data->max_quant[s->type-1]) {
1038                  data->quant = data->max_quant[s->type-1];                  data->quant = data->max_quant[s->type-1];
1039              }              }
1040    
1041              /* subsequent p/b frame quants can only be +- 2 */          /*
1042             * To avoid big quality jumps from frame to frame, we apply a "security"
1043             * rule that makes |last_quant - new_quant| <= 2. This rule only applies
1044             * to predicted frames (P and B)
1045             */
1046                  if (s->type != XVID_TYPE_IVOP && rc->last_quant[s->type-1] && capped_to_max_framesize == 0) {                  if (s->type != XVID_TYPE_IVOP && rc->last_quant[s->type-1] && capped_to_max_framesize == 0) {
1047    
1048                          if (data->quant > rc->last_quant[s->type-1] + 2) {                          if (data->quant > rc->last_quant[s->type-1] + 2) {
# Line 961  Line 1055 
1055                          }                          }
1056                  }                  }
1057    
1058            /*
1059             * We don't want to pollute the RC history results when our computed quant
1060             * has been computed from a capped frame size
1061             */
1062                  if (capped_to_max_framesize == 0) {                  if (capped_to_max_framesize == 0) {
1063                  rc->last_quant[s->type-1] = data->quant;                  rc->last_quant[s->type-1] = data->quant;
1064                  }                  }
1065    
   
         }   /* if */  
   
     }  
   
1066      return 0;      return 0;
1067  }  }
1068    
# Line 979  Line 1072 
1072  {  {
1073      stat_t * s = &rc->stats[data->frame_num];      stat_t * s = &rc->stats[data->frame_num];
1074    
1075      if (data->frame_num >= rc->num_frames) {          /* Insufficent stats data */
1076          /* insufficent stats data */      if (data->frame_num >= rc->num_frames)
1077          return 0;          return 0;
     }  
1078    
1079      rc->quant_count[data->quant]++;      rc->quant_count[data->quant]++;
1080    

Legend:
Removed from v.1036  
changed lines
  Added in v.1037

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