📄 2pass.cpp.svn-base
字号:
(dbytes - twopass.average_pframe) / twopass.alt_curve_high_diff); break; case 0: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_high_diff)))); } } } else { if (dbytes <= twopass.alt_curve_low) curve_temp = dbytes; else { switch(config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_low_diff))); break; case 1: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * (dbytes - twopass.average_pframe) / twopass.alt_curve_low_diff); break; case 0: curve_temp = dbytes * (twopass.alt_curve_mid_qual + twopass.alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_low_diff)))); } } } if (twopass.movie_curve > 1.0) dbytes *= twopass.movie_curve; newquant = (int)(dbytes * 2.0 / (curve_temp * twopass.curve_comp_scale + twopass.curve_bias_bonus)); if (newquant > 1) { if (newquant != oldquant) { oldquant = newquant; percent = (int)((i - twopass.average_pframe) * 100.0 / twopass.average_pframe); wsprintf(s, _l("quant:%i threshold at %i : %i percent"), newquant, i, percent); quant_threshs[newquant].thresh=i;quant_threshs[newquant].percent=percent; DEBUG2P(s); } } } } } twopass.overflow = 0; twopass.KFoverflow = 0; twopass.KFoverflow_partial = 0; twopass.KF_idx = 1; break; } return ICERR_OK;}// NOTE: codec_2pass_get_quant() should be called for all the frames that are in the stats file(s)int Txvid_2pass::codec_2pass_get_quant(TencFrameParams *frame){// DWORD read; int bytes1, bytes2; int overflow; int credits_pos; int capped_to_max_framesize = 0; int KFdistance, KF_min_size; if (framenum == 0) { int i; for (i=0 ; i<32 ; ++i) { bquant_error[i] = 0.0; pquant_error[i] = 0.0; } curve_comp_error = 0.0; last_bquant = 0; last_pquant = 0; } if (twopass.nns_array_pos >= twopass.nns_array_length) { // fix for VirtualDub 1.4.13 bframe handling if (config.max_b_frames > 0 && framenum < twopass.nns_array_length + config.max_b_frames) { return ICERR_OK; } else { DEBUGERR(_l("ERROR: VIDEO EXCEEDS 1ST PASS!!!")); return ICERR_ERROR; } } memcpy(&twopass.nns1, &twopass.nns1_array[twopass.nns_array_pos], sizeof(NNSTATS)); if (config.mode == DLG_MODE_2PASS_2_EXT) memcpy(&twopass.nns2, &twopass.nns2_array[twopass.nns_array_pos], sizeof(NNSTATS)); twopass.nns_array_pos++; bytes1 = twopass.nns1.bytes; // skip unnecessary frames. if (twopass.nns1.dd_v & NNSTATS_SKIPFRAME) { twopass.bytes1 = bytes1; twopass.bytes2 = bytes1; twopass.desired_bytes2 = bytes1; frame->frametype = FRAME_TYPE::SKIP; return ICERR_OK; } else if (twopass.nns1.dd_v & NNSTATS_PADFRAME) { twopass.bytes1 = bytes1; twopass.bytes2 = bytes1; twopass.desired_bytes2 = bytes1; frame->frametype = FRAME_TYPE::PAD; return ICERR_OK; } else if (twopass.nns1.dd_v & NNSTATS_DELAYFRAME) { twopass.bytes1 = bytes1; twopass.bytes2 = bytes1; twopass.desired_bytes2 = bytes1; frame->frametype = FRAME_TYPE::DELAY; return ICERR_OK; } overflow = twopass.overflow / 8; // override codec i-frame choice (reenable in credits) if (twopass.nns1.quant & NNSTATS_KEYFRAME) frame->frametype=FRAME_TYPE::I; else if (twopass.nns1.dd_v & NNSTATS_BFRAME) frame->frametype=FRAME_TYPE::B; else frame->frametype=FRAME_TYPE::P; if (frame->frametype==FRAME_TYPE::I) { overflow = 0; } credits_pos = codec_is_in_credits( framenum); if (credits_pos) { if (config.mode == DLG_MODE_2PASS_2_INT) { switch (config.credits_mode) { case CREDITS_MODE_RATE : case CREDITS_MODE_SIZE : if (credits_pos == CREDITS_START) { bytes2 = (int)(bytes1 / twopass.credits_start_curve); } else // CREDITS_END { bytes2 = (int)(bytes1 / twopass.credits_end_curve); } frame->frametype = -1; break; case CREDITS_MODE_QUANT : if (config.credits_quant_i != config.credits_quant_p) { frame->quant = frame->frametype ? config.credits_quant_i : config.credits_quant_p; } else { frame->quant = config.credits_quant_p; frame->frametype = -1; } twopass.bytes1 = bytes1; twopass.bytes2 = bytes1; twopass.desired_bytes2 = bytes1; return ICERR_OK; } } else // DLG_MODE_2PASS_2_EXT { if (config.credits_mode == CREDITS_MODE_QUANT) { if (config.credits_quant_i != config.credits_quant_p) { frame->quant = frame->frametype == FRAME_TYPE::I ? config.credits_quant_i : config.credits_quant_p; } else { frame->quant = config.credits_quant_p; frame->frametype = -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 { double dbytes, curve_temp; bytes2 = (config.mode == DLG_MODE_2PASS_2_INT) ? bytes1 : twopass.nns2.bytes; if (frame->frametype==FRAME_TYPE::I) { dbytes = ((int)(bytes2 + bytes2 * config.keyframe_boost / 100)) / twopass.movie_curve; } else { dbytes = bytes2 / twopass.movie_curve; } if (twopass.nns1.dd_v & NNSTATS_BFRAME) dbytes *= twopass.average_pframe / twopass.average_bframe; // spread the compression error across payback_delay frames if (config.bitrate_payback_method == 0) { bytes2 = (int)(curve_comp_error / config.bitrate_payback_delay); } else { bytes2 = (int)(curve_comp_error * dbytes / twopass.average_pframe / config.bitrate_payback_delay); if (labs(bytes2) > fabs(curve_comp_error)) { bytes2 = (int)curve_comp_error; } } curve_comp_error -= bytes2; if (config.use_alt_curve) { if (!(frame->frametype==FRAME_TYPE::I)) { if (dbytes > twopass.average_pframe) { if (dbytes >= twopass.alt_curve_high) curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev); else { switch(config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_high_diff))); break; case 1: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * (dbytes - twopass.average_pframe) / twopass.alt_curve_high_diff); break; case 0: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_high_diff)))); } } } else { if (dbytes <= twopass.alt_curve_low) curve_temp = dbytes; else { switch(config.alt_curve_type) { case 2: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * sin(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_low_diff))); break; case 1: curve_temp = dbytes * (twopass.alt_curve_mid_qual - twopass.alt_curve_qual_dev * (dbytes - twopass.average_pframe) / twopass.alt_curve_low_diff); break; case 0: curve_temp = dbytes * (twopass.alt_curve_mid_qual + twopass.alt_curve_qual_dev * (1.0 - cos(DEG2RAD * ((dbytes - twopass.average_pframe) * 90.0 / twopass.alt_curve_low_diff)))); } } } if (twopass.nns1.dd_v & NNSTATS_BFRAME) curve_temp *= twopass.average_bframe / twopass.average_pframe; curve_temp = curve_temp * twopass.curve_comp_scale + twopass.curve_bias_bonus; bytes2 += ((int)curve_temp); curve_comp_error += curve_temp - ((int)curve_temp); } else { if (twopass.nns1.dd_v & NNSTATS_BFRAME) dbytes *= twopass.average_bframe / twopass.average_pframe; bytes2 += ((int)dbytes); curve_comp_error += dbytes - ((int)dbytes); } } else if ((config.curve_compression_high + config.curve_compression_low) && !(frame->frametype==FRAME_TYPE::I)) { if (dbytes > twopass.average_pframe) { curve_temp = twopass.curve_comp_scale * ((double)dbytes + (twopass.average_pframe - dbytes) * config.curve_compression_high / 100.0); } else { curve_temp = twopass.curve_comp_scale * ((double)dbytes + (twopass.average_pframe - dbytes) * config.curve_compression_low / 100.0); } if (twopass.nns1.dd_v & NNSTATS_BFRAME) curve_temp *= twopass.average_bframe / twopass.average_pframe; bytes2 += ((int)curve_temp); curve_comp_error += curve_temp - ((int)curve_temp); } else { if (twopass.nns1.dd_v & NNSTATS_BFRAME) dbytes *= twopass.average_bframe / twopass.average_pframe; bytes2 += ((int)dbytes); curve_comp_error += dbytes - ((int)dbytes); } // cap bytes2 to first pass size, lowers number of quant=1 frames if (bytes2 > bytes1) { curve_comp_error += bytes2 - bytes1; bytes2 = bytes1; } else { if (frame->frametype==FRAME_TYPE::I) { if (bytes2 < twopass.minisize) { curve_comp_error -= twopass.minisize - bytes2; bytes2 = twopass.minisize; } } else if (twopass.nns1.dd_v & NNSTATS_BFRAME) { if (bytes2 < twopass.minbsize) bytes2 = twopass.minbsize; } else { if (bytes2 < twopass.minpsize) bytes2 = twopass.minpsize; } } } twopass.desired_bytes2 = bytes2; // if this keyframe is too close to the next, // reduce it's byte allotment if ((frame->frametype==FRAME_TYPE::I) && !credits_pos) { KFdistance = twopass.keyframe_locations[twopass.KF_idx] - twopass.keyframe_locations[twopass.KF_idx - 1]; if (KFdistance < config.kftreshold) { KFdistance = KFdistance - config.min_key_interval; if (KFdistance >= 0) { KF_min_size = bytes2 * (100 - config.kfreduction) / 100; if (KF_min_size < 1) KF_min_size = 1; bytes2 = KF_min_size + (bytes2 - KF_min_size) * KFdistance / (config.kftreshold - 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_pframe); // Foxer: reign in overflow with huge frames if (labs(overflow) > labs(twopass.overflow)) { overflow = twopass.overflow;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -