--- trunk/vfw/src/2pass.c 2002/07/26 19:58:22 342 +++ trunk/vfw/src/2pass.c 2002/09/12 21:18:49 482 @@ -161,7 +161,7 @@ { if (twopass->nns1.quant & NNSTATS_KEYFRAME) { - i_boost_total = twopass->nns2.bytes * codec->config.keyframe_boost / 100; + i_boost_total += twopass->nns2.bytes * codec->config.keyframe_boost / 100; i_total += twopass->nns2.bytes; twopass->keyframe_locations[i_frames] = frames; ++i_frames; @@ -710,6 +710,7 @@ int overflow; int credits_pos; int capped_to_max_framesize = 0; + int KFdistance, KF_min_size; if (codec->framenum == 0) { @@ -793,7 +794,27 @@ } else // DLG_MODE_2PASS_2_EXT { - bytes2 = twopass->nns2.bytes; + if (codec->config.credits_mode == CREDITS_MODE_QUANT) + { + if (codec->config.credits_quant_i != codec->config.credits_quant_p) + { + frame->quant = frame->intra ? + codec->config.credits_quant_i : + codec->config.credits_quant_p; + } + else + { + frame->quant = codec->config.credits_quant_p; + frame->intra = -1; + } + + twopass->bytes1 = bytes1; + twopass->bytes2 = bytes1; + twopass->desired_bytes2 = bytes1; + return ICERR_OK; + } + else + bytes2 = twopass->nns2.bytes; } } else // Foxer: apply curve compression outside credits @@ -929,6 +950,32 @@ twopass->desired_bytes2 = bytes2; + // if this keyframe is too close to the next, + // reduce it's byte allotment + if (frame->intra && !credits_pos) + { + KFdistance = codec->twopass.keyframe_locations[codec->twopass.KF_idx] - + codec->twopass.keyframe_locations[codec->twopass.KF_idx - 1]; + + if (KFdistance < codec->config.kftreshold) + { + KFdistance = KFdistance - codec->config.min_key_interval; + + if (KFdistance >= 0) + { + KF_min_size = bytes2 * (100 - codec->config.kfreduction) / 100; + if (KF_min_size < 1) + KF_min_size = 1; + + bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance / + (codec->config.kftreshold - codec->config.min_key_interval); + + if (bytes2 < 1) + bytes2 = 1; + } + } + } + // Foxer: scale overflow in relation to average size, so smaller frames don't get // too much/little bitrate overflow = (int)((double)overflow * bytes2 / twopass->average_frame); @@ -1110,6 +1157,9 @@ codec->twopass.quant_count[frame->quant]++; if ((codec->twopass.nns1.quant & NNSTATS_KEYFRAME)) { + // calculate how much to distribute per frame in + // order to make up for this keyframe's overflow + codec->twopass.overflow += codec->twopass.KFoverflow; codec->twopass.KFoverflow = codec->twopass.desired_bytes2 - frame->length; @@ -1132,6 +1182,8 @@ } else { + // distribute part of the keyframe overflow + codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length + codec->twopass.KFoverflow_partial; codec->twopass.KFoverflow -= codec->twopass.KFoverflow_partial;