Merge "CQ and two pass rate control."

This commit is contained in:
Paul Wilkins 2011-09-30 02:57:54 -07:00 committed by Gerrit Code Review
commit a572ac8327
3 changed files with 326 additions and 213 deletions

View File

@ -152,7 +152,7 @@ static void output_stats(const VP8_COMP *cpi,
fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
" %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
" %12.0f %12.4f\n",
" %12.0f %12.0f %12.4f\n",
stats->frame,
stats->intra_error,
stats->coded_error,
@ -168,6 +168,7 @@ static void output_stats(const VP8_COMP *cpi,
stats->MVrv,
stats->MVcv,
stats->mv_in_out_count,
stats->new_mv_count,
stats->count,
stats->duration);
fclose(fpfile);
@ -192,6 +193,7 @@ static void zero_stats(FIRSTPASS_STATS *section)
section->MVrv = 0.0;
section->MVcv = 0.0;
section->mv_in_out_count = 0.0;
section->new_mv_count = 0.0;
section->count = 0.0;
section->duration = 1.0;
}
@ -213,10 +215,33 @@ static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
section->MVrv += frame->MVrv;
section->MVcv += frame->MVcv;
section->mv_in_out_count += frame->mv_in_out_count;
section->new_mv_count += frame->new_mv_count;
section->count += frame->count;
section->duration += frame->duration;
}
static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
{
section->frame -= frame->frame;
section->intra_error -= frame->intra_error;
section->coded_error -= frame->coded_error;
section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
section->pcnt_inter -= frame->pcnt_inter;
section->pcnt_motion -= frame->pcnt_motion;
section->pcnt_second_ref -= frame->pcnt_second_ref;
section->pcnt_neutral -= frame->pcnt_neutral;
section->MVr -= frame->MVr;
section->mvr_abs -= frame->mvr_abs;
section->MVc -= frame->MVc;
section->mvc_abs -= frame->mvc_abs;
section->MVrv -= frame->MVrv;
section->MVcv -= frame->MVcv;
section->mv_in_out_count -= frame->mv_in_out_count;
section->new_mv_count -= frame->new_mv_count;
section->count -= frame->count;
section->duration -= frame->duration;
}
static void avg_stats(FIRSTPASS_STATS *section)
{
if (section->count < 1.0)
@ -242,49 +267,16 @@ static void avg_stats(FIRSTPASS_STATS *section)
// Calculate a modified Error used in distributing bits between easier and harder frames
static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
{
double av_err = cpi->twopass.total_stats->ssim_weighted_pred_err;
double av_err = ( cpi->twopass.total_stats->ssim_weighted_pred_err /
cpi->twopass.total_stats->count );
double this_err = this_frame->ssim_weighted_pred_err;
double modified_err;
//double relative_next_iiratio;
//double next_iiratio;
//double sum_iiratio;
//int i;
//FIRSTPASS_STATS next_frame;
//FIRSTPASS_STATS *start_pos;
/*start_pos = cpi->twopass.stats_in;
sum_iiratio = 0.0;
i = 0;
while ( (i < 1) && input_stats(cpi,&next_frame) != EOF )
{
next_iiratio = next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error);
next_iiratio = ( next_iiratio < 1.0 ) ? 1.0 : (next_iiratio > 20.0) ? 20.0 : next_iiratio;
sum_iiratio += next_iiratio;
i++;
}
if ( i > 0 )
{
relative_next_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK(cpi->twopass.avg_iiratio * (double)i);
}
else
{
relative_next_iiratio = 1.0;
}
reset_fpf_position(cpi, start_pos);*/
if (this_err > av_err)
modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
else
modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);
/*
relative_next_iiratio = pow(relative_next_iiratio,0.25);
modified_err = modified_err * relative_next_iiratio;
*/
return modified_err;
}
@ -516,8 +508,9 @@ void vp8_first_pass(VP8_COMP *cpi)
int second_ref_count = 0;
int intrapenalty = 256;
int neutral_count = 0;
int new_mv_count = 0;
int sum_in_vectors = 0;
uint32_t lastmv_as_int = 0;
int_mv zero_ref_mv;
@ -697,6 +690,11 @@ void vp8_first_pass(VP8_COMP *cpi)
{
mvcount++;
// Was it different from the last non zero vector
if ( d->bmi.mv.as_int != lastmv_as_int )
new_mv_count++;
lastmv_as_int = d->bmi.mv.as_int;
// Does the Row vector point inwards or outwards
if (mb_row < cm->mb_rows / 2)
{
@ -794,6 +792,7 @@ void vp8_first_pass(VP8_COMP *cpi)
fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / (double)mvcount;
fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / (double)mvcount;
fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
fps.new_mv_count = new_mv_count;
fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
}
@ -851,42 +850,117 @@ void vp8_first_pass(VP8_COMP *cpi)
}
extern const int vp8_bits_per_mb[2][QINDEX_RANGE];
#define BASE_ERRPERMB 150
static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
// Estimate a cost per mb attributable to overheads such as the coding of
// modes and motion vectors.
// Currently simplistic in its assumptions for testing.
//
double bitcost( double prob )
{
return -(log( prob ) / log( 2.0 ));
}
static long long estimate_modemvcost(VP8_COMP *cpi,
FIRSTPASS_STATS * fpstats)
{
int mv_cost;
int mode_cost;
double av_pct_inter = fpstats->pcnt_inter / fpstats->count;
double av_pct_motion = fpstats->pcnt_motion / fpstats->count;
double av_intra = (1.0 - av_pct_inter);
double zz_cost;
double motion_cost;
double intra_cost;
zz_cost = bitcost(av_pct_inter - av_pct_motion);
motion_cost = bitcost(av_pct_motion);
intra_cost = bitcost(av_intra);
// Estimate of extra bits per mv overhead for mbs
// << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb
mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9;
// Crude estimate of overhead cost from modes
// << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb
mode_cost =
(int)( ( ((av_pct_inter - av_pct_motion) * zz_cost) +
(av_pct_motion * motion_cost) +
(av_intra * intra_cost) ) * cpi->common.MBs ) << 9;
return mv_cost + mode_cost;
}
static double calc_correction_factor( double err_per_mb,
double err_devisor,
double pt_low,
double pt_high,
int Q )
{
double power_term;
double error_term = err_per_mb / err_devisor;
double correction_factor;
// Adjustment based on Q to power term.
power_term = pt_low + (Q * 0.01);
power_term = (power_term > pt_high) ? pt_high : power_term;
// Adjustments to error term
// TBD
// Calculate correction factor
correction_factor = pow(error_term, power_term);
// Clip range
correction_factor =
(correction_factor < 0.05)
? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
return correction_factor;
}
static int estimate_max_q(VP8_COMP *cpi,
FIRSTPASS_STATS * fpstats,
int section_target_bandwitdh,
int overhead_bits )
{
int Q;
int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
double section_err = (fpstats->coded_error / fpstats->count);
double err_per_mb = section_err / num_mbs;
double correction_factor;
double err_correction_factor;
double corr_high;
double speed_correction = 1.0;
double pow_highq = 0.90;
double pow_lowq = 0.40;
double inter_pct = (fpstats->pcnt_inter / fpstats->count);
double intra_pct = 1.0 - inter_pct;
int overhead_bits_per_mb;
if (section_target_bandwitdh <= 0)
return cpi->twopass.maxq_max_limit; // Highest value allowed
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
target_norm_bits_per_mb =
(section_target_bandwitdh < (1 << 20))
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
// Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
if ((cpi->rolling_target_bits > 0) && (cpi->active_worst_quality < cpi->worst_quality))
// Calculate a corrective factor based on a rolling ratio of bits spent
// vs target bits
if ((cpi->rolling_target_bits > 0) &&
(cpi->active_worst_quality < cpi->worst_quality))
{
double rolling_ratio;
rolling_ratio = (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits;
rolling_ratio = (double)cpi->rolling_actual_bits /
(double)cpi->rolling_target_bits;
//if ( cpi->twopass.est_max_qcorrection_factor > rolling_ratio )
if (rolling_ratio < 0.95)
//cpi->twopass.est_max_qcorrection_factor *= adjustment_rate;
cpi->twopass.est_max_qcorrection_factor -= 0.005;
//else if ( cpi->twopass.est_max_qcorrection_factor < rolling_ratio )
else if (rolling_ratio > 1.05)
cpi->twopass.est_max_qcorrection_factor += 0.005;
//cpi->twopass.est_max_qcorrection_factor /= adjustment_rate;
cpi->twopass.est_max_qcorrection_factor =
(cpi->twopass.est_max_qcorrection_factor < 0.1)
? 0.1
@ -894,7 +968,8 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
? 10.0 : cpi->twopass.est_max_qcorrection_factor;
}
// Corrections for higher compression speed settings (reduced compression expected)
// Corrections for higher compression speed settings
// (reduced compression expected)
if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
{
if (cpi->oxcf.cpu_used <= 5)
@ -903,10 +978,10 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
speed_correction = 1.25;
}
// Correction factor used for Q values >= 20
corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
corr_high = (corr_high < 0.05)
? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Estimate of overhead bits per mb
// Correction to overhead bits for min allowed Q.
overhead_bits_per_mb = overhead_bits / num_mbs;
overhead_bits_per_mb *= pow( 0.98, (double)cpi->twopass.maxq_min_limit );
// Try and pick a max Q that will be high enough to encode the
// content at the given rate.
@ -914,18 +989,22 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
{
int bits_per_mb_at_this_q;
if (Q < 50)
{
correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
}
else
correction_factor = corr_high;
// Error per MB based correction factor
err_correction_factor =
calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
bits_per_mb_at_this_q = (int)(.5 + correction_factor
bits_per_mb_at_this_q =
vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
bits_per_mb_at_this_q = (int)(.5 + err_correction_factor
* speed_correction * cpi->twopass.est_max_qcorrection_factor
* cpi->twopass.section_max_qfactor
* (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
* (double)bits_per_mb_at_this_q);
// Mode and motion overhead
// As Q rises in real encode loop rd code will force overhead down
// We make a crude adjustment for this here as *.98 per Q step.
overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
@ -934,10 +1013,8 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
// Restriction on active max q for constrained quality mode.
if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(Q < cpi->cq_target_quality) )
//(Q < cpi->oxcf.cq_level;) )
{
Q = cpi->cq_target_quality;
//Q = cpi->oxcf.cq_level;
}
// Adjust maxq_min_limit and maxq_max_limit limits based on
@ -955,6 +1032,97 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
return Q;
}
// For cq mode estimate a cq level that matches the observed
// complexity and data rate.
static int estimate_cq( VP8_COMP *cpi,
FIRSTPASS_STATS * fpstats,
int section_target_bandwitdh,
int overhead_bits )
{
int Q;
int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
double section_err = (fpstats->coded_error / fpstats->count);
double err_per_mb = section_err / num_mbs;
double err_correction_factor;
double corr_high;
double speed_correction = 1.0;
double clip_iiratio;
double clip_iifactor;
double inter_pct = (fpstats->pcnt_inter / fpstats->count);
double intra_pct = 1.0 - inter_pct;
int overhead_bits_per_mb;
if (0)
{
FILE *f = fopen("epmp.stt", "a");
fprintf(f, "%10.2f\n", err_per_mb );
fclose(f);
}
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
// Estimate of overhead bits per mb
overhead_bits_per_mb = overhead_bits / num_mbs;
// Corrections for higher compression speed settings
// (reduced compression expected)
if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
{
if (cpi->oxcf.cpu_used <= 5)
speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
else
speed_correction = 1.25;
}
// II ratio correction factor for clip as a whole
clip_iiratio = cpi->twopass.total_stats->intra_error /
DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error);
clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
if (clip_iifactor < 0.80)
clip_iifactor = 0.80;
// Try and pick a Q that can encode the content at the given rate.
for (Q = 0; Q < MAXQ; Q++)
{
int bits_per_mb_at_this_q;
// Error per MB based correction factor
err_correction_factor =
calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q);
bits_per_mb_at_this_q =
vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
bits_per_mb_at_this_q =
(int)( .5 + err_correction_factor *
speed_correction *
clip_iifactor *
(double)bits_per_mb_at_this_q);
// Mode and motion overhead
// As Q rises in real encode loop rd code will force overhead down
// We make a crude adjustment for this here as *.98 per Q step.
overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
}
// Clip value to range "best allowed to (worst allowed - 1)"
Q = cq_level[Q];
if ( Q >= cpi->worst_quality )
Q = cpi->worst_quality - 1;
if ( Q < cpi->best_quality )
Q = cpi->best_quality;
return Q;
}
static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
{
int Q;
@ -962,11 +1130,9 @@ static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_band
int target_norm_bits_per_mb;
double err_per_mb = section_err / num_mbs;
double correction_factor;
double err_correction_factor;
double corr_high;
double speed_correction = 1.0;
double pow_highq = 0.90;
double pow_lowq = 0.40;
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
@ -979,24 +1145,20 @@ static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_band
speed_correction = 1.25;
}
// Correction factor used for Q values >= 20
corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Try and pick a Q that can encode the content at the given rate.
for (Q = 0; Q < MAXQ; Q++)
{
int bits_per_mb_at_this_q;
if (Q < 50)
{
correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
}
else
correction_factor = corr_high;
// Error per MB based correction factor
err_correction_factor =
calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->twopass.est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
bits_per_mb_at_this_q =
(int)( .5 + ( err_correction_factor *
speed_correction *
cpi->twopass.est_max_qcorrection_factor *
(double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0 ) );
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
@ -1059,23 +1221,17 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta
// Combine the various factors calculated above
combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;
// Correction factor used for Q values >= 20
corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Try and pick a Q that should be high enough to encode the content at the given rate.
for (Q = 0; Q < MAXQ; Q++)
{
// Q values < 20 treated as a special case
if (Q < 20)
{
err_correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
err_correction_factor = (err_correction_factor < 0.05) ? 0.05 : (err_correction_factor > 5.0) ? 5.0 : err_correction_factor;
}
else
err_correction_factor = corr_high;
// Error per MB based correction factor
err_correction_factor =
calc_correction_factor(err_per_mb, 150.0, pow_lowq, pow_highq, Q);
bits_per_mb_at_this_q = (int)(.5 + err_correction_factor * combined_correction_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q]);
bits_per_mb_at_this_q =
(int)(.5 + ( err_correction_factor *
combined_correction_factor *
(double)vp8_bits_per_mb[INTER_FRAME][Q]) );
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
@ -1102,77 +1258,6 @@ static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_ta
return Q;
}
// For cq mode estimate a cq level that matches the observed
// complexity and data rate.
static int estimate_cq(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
{
int Q;
int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
double err_per_mb = section_err / num_mbs;
double correction_factor;
double corr_high;
double speed_correction = 1.0;
double pow_highq = 0.90;
double pow_lowq = 0.40;
double clip_iiratio;
double clip_iifactor;
target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
? (512 * section_target_bandwitdh) / num_mbs
: 512 * (section_target_bandwitdh / num_mbs);
// Corrections for higher compression speed settings
// (reduced compression expected)
if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
{
if (cpi->oxcf.cpu_used <= 5)
speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
else
speed_correction = 1.25;
}
// II ratio correction factor for clip as a whole
clip_iiratio = cpi->twopass.total_stats->intra_error /
DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error);
clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
if (clip_iifactor < 0.80)
clip_iifactor = 0.80;
// Correction factor used for Q values >= 20
corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;
// Try and pick a Q that can encode the content at the given rate.
for (Q = 0; Q < MAXQ; Q++)
{
int bits_per_mb_at_this_q;
if (Q < 50)
{
correction_factor =
pow( err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
correction_factor = (correction_factor < 0.05) ? 0.05
: (correction_factor > 5.0) ? 5.0
: correction_factor;
}
else
correction_factor = corr_high;
bits_per_mb_at_this_q =
(int)( .5 + correction_factor *
speed_correction *
clip_iifactor *
(double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
break;
}
return cq_level[Q];
}
extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);
void vp8_init_second_pass(VP8_COMP *cpi)
@ -1183,19 +1268,13 @@ void vp8_init_second_pass(VP8_COMP *cpi)
double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
zero_stats(cpi->twopass.total_stats);
zero_stats(cpi->twopass.total_left_stats);
if (!cpi->twopass.stats_in_end)
return;
*cpi->twopass.total_stats = *cpi->twopass.stats_in_end;
cpi->twopass.total_error_left = cpi->twopass.total_stats->ssim_weighted_pred_err;
cpi->twopass.total_intra_error_left = cpi->twopass.total_stats->intra_error;
cpi->twopass.total_coded_error_left = cpi->twopass.total_stats->coded_error;
cpi->twopass.start_tot_err_left = cpi->twopass.total_error_left;
//cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
//cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
*cpi->twopass.total_left_stats = *cpi->twopass.total_stats;
// each frame can have a different duration, as the frame rate in the source
// isn't guaranteed to be constant. The frame rate prior to the first frame
@ -1207,7 +1286,6 @@ void vp8_init_second_pass(VP8_COMP *cpi)
cpi->output_frame_rate = cpi->oxcf.frame_rate;
cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->duration * two_pass_min_rate / 10000000.0);
cpi->twopass.clip_bits_total = cpi->twopass.bits_left;
// Calculate a minimum intra value to be used in determining the IIratio
// scores used in the second pass. We have this minimum to make sure
@ -1216,8 +1294,6 @@ void vp8_init_second_pass(VP8_COMP *cpi)
cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
avg_stats(cpi->twopass.total_stats);
// Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence
{
double sum_iiratio = 0.0;
@ -2137,7 +2213,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
cpi->twopass.alt_extra_bits = 0;
}
// Adjustment to estimate_max_q based on a measure of complexity of the section
// Adjustments based on a measure of complexity of the section
if (cpi->common.frame_type != KEY_FRAME)
{
FIRSTPASS_STATS sectionstats;
@ -2238,6 +2314,8 @@ void vp8_second_pass(VP8_COMP *cpi)
FIRSTPASS_STATS *start_pos;
int overhead_bits;
if (!cpi->twopass.stats_in)
{
return ;
@ -2337,20 +2415,26 @@ void vp8_second_pass(VP8_COMP *cpi)
if (cpi->target_bandwidth < 0)
cpi->target_bandwidth = 0;
// Account for mv, mode and other overheads.
overhead_bits = estimate_modemvcost(
cpi, cpi->twopass.total_left_stats );
// Special case code for first frame.
if (cpi->common.current_video_frame == 0)
{
cpi->twopass.est_max_qcorrection_factor = 1.0;
// Experimental code to try and set a cq_level in constrained
// quality mode.
// Set a cq_level in constrained quality mode.
if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
{
int est_cq;
est_cq =
estimate_cq( cpi,
(cpi->twopass.total_coded_error_left / frames_left),
(int)(cpi->twopass.bits_left / frames_left));
cpi->twopass.total_left_stats,
(int)(cpi->twopass.bits_left / frames_left),
overhead_bits );
cpi->cq_target_quality = cpi->oxcf.cq_level;
if ( est_cq > cpi->cq_target_quality )
@ -2360,9 +2444,12 @@ void vp8_second_pass(VP8_COMP *cpi)
// guess at maxq needed in 2nd pass
cpi->twopass.maxq_max_limit = cpi->worst_quality;
cpi->twopass.maxq_min_limit = cpi->best_quality;
tmp_q = estimate_max_q( cpi,
(cpi->twopass.total_coded_error_left / frames_left),
(int)(cpi->twopass.bits_left / frames_left));
tmp_q = estimate_max_q(
cpi,
cpi->twopass.total_left_stats,
(int)(cpi->twopass.bits_left / frames_left),
overhead_bits );
// Limit the maxq value returned subsequently.
// This increases the risk of overspend or underspend if the initial
@ -2383,14 +2470,18 @@ void vp8_second_pass(VP8_COMP *cpi)
// radical adjustments to the allowed quantizer range just to use up a
// few surplus bits or get beneath the target rate.
else if ( (cpi->common.current_video_frame <
(((unsigned int)cpi->twopass.total_stats->count * 255)>>8)) &&
(((unsigned int)cpi->twopass.total_stats->count * 255)>>8)) &&
((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
(unsigned int)cpi->twopass.total_stats->count) )
(unsigned int)cpi->twopass.total_stats->count) )
{
if (frames_left < 1)
frames_left = 1;
tmp_q = estimate_max_q(cpi, (cpi->twopass.total_coded_error_left / frames_left), (int)(cpi->twopass.bits_left / frames_left));
tmp_q = estimate_max_q(
cpi,
cpi->twopass.total_left_stats,
(int)(cpi->twopass.bits_left / frames_left),
overhead_bits );
// Move active_worst_quality but in a damped way
if (tmp_q > cpi->active_worst_quality)
@ -2398,13 +2489,14 @@ void vp8_second_pass(VP8_COMP *cpi)
else if (tmp_q < cpi->active_worst_quality)
cpi->active_worst_quality --;
cpi->active_worst_quality = ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
cpi->active_worst_quality =
((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
}
cpi->twopass.frames_to_key --;
cpi->twopass.total_error_left -= this_frame_error;
cpi->twopass.total_intra_error_left -= this_frame_intra_error;
cpi->twopass.total_coded_error_left -= this_frame_coded_error;
// Update the total stats remaining sturcture
subtract_stats(cpi->twopass.total_left_stats, &this_frame );
}

View File

@ -309,6 +309,9 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
vpx_free(cpi->twopass.total_stats);
cpi->twopass.total_stats = 0;
vpx_free(cpi->twopass.total_left_stats);
cpi->twopass.total_left_stats = 0;
vpx_free(cpi->twopass.this_frame_stats);
cpi->twopass.this_frame_stats = 0;
#endif
@ -1335,11 +1338,16 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
cpi->twopass.total_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
vpx_free(cpi->twopass.total_left_stats);
cpi->twopass.total_left_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
vpx_free(cpi->twopass.this_frame_stats);
cpi->twopass.this_frame_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
if(!cpi->twopass.total_stats || !cpi->twopass.this_frame_stats)
if( !cpi->twopass.total_stats ||
!cpi->twopass.total_left_stats ||
!cpi->twopass.this_frame_stats)
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate firstpass stats");
#endif
@ -3511,12 +3519,13 @@ static void encode_frame_to_data_rate
(cpi->avg_frame_qindex < cpi->active_worst_quality) )
{
Q = cpi->avg_frame_qindex;
}
if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(Q < cpi->oxcf.cq_level) )
{
Q = cpi->oxcf.cq_level;
}
// For constrained quality dont allow Q less than the cq level
if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(Q < cpi->cq_target_quality) )
{
Q = cpi->cq_target_quality;
}
if ( cpi->pass == 2 )
@ -3527,6 +3536,13 @@ static void encode_frame_to_data_rate
cpi->active_best_quality = gf_high_motion_minq[Q];
else
cpi->active_best_quality = gf_mid_motion_minq[Q];
// Constrained quality use slightly lower active best.
if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
{
cpi->active_best_quality =
cpi->active_best_quality * 15/16;
}
}
// One pass more conservative
else
@ -3537,7 +3553,7 @@ static void encode_frame_to_data_rate
cpi->active_best_quality = inter_minq[Q];
// For the constant/constrained quality mode we dont want
// the quality to rise above the cq level.
// q to fall below the cq level.
if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
(cpi->active_best_quality < cpi->cq_target_quality) )
{
@ -3590,8 +3606,9 @@ static void encode_frame_to_data_rate
if (cpi->active_best_quality < cpi->best_quality)
cpi->active_best_quality = cpi->best_quality;
else if (cpi->active_best_quality > cpi->active_worst_quality)
cpi->active_best_quality = cpi->active_worst_quality;
if ( cpi->active_worst_quality < cpi->active_best_quality )
cpi->active_worst_quality = cpi->active_best_quality;
// Determine initial Q to try
Q = vp8_regulate_q(cpi, cpi->this_frame_target);
@ -4294,7 +4311,7 @@ static void encode_frame_to_data_rate
vp8_clear_system_state(); //__asm emms;
if (cpi->twopass.total_coded_error_left != 0.0)
if (cpi->twopass.total_left_stats.coded_error != 0.0)
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6d %6d"
"%6d %6d %6d %5d %5d %5d %8d %8.2f %10d %10.3f"
"%10.3f %8d\n",
@ -4305,13 +4322,16 @@ static void encode_frame_to_data_rate
(cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
(int)cpi->total_actual_bits, cm->base_qindex,
cpi->active_best_quality, cpi->active_worst_quality,
cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant,
cpi->ni_av_qi, cpi->cq_target_quality,
cpi->zbin_over_quant,
//cpi->avg_frame_qindex, cpi->zbin_over_quant,
cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
cm->frame_type, cpi->gfu_boost,
cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left,
cpi->twopass.total_coded_error_left,
(double)cpi->twopass.bits_left / cpi->twopass.total_coded_error_left,
cpi->twopass.est_max_qcorrection_factor,
(int)cpi->twopass.bits_left,
cpi->twopass.total_left_stats.coded_error,
(double)cpi->twopass.bits_left /
cpi->twopass.total_left_stats.coded_error,
cpi->tot_recode_hits);
else
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d %10d %6d %6d"
@ -4324,12 +4344,15 @@ static void encode_frame_to_data_rate
(cpi->oxcf.starting_buffer_level-cpi->bits_off_target),
(int)cpi->total_actual_bits, cm->base_qindex,
cpi->active_best_quality, cpi->active_worst_quality,
cpi->ni_av_qi, cpi->cq_target_quality, cpi->zbin_over_quant,
cpi->ni_av_qi, cpi->cq_target_quality,
cpi->zbin_over_quant,
//cpi->avg_frame_qindex, cpi->zbin_over_quant,
cm->refresh_golden_frame, cm->refresh_alt_ref_frame,
cm->frame_type, cpi->gfu_boost,
cpi->twopass.est_max_qcorrection_factor, (int)cpi->twopass.bits_left,
cpi->twopass.total_coded_error_left, cpi->tot_recode_hits);
cpi->twopass.est_max_qcorrection_factor,
(int)cpi->twopass.bits_left,
cpi->twopass.total_left_stats.coded_error,
cpi->tot_recode_hits);
fclose(f);

View File

@ -108,6 +108,7 @@ typedef struct
double MVrv;
double MVcv;
double mv_in_out_count;
double new_mv_count;
double duration;
double count;
}
@ -523,6 +524,7 @@ typedef struct VP8_COMP
FIRSTPASS_STATS *total_stats;
FIRSTPASS_STATS *this_frame_stats;
FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start;
FIRSTPASS_STATS *total_left_stats;
int first_pass_done;
int64_t bits_left;
int64_t clip_bits_total;
@ -530,10 +532,6 @@ typedef struct VP8_COMP
double modified_error_total;
double modified_error_used;
double modified_error_left;
double total_error_left;
double total_intra_error_left;
double total_coded_error_left;
double start_tot_err_left;
double kf_intra_err_min;
double gf_intra_err_min;
int frames_to_key;