[svn] / trunk / vfw / src / 2pass.c Repository:
ViewVC logotype

Diff of /trunk/vfw/src/2pass.c

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

revision 102, Fri Apr 5 14:42:37 2002 UTC revision 482, Thu Sep 12 21:18:49 2002 UTC
# Line 23  Line 23 
23   *   *
24   *      History:   *      History:
25   *   *
26     *      17.04.2002      changed 1st pass quant to always be 2 (2pass_update())
27     *      07.04.2002      added max bitrate constraint, overflow controls (foxer)
28   *      31.03.2002      inital version;   *      31.03.2002      inital version;
29   *   *
30   *************************************************************************/   *************************************************************************/
# Line 159  Line 161 
161                                  {                                  {
162                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)                                          if (twopass->nns1.quant & NNSTATS_KEYFRAME)
163                                          {                                          {
164                                                  i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100;                                                  i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100;
165                                                  i_total += twopass->nns2.bytes;                                                  i_total += twopass->nns2.bytes;
166                                                    twopass->keyframe_locations[i_frames] = frames;
167                                                  ++i_frames;                                                  ++i_frames;
168                                          }                                          }
169    
# Line 172  Line 175 
175    
176                                  ++frames;                                  ++frames;
177                          }                          }
178                            twopass->keyframe_locations[i_frames] = frames;
179    
180                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);                          twopass->movie_curve = ((double)(total_ext + i_boost_total) / total_ext);
181                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);                          twopass->average_frame = ((double)(total_ext - i_total) / (frames - credits_frames - i_frames) / twopass->movie_curve);
# Line 369  Line 373 
373                                  {                                  {
374                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          i_total += twopass->nns1.bytes + twopass->nns1.bytes * codec->config.keyframe_boost / 100;
375                                          total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;                                          total += twopass->nns1.bytes * codec->config.keyframe_boost / 100;
376                                            twopass->keyframe_locations[i_frames] = frames;
377                                          ++i_frames;                                          ++i_frames;
378                                  }                                  }
379    
# Line 376  Line 381 
381    
382                                  ++frames;                                  ++frames;
383                          }                          }
384                            twopass->keyframe_locations[i_frames] = frames;
385    
386                          // compensate for avi frame overhead                          // compensate for avi frame overhead
387                          desired -= frames * 24;                          desired -= frames * 24;
# Line 680  Line 686 
686                  }                  }
687    
688                  twopass->overflow = 0;                  twopass->overflow = 0;
689                    twopass->KFoverflow = 0;
690                    twopass->KFoverflow_partial = 0;
691                    twopass->KF_idx = 1;
692    
693                  break;                  break;
694          }          }
# Line 700  Line 709 
709          int bytes1, bytes2;          int bytes1, bytes2;
710          int overflow;          int overflow;
711          int credits_pos;          int credits_pos;
712            int capped_to_max_framesize = 0;
713            int KFdistance, KF_min_size;
714    
715          if (codec->framenum == 0)          if (codec->framenum == 0)
716          {          {
# Line 708  Line 719 
719                  for (i=0 ; i<32 ; ++i)                  for (i=0 ; i<32 ; ++i)
720                  {                  {
721                          quant_error[i] = 0.0;                          quant_error[i] = 0.0;
722                            twopass->quant_count[i] = 0;
723                  }                  }
724    
725                  curve_comp_error = 0.0;                  curve_comp_error = 0.0;
# Line 782  Line 794 
794                  }                  }
795                  else    // DLG_MODE_2PASS_2_EXT                  else    // DLG_MODE_2PASS_2_EXT
796                  {                  {
797                            if (codec->config.credits_mode == CREDITS_MODE_QUANT)
798                            {
799                                    if (codec->config.credits_quant_i != codec->config.credits_quant_p)
800                                    {
801                                            frame->quant = frame->intra ?
802                                                    codec->config.credits_quant_i :
803                                                    codec->config.credits_quant_p;
804                                    }
805                                    else
806                                    {
807                                            frame->quant = codec->config.credits_quant_p;
808                                            frame->intra = -1;
809                                    }
810    
811                                    twopass->bytes1 = bytes1;
812                                    twopass->bytes2 = bytes1;
813                                    twopass->desired_bytes2 = bytes1;
814                                    return ICERR_OK;
815                            }
816                            else
817                          bytes2 = twopass->nns2.bytes;                          bytes2 = twopass->nns2.bytes;
818                  }                  }
819          }          }
# Line 918  Line 950 
950    
951          twopass->desired_bytes2 = bytes2;          twopass->desired_bytes2 = bytes2;
952    
953            // if this keyframe is too close to the next,
954            // reduce it's byte allotment
955            if (frame->intra && !credits_pos)
956            {
957                    KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
958                            codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1];
959    
960                    if (KFdistance < codec->config.kftreshold)
961                    {
962                            KFdistance = KFdistance - codec->config.min_key_interval;
963    
964                            if (KFdistance >= 0)
965                            {
966                                    KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100;
967                                    if (KF_min_size < 1)
968                                            KF_min_size = 1;
969    
970                                    bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance /
971                                            (codec->config.kftreshold - codec->config.min_key_interval);
972    
973                                    if (bytes2 < 1)
974                                            bytes2 = 1;
975                            }
976                    }
977            }
978    
979          // Foxer: scale overflow in relation to average size, so smaller frames don't get          // Foxer: scale overflow in relation to average size, so smaller frames don't get
980          // too much/little bitrate          // too much/little bitrate
981          overflow = (int)((double)overflow * bytes2 / twopass->average_frame);          overflow = (int)((double)overflow * bytes2 / twopass->average_frame);
# Line 929  Line 987 
987          }          }
988    
989          // Foxer: make sure overflow doesn't run away          // Foxer: make sure overflow doesn't run away
990          if (overflow > bytes2 * 6 / 10)          if (overflow > bytes2 * codec->config.twopass_max_overflow_improvement / 100)
991          {          {
992                  bytes2 += (overflow <= bytes2) ? bytes2 * 6 / 10 : overflow * 6 / 10;                  bytes2 += (overflow <= bytes2) ? bytes2 * codec->config.twopass_max_overflow_improvement / 100 :
993                            overflow * codec->config.twopass_max_overflow_improvement / 100;
994          }          }
995          else if (overflow < bytes2 * -6 / 10)          else if (overflow < bytes2 * codec->config.twopass_max_overflow_degradation / -100)
996          {          {
997                  bytes2 += bytes2 * -6 / 10;                  bytes2 += bytes2 * codec->config.twopass_max_overflow_degradation / -100;
998          }          }
999          else          else
1000          {          {
1001                  bytes2 += overflow;                  bytes2 += overflow;
1002          }          }
1003    
1004            if (bytes2 > twopass->max_framesize)
1005            {
1006                    capped_to_max_framesize = 1;
1007                    bytes2 = twopass->max_framesize;
1008            }
1009    
1010          if (bytes2 < 1)          if (bytes2 < 1)
1011          {          {
1012                  bytes2 = 1;                  bytes2 = 1;
# Line 1005  Line 1070 
1070                  }                  }
1071    
1072                  // subsequent frame quants can only be +- 2                  // subsequent frame quants can only be +- 2
1073                  if (last_quant)                  if (last_quant && capped_to_max_framesize == 0)
1074                  {                  {
1075                          if (frame->quant > last_quant + 2)                          if (frame->quant > last_quant + 2)
1076                          {                          {
# Line 1020  Line 1085 
1085                  }                  }
1086          }          }
1087    
1088            if (capped_to_max_framesize == 0)
1089          last_quant = frame->quant;          last_quant = frame->quant;
1090    
1091          if (codec->config.quant_type == QUANT_MODE_MOD)          if (codec->config.quant_type == QUANT_MODE_MOD)
# Line 1038  Line 1104 
1104    
1105          NNSTATS nns1;          NNSTATS nns1;
1106          DWORD wrote;          DWORD wrote;
1107            int credits_pos, tempdiv;
1108          char* quant_type;          char* quant_type;
1109    
1110          if (codec->framenum == 0)          if (codec->framenum == 0)
# Line 1060  Line 1127 
1127                  nns1.md_u = nns1.md_y = 0;                  nns1.md_u = nns1.md_y = 0;
1128                  nns1.mk_u = nns1.mk_y = 0;                  nns1.mk_u = nns1.mk_y = 0;
1129    
1130                  nns1.quant = stats->quant;  //              nns1.quant = stats->quant;
1131                    nns1.quant = 2;                         // ugly fix for lumi masking in 1st pass returning new quant
1132                  if (frame->intra)                  if (frame->intra)
1133                  {                  {
1134                          nns1.quant |= NNSTATS_KEYFRAME;                          nns1.quant |= NNSTATS_KEYFRAME;
# Line 1083  Line 1151 
1151    
1152          case DLG_MODE_2PASS_2_INT :          case DLG_MODE_2PASS_2_INT :
1153          case DLG_MODE_2PASS_2_EXT :          case DLG_MODE_2PASS_2_EXT :
1154                    credits_pos = codec_is_in_credits(&codec->config, codec->framenum);
1155                    if (!credits_pos)
1156                    {
1157                            codec->twopass.quant_count[frame->quant]++;
1158                            if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME))
1159                            {
1160                                    // calculate how much to distribute per frame in
1161                                    // order to make up for this keyframe's overflow
1162    
1163                                    codec->twopass.overflow += codec->twopass.KFoverflow;
1164                                    codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length;
1165    
1166                                    tempdiv = (codec->twopass.keyframe_locations[codec->twopass.KF_idx] -
1167                                            codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]);
1168    
1169                                    if (tempdiv > 1)
1170                                    {
1171                                            // non-consecutive keyframes
1172                                            codec->twopass.KFoverflow_partial = codec->twopass.KFoverflow / (tempdiv - 1);
1173                                    }
1174                                    else
1175                                    {
1176                                            // consecutive keyframes
1177                                            codec->twopass.overflow += codec->twopass.KFoverflow;
1178                                            codec->twopass.KFoverflow = 0;
1179                                            codec->twopass.KFoverflow_partial = 0;
1180                                    }
1181                                    codec->twopass.KF_idx++;
1182                            }
1183                            else
1184                            {
1185                                    // distribute part of the keyframe overflow
1186    
1187                                    codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length +
1188                                            codec->twopass.KFoverflow_partial;
1189                                    codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;
1190                            }
1191                    }
1192                    else
1193                    {
1194                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;                  codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length;
1195                  DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum))  
1196                            // ugly fix for credits..
1197                            codec->twopass.overflow += codec->twopass.KFoverflow;
1198                            codec->twopass.KFoverflow = 0;
1199                            codec->twopass.KFoverflow_partial = 0;
1200                            // end of ugly fix.
1201                    }
1202    
1203                    DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, credits_pos)
1204                  break;                  break;
1205    
1206          default:          default:
# Line 1094  Line 1210 
1210          return ICERR_OK;          return ICERR_OK;
1211  }  }
1212    
1213    void codec_2pass_finish(CODEC* codec)
1214    {
1215            int i;
1216            char s[100];
1217            if (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT)
1218            {
1219                    // output the quantizer distribution for this encode.
1220    
1221                    OutputDebugString("Quantizer distribution for 2nd pass:");
1222                    for (i=1; i<=31; i++)
1223                    {
1224                            if (codec->twopass.quant_count[i])
1225                            {
1226                                    wsprintf(s, "Q:%i:%i", i, codec->twopass.quant_count[i]);
1227                                    OutputDebugString(s);
1228                            }
1229                    }
1230                    return;
1231            }
1232    }

Legend:
Removed from v.102  
changed lines
  Added in v.482

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