[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 1308, Wed Jan 7 13:51:02 2004 UTC revision 1309, Wed Jan 7 13:51:24 2004 UTC
# Line 25  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.33 2003-12-21 17:38:17 edgomez Exp $   * $Id: plugin_2pass2.c,v 1.1.2.34 2004-01-07 13:51:24 edgomez Exp $
29   *   *
30   *****************************************************************************/   *****************************************************************************/
31    
# Line 130  Line 130 
130    
131          /*----------------------------------          /*----------------------------------
132           * Zones statistical data           * Zones statistical data
          *  
          * ToDo: Fix zones, current  
          *       implementation is buggy  
133           *--------------------------------*/           *--------------------------------*/
134    
         /* Average weight of the zones */  
         double avg_weight;  
   
135          /* Total length used by XVID_ZONE_QUANT zones */          /* Total length used by XVID_ZONE_QUANT zones */
136          uint64_t tot_quant;          uint64_t tot_quant;
137          uint64_t tot_quant_invariant;          uint64_t tot_quant_invariant;
138    
139            /* Holds the total amount of frame bytes, zone weighted (only scalable
140             * part of frame bytes) */
141            uint64_t tot_weighted;
142    
143          /*----------------------------------          /*----------------------------------
144           * Advanced settings helper ratios           * Advanced settings helper ratios
145           *--------------------------------*/           *--------------------------------*/
# Line 375  Line 373 
373          if(rc->param.container_frame_overhead)          if(rc->param.container_frame_overhead)
374                  DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- New target filesize after container compensation: %lld\n", rc->target);                  DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- New target filesize after container compensation: %lld\n", rc->target);
375    
376            /* When bitrate is not given it means it has been scaled by an external
377             * application */
378            if (rc->param.bitrate) {
379                    /* Apply zone settings
380                     * - set rc->tot_quant which represents the total num of bytes spent in
381                     *   fixed quant zones
382                     * - set rc->tot_weighted which represents the total amount of bytes
383                     *   spent in normal or weighted zones in first pass (normal zones can
384                     *   be considered weight=1)
385                     * - set rc->tot_quant_invariant which represents the total num of bytes
386                     *   spent in fixed quant zones for headers */
387                    zone_process(rc, create);
388            } else {
389                    /* External scaling -- zones are ignored */
390                    for (i=0;i<rc->num_frames;i++) {
391                            rc->stats[i].zone_mode = XVID_ZONE_WEIGHT;
392                            rc->stats[i].weight = 1.0;
393                    }
394                    rc->tot_quant = 0;
395            }
396    
397          /* Gathers some information about first pass stats:          /* Gathers some information about first pass stats:
398           *  - finds the minimum frame length for each frame type during 1st pass.           *  - finds the minimum frame length for each frame type during 1st pass.
399           *     rc->min_size[]           *     rc->min_size[]
# Line 390  Line 409 
409           */           */
410          first_pass_stats_prepare_data(rc);          first_pass_stats_prepare_data(rc);
411    
412          /* When bitrate is not given it means it has been scaled by an external          /* If we have a user bitrate, it means it's an internal curve scaling */
          * application */  
