summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/firstpass.c479
-rw-r--r--vp8/encoder/onyx_if.c58
-rw-r--r--vp8/encoder/onyx_int.h6
3 files changed, 325 insertions, 218 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 35adb9d10..4f3b75ce2 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -146,7 +146,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,
@@ -162,6 +162,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);
@@ -186,6 +187,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;
}
@@ -207,10 +209,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)
@@ -236,49 +261,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;
}
@@ -510,8 +502,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;
@@ -542,7 +535,7 @@ void vp8_first_pass(VP8_COMP *cpi)
//if ( 0 )
{
int flag[2] = {1, 1};
- vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q);
+ vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
}
@@ -691,6 +684,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)
{
@@ -788,6 +786,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;
}
@@ -844,42 +843,117 @@ void vp8_first_pass(VP8_COMP *cpi)
}
-#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
@@ -887,7 +961,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)
@@ -896,10 +971,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.
@@ -907,18 +982,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 =
+ vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;
- bits_per_mb_at_this_q = (int)(.5 + correction_factor
+ 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;
@@ -927,10 +1006,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
@@ -948,6 +1025,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;
@@ -955,11 +1123,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);
@@ -972,28 +1138,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);
+ (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;
@@ -1056,26 +1214,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) );
+ (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 +1251,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 +1261,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 +1279,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 +1287,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;
@@ -2238,6 +2307,8 @@ void vp8_second_pass(VP8_COMP *cpi)
FIRSTPASS_STATS *start_pos;
+ int overhead_bits;
+
if (!cpi->twopass.stats_in)
{
return ;
@@ -2337,20 +2408,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 +2437,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 +2463,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 +2482,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 );
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index ec5ff64ef..2dcddc0d1 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -339,6 +339,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
@@ -1553,11 +1556,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
@@ -3812,12 +3820,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 )
@@ -3828,6 +3837,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
@@ -3838,7 +3854,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) )
{
@@ -3891,8 +3907,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);
@@ -4622,7 +4639,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",
@@ -4633,13 +4650,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"
@@ -4652,15 +4672,19 @@ 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);
+ if ( 0 )
{
FILE *fmodes = fopen("Modes.stt", "a");
int i;
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 465faeec7..622f25068 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -120,6 +120,7 @@ typedef struct
double MVrv;
double MVcv;
double mv_in_out_count;
+ double new_mv_count;
double duration;
double count;
}
@@ -567,6 +568,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;
@@ -574,10 +576,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;