double correction_factor;
// Adjustment based on actual quantizer to power term.
- power_term = (vp8_convert_qindex_to_q(Q) * 0.01) + 0.36;
+ power_term = (vp8_convert_qindex_to_q(Q) * 0.01) + pt_low;
power_term = (power_term > pt_high) ? pt_high : power_term;
// Adjustments to error term
// PGW TODO..
// This code removes direct dependency on QIndex to determin the range
// (now uses the actual quantizer) but has not been tuned.
-static double adjust_maxq_qrange(VP8_COMP *cpi, int qindex )
+static double adjust_maxq_qrange(VP8_COMP *cpi)
{
int i;
- double q = vp8_convert_qindex_to_q(qindex);
+ double q;
- // Set the max corresponding to real q * 2.0
+ // Set the max corresponding to cpi->avg_q * 2.0
+ q = cpi->avg_q * 2.0;
cpi->twopass.maxq_max_limit = cpi->worst_quality;
- for ( i = qindex; i < cpi->worst_quality; i++ )
+ for ( i = cpi->best_quality; i <= cpi->worst_quality; i++ )
{
- if ( vp8_convert_qindex_to_q(qindex) >= (q * 2.0) )
- {
- cpi->twopass.maxq_max_limit = i;
- }
+ cpi->twopass.maxq_max_limit = i;
+ if ( vp8_convert_qindex_to_q(i) >= q )
+ break;
}
- // Set the min corresponding to real q * 0.5
+ // Set the min corresponding to cpi->avg_q * 0.5
+ q = cpi->avg_q * 0.5;
cpi->twopass.maxq_min_limit = cpi->best_quality;
- for ( i = qindex; i > cpi->best_quality; i-- )
+ for ( i = cpi->worst_quality; i >= cpi->best_quality; i-- )
{
- if ( vp8_convert_qindex_to_q(qindex) <= (q * 0.5) )
- {
- cpi->twopass.maxq_min_limit = i;
- }
+ cpi->twopass.maxq_min_limit = i;
+ if ( vp8_convert_qindex_to_q(i) <= q )
+ break;
}
}
// Error per MB based correction factor
err_correction_factor =
- calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
+ calc_correction_factor(err_per_mb, 150.0, 0.36, 0.90, Q);
bits_per_mb_at_this_q =
vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;
((unsigned int)cpi->twopass.total_stats->count >> 8)) &&
(cpi->ni_frames > 150) )
{
- adjust_maxq_qrange( cpi, cpi->ni_av_qi );
+ adjust_maxq_qrange( cpi );
}
return Q;
// Error per MB based correction factor
err_correction_factor =
- calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q);
+ calc_correction_factor(err_per_mb, 100.0, 0.36, 0.90, Q);
bits_per_mb_at_this_q =
vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;
// Error per MB based correction factor
err_correction_factor =
- calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
+ calc_correction_factor(err_per_mb, 150.0, 0.36, 0.90, Q);
bits_per_mb_at_this_q =
(int)( .5 + ( err_correction_factor *
cpi->per_frame_bandwidth = target_frame_size; // Per frame bit target for this frame
}
+// Make a damped adjustment to the active max q.
+int adjust_active_maxq( int old_maxqi, int new_maxqi )
+{
+ int i;
+ int ret_val = new_maxqi;
+ double old_q;
+ double new_q;
+ double target_q;
+
+ old_q = vp8_convert_qindex_to_q( old_maxqi );
+ new_q = vp8_convert_qindex_to_q( new_maxqi );
+
+ target_q = ((old_q * 7.0) + new_q) / 8.0;
+
+ if ( target_q > old_q )
+ {
+ for ( i = old_maxqi; i <= new_maxqi; i++ )
+ {
+ if ( vp8_convert_qindex_to_q( i ) >= target_q )
+ {
+ ret_val = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for ( i = old_maxqi; i >= new_maxqi; i-- )
+ {
+ if ( vp8_convert_qindex_to_q( i ) <= target_q )
+ {
+ ret_val = i;
+ break;
+ }
+ }
+ }
+
+ return ret_val;
+}
+
void vp8_second_pass(VP8_COMP *cpi)
{
int tmp_q;
(int)(cpi->twopass.bits_left / frames_left),
overhead_bits );
+ cpi->active_worst_quality = tmp_q;
+ cpi->ni_av_qi = tmp_q;
+ cpi->avg_q = vp8_convert_qindex_to_q( tmp_q );
+
// Limit the maxq value returned subsequently.
// This increases the risk of overspend or underspend if the initial
// estimate for the clip is bad, but helps prevent excessive
// variation in Q, especially near the end of a clip
// where for example a small overspend may cause Q to crash
- adjust_maxq_qrange(cpi, tmp_q);
-
- cpi->active_worst_quality = tmp_q;
- cpi->ni_av_qi = tmp_q;
+ adjust_maxq_qrange(cpi);
}
// The last few frames of a clip almost always have to few or too many
(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)
- cpi->active_worst_quality ++;
- else if (tmp_q < cpi->active_worst_quality)
- cpi->active_worst_quality --;
-
+ // Make a damped adjustment to active max Q
cpi->active_worst_quality =
- ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
+ adjust_active_maxq( cpi->active_worst_quality, tmp_q );
}
cpi->twopass.frames_to_key --;
}
+// Computes a q delta (in "q index" terms) to get from a starting q value
+// to a target value
+// target q value
+static int compute_qdelta( VP8_COMP *cpi, double qstart, double qtarget )
+{
+ int i;
+ int start_index = cpi->worst_quality;
+ int target_index = cpi->worst_quality;
+ int retval = 0;
+
+ // Convert the average q value to an index.
+ for ( i = cpi->best_quality; i < cpi->worst_quality; i++ )
+ {
+ start_index = i;
+ if ( vp8_convert_qindex_to_q(i) >= qstart )
+ break;
+ }
+
+ // Convert the q target to an index
+ for ( i = cpi->best_quality; i < cpi->worst_quality; i++ )
+ {
+ target_index = i;
+ if ( vp8_convert_qindex_to_q(i) >= qtarget )
+ break;
+ }
+
+ return target_index - start_index;
+}
+
//#if CONFIG_SEGFEATURES
static void init_seg_features(VP8_COMP *cpi)
{
VP8_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
- int high_q = ((int)vp8_convert_qindex_to_q(cpi->ni_av_qi) > 32);
+ int high_q = (int)(cpi->avg_q > 32.0);
+ int qi_delta;
// For now at least dont enable seg features alongside cyclic refresh.
if ( cpi->cyclic_refresh_mode_enabled ||
xd->update_mb_segmentation_map = 1;
xd->update_mb_segmentation_data = 1;
- set_segdata( xd, 1, SEG_LVL_ALT_Q, -(3+(cpi->ni_av_qi >> 3)) );
+ qi_delta = compute_qdelta( cpi, cpi->avg_q, (cpi->avg_q * 0.875) );
+ set_segdata( xd, 1, SEG_LVL_ALT_Q, (qi_delta - 2) );
set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 );
enable_segfeature(xd, 1, SEG_LVL_ALT_Q);
xd->update_mb_segmentation_data = 1;
xd->mb_segement_abs_delta = SEGMENT_DELTADATA;
- set_segdata( xd, 1, SEG_LVL_ALT_Q, 5 );
+ qi_delta = compute_qdelta( cpi, cpi->avg_q,
+ (cpi->avg_q * 1.125) );
+ set_segdata( xd, 1, SEG_LVL_ALT_Q, (qi_delta + 2) );
+ set_segdata( xd, 1, SEG_LVL_ALT_Q, 0 );
enable_segfeature(xd, 1, SEG_LVL_ALT_Q);
set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 );
cpi->ni_av_qi = cpi->oxcf.worst_allowed_q;
cpi->ni_tot_qi = 0;
cpi->ni_frames = 0;
+ cpi->tot_q = 0.0;
+ cpi->avg_q = vp8_convert_qindex_to_q( cpi->oxcf.worst_allowed_q );
cpi->total_byte_count = 0;
cpi->drop_frame = 0;
if ((cm->frame_type != KEY_FRAME) && !cm->refresh_golden_frame && !cm->refresh_alt_ref_frame)
{
cpi->ni_frames++;
+ cpi->tot_q += vp8_convert_qindex_to_q(Q);
+ cpi->avg_q = cpi->tot_q / (double)cpi->ni_frames;
// Calculate the average Q for normal inter frames (not key or GFU
// frames).
if (cpi->twopass.total_left_stats->coded_error != 0.0)
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d"
- "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
+ "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
"%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
"%10.3f %8d\n",
cpi->common.current_video_frame, cpi->this_frame_target,
#endif
vp8_convert_qindex_to_q(cpi->active_best_quality),
vp8_convert_qindex_to_q(cpi->active_worst_quality),
+ cpi->avg_q,
vp8_convert_qindex_to_q(cpi->ni_av_qi),
vp8_convert_qindex_to_q(cpi->cq_target_quality),
cpi->zbin_over_quant,
cpi->tot_recode_hits);
else
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d"
- "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
+ "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
"%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
"%8d\n",
cpi->common.current_video_frame,
#endif
vp8_convert_qindex_to_q(cpi->active_best_quality),
vp8_convert_qindex_to_q(cpi->active_worst_quality),
+ cpi->avg_q,
vp8_convert_qindex_to_q(cpi->ni_av_qi),
vp8_convert_qindex_to_q(cpi->cq_target_quality),
cpi->zbin_over_quant,