413          if (rc->param.bitrate) {          if (rc->param.bitrate) {
                 /* Apply zone settings  
                  * - set rc->tot_quant which represents the total num of bytes spent in  
                  *   fixed quant zones  
                  * - set rc->tot_quant_invariant which represents the total num of bytes spent  
                  *   in fixed quant zones for headers */  
                 zone_process(rc, create);  
414                  /* Perform internal curve scaling */                  /* Perform internal curve scaling */
415                  first_pass_scale_curve_internal(rc);                  first_pass_scale_curve_internal(rc);
         } else {  
                 /* External scaling -- zones are ignored */  
                 for (i=0;i<rc->num_frames;i++) {  
                         rc->stats[i].zone_mode = XVID_ZONE_WEIGHT;  
                         rc->stats[i].weight = 1.0;  
                 }  
                 rc->avg_weight = 1.0;  
                 rc->tot_quant = 0;  
416          }          }
417    
418          /* Apply advanced curve options, and compute some parameters in order to          /* Apply advanced curve options, and compute some parameters in order to
# Line 984  Line 988 
988    
989  /* pre-process the statistics data  /* pre-process the statistics data
990   * - for each type, count, tot_length, min_length, max_length   * - for each type, count, tot_length, min_length, max_length
991   * - set keyframes_locations */   * - set keyframes_locations, tot_prescaled */
992  static void  static void
993  first_pass_stats_prepare_data(rc_2pass2_t * rc)  first_pass_stats_prepare_data(rc_2pass2_t * rc)
994  {  {
# Line 1001  Line 1005 
1005          }          }
1006    
1007          rc->max_length = INT_MIN;          rc->max_length = INT_MIN;
1008            rc->tot_weighted = 0;
1009    
1010          /* Loop through all frames and find/compute all the stuff this function          /* Loop through all frames and find/compute all the stuff this function
1011           * is supposed to do */           * is supposed to do */
# Line 1010  Line 1015 
1015                  rc->count[s->type-1]++;                  rc->count[s->type-1]++;
1016                  rc->tot_length[s->type-1] += s->length;                  rc->tot_length[s->type-1] += s->length;
1017                  rc->tot_invariant[s->type-1] += s->invariant;                  rc->tot_invariant[s->type-1] += s->invariant;
1018                    if (s->zone_mode != XVID_ZONE_QUANT)
1019                            rc->tot_weighted += (int)(s->weight*(s->length - s->invariant));
1020    
1021                  if (s->length < rc->min_length[s->type-1]) {                  if (s->length < rc->min_length[s->type-1]) {
1022                          rc->min_length[s->type-1] = s->length;                          rc->min_length[s->type-1] = s->length;
# Line 1044  Line 1051 
1051          int i,j;          int i,j;
1052          int n = 0;          int n = 0;
1053    
         rc->avg_weight = 0.0;  
1054          rc->tot_quant = 0;          rc->tot_quant = 0;
1055          rc->tot_quant_invariant = 0;          rc->tot_quant_invariant = 0;
1056    
# Line 1053  Line 1059 
1059                          rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;                          rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;
1060                          rc->stats[j].weight = 1.0;                          rc->stats[j].weight = 1.0;
1061                  }                  }
                 rc->avg_weight += rc->num_frames * 1.0;  
1062                  n += rc->num_frames;                  n += rc->num_frames;
1063          }          }
1064    
# Line 1062  Line 1067 
1067    
1068                  int next = (i+1<create->num_zones) ? create->zones[i+1].frame : rc->num_frames;                  int next = (i+1<create->num_zones) ? create->zones[i+1].frame : rc->num_frames;
1069    
1070                    /* Zero weight make no sense */
1071                    if (create->zones[i].increment == 0) create->zones[i].increment = 1;
1072                    /* And obviously an undetermined infinite makes even less sense */
1073                    if (create->zones[i].base == 0) create->zones[i].base = 1;
1074    
1075                  if (i==0 && create->zones[i].frame > 0) {                  if (i==0 && create->zones[i].frame > 0) {
1076                          for (j = 0; j < create->zones[i].frame && j < rc->num_frames; j++) {                          for (j = 0; j < create->zones[i].frame && j < rc->num_frames; j++) {
1077                                  rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;                                  rc->stats[j].zone_mode = XVID_ZONE_WEIGHT;
1078                                  rc->stats[j].weight = 1.0;                                  rc->stats[j].weight = 1.0;
1079                          }                          }
                         rc->avg_weight += create->zones[i].frame * 1.0;  
1080                          n += create->zones[i].frame;                          n += create->zones[i].frame;
1081                  }                  }
1082    
# Line 1077  Line 1086 
1086                                  rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;                                  rc->stats[j].weight = (double)create->zones[i].increment / (double)create->zones[i].base;
1087                          }                          }
1088                          next -= create->zones[i].frame;                          next -= create->zones[i].frame;
                         rc->avg_weight += (double)(next * create->zones[i].increment) / (double)create->zones[i].base;  
1089                          n += next;                          n += next;
1090                  } else{  /* XVID_ZONE_QUANT */                  } else{  /* XVID_ZONE_QUANT */
1091                          for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {                          for (j = create->zones[i].frame; j < next && j < rc->num_frames; j++ ) {
# Line 1088  Line 1096 
1096                          }                          }
1097                  }                  }
1098          }          }
         rc->avg_weight = n>0 ? rc->avg_weight/n : 1.0;  
   
         DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- center_weight:%f (for %d frames)  fixed_bytes:%d\n", rc->avg_weight, n, rc->tot_quant);  
1099  }  }
1100    
1101    
# Line 1099  Line 1104 
1104  first_pass_scale_curve_internal(rc_2pass2_t *rc)  first_pass_scale_curve_internal(rc_2pass2_t *rc)
1105  {  {
1106          int64_t target;          int64_t target;
         int64_t pass1_length;  
1107          int64_t total_invariant;          int64_t total_invariant;
1108          double scaler;          double scaler;
1109          int i, num_MBs;          int i, num_MBs;
# Line 1118  Line 1122 
1122          target  = rc->target;          target  = rc->target;
1123          target -= rc->tot_quant;          target -= rc->tot_quant;
1124    
         /* Do the same for the first pass data */  
         pass1_length  = rc->tot_length[XVID_TYPE_IVOP-1];  
         pass1_length += rc->tot_length[XVID_TYPE_PVOP-1];  
         pass1_length += rc->tot_length[XVID_TYPE_BVOP-1];  
         pass1_length -= rc->tot_quant;  
   
1125          /* Let's compute a linear scaler in order to perform curve scaling */          /* Let's compute a linear scaler in order to perform curve scaling */
1126          scaler = (double)(target - total_invariant) / (double)(pass1_length - total_invariant);          scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted);
   
 #ifdef PASS_SMALLER  
         if ((target - total_invariant) <= 0 ||  
                 (pass1_length - total_invariant) <= 0 ||  
                 target >= pass1_length) {  
                 DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- WARNING: Undersize detected before correction\n");  
                 scaler = 1.0;  
         }  
 #endif  
1127    
1128          /* Compute min frame lengths (for each frame type) according to the number          /* Compute min frame lengths (for each frame type) according to the number
1129           * of MBs. We sum all block type counters of frame 0, this gives us the           * of MBs. We sum all block type counters of frame 0, this gives us the
# Line 1177  Line 1166 
1166                  }                  }
1167    
1168                  /* Compute the scaled length -- only non invariant data length is scaled */                  /* Compute the scaled length -- only non invariant data length is scaled */
1169                  len = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight / rc->avg_weight);                  len = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight);
1170    
1171                  /* Compare with the computed minimum */                  /* Compare with the computed minimum */
1172                  if (len < rc->min_length[s->type-1]) {                  if (len < rc->min_length[s->type-1]) {
# Line 1189  Line 1178 
1178                           * total counters, as we prepare a second pass for 'regular'                           * total counters, as we prepare a second pass for 'regular'
1179                           * frames */                           * frames */
1180                          target -= s->scaled_length;                          target -= s->scaled_length;
                         pass1_length -= s->length;  
1181                  } else {                  } else {
1182                          /* Do nothing for now, we'll scale this later */                          /* Do nothing for now, we'll scale this later */
1183                          s->scaled_length = 0;                          s->scaled_length = 0;
# Line 1200  Line 1188 
1188           * total counters. Now, it's possible to scale the 'regular' frames. */           * total counters. Now, it's possible to scale the 'regular' frames. */
1189    
1190          /* Scaling factor for 'regular' frames */          /* Scaling factor for 'regular' frames */
1191          scaler = (double)(target - total_invariant) / (double)(pass1_length - total_invariant);          scaler = (double)(target - total_invariant) / (double)(rc->tot_weighted);
   
 #ifdef PASS_SMALLER  
         /* Detect undersizing */  
         if (target <= 0 || pass1_length <= 0 || target >= pass1_length) {  
                 DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- WARNING: Undersize detected after correction\n");  
                 scaler = 1.0;  
         }  
 #endif  
1192    
1193          /* Do another pass with the new scaler */          /* Do another pass with the new scaler */
1194          for (i=0; i<rc->num_frames; i++) {          for (i=0; i<rc->num_frames; i++) {
# Line 1216  Line 1196 
1196    
1197                  /* Ignore frame with forced frame sizes */                  /* Ignore frame with forced frame sizes */
1198                  if (s->scaled_length == 0)                  if (s->scaled_length == 0)
1199                          s->scaled_length = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight / rc->avg_weight);                          s->scaled_length = s->invariant + (int)((double)(s->length-s->invariant) * scaler * s->weight);
1200          }          }
1201    
1202          /* Job done */          /* Job done */

Legend:
Removed from v.1308  
changed lines
  Added in v.1309

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