Fix CQ range and experimental KF sizing changes.

The CQ level was not using the q_trans[] array to convert
to a 0-127 range as per min and maxq

Experimental change to try and match the reconstruction
error for forced key frames approximately to that of the
previous frame by means of the recode loop. Though this
may cause extra recodes and the recode behavior has not
been optimized, it can only happen on forced key frames.

Change-Id: I1f7e42d526f1b1cb556dd461eff1a692bd1b5b2f
This commit is contained in:
Paul Wilkins 2011-01-17 17:23:11 +00:00
parent a1a4d23797
commit 339c512762
3 changed files with 75 additions and 27 deletions

View File

@ -1551,6 +1551,7 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->auto_worst_q = 0;
cpi->oxcf.best_allowed_q = MINQ;
cpi->oxcf.worst_allowed_q = MAXQ;
cpi->oxcf.cq_level = MINQ;
cpi->oxcf.end_usage = USAGE_STREAM_FROM_SERVER;
cpi->oxcf.starting_buffer_level = 4000;
@ -1651,6 +1652,7 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q];
cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level];
if (oxcf->fixed_q >= 0)
{
@ -1740,6 +1742,8 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->avg_frame_qindex = cpi->oxcf.worst_allowed_q;
cpi->best_quality = cpi->oxcf.best_allowed_q;
cpi->active_best_quality = cpi->oxcf.best_allowed_q;
cpi->cq_target_quality = cpi->oxcf.cq_level;
cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
@ -1936,6 +1940,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
cpi->oxcf.best_allowed_q = q_trans[oxcf->best_allowed_q];
cpi->oxcf.cq_level = q_trans[cpi->oxcf.cq_level];
if (oxcf->fixed_q >= 0)
{
@ -2028,7 +2033,6 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->active_best_quality = cpi->oxcf.best_allowed_q;
cpi->buffered_mode = (cpi->oxcf.optimal_buffer_level > 0) ? TRUE : FALSE;
// Experimental cq target value
cpi->cq_target_quality = cpi->oxcf.cq_level;
cpi->rolling_target_bits = cpi->av_per_frame_bandwidth;
@ -3817,29 +3821,28 @@ static void encode_frame_to_data_rate
if ( cm->frame_type == KEY_FRAME )
{
// Special case for key frames forced because we have reached
// the maximum key frame interval. Here force the Q to a range
// close to but just below the ambient Q to minimize the risk
// of popping
if ( cpi->this_key_frame_forced )
if ( cpi->pass == 2 )
{
cpi->active_worst_quality = cpi->avg_frame_qindex * 7/8;
cpi->active_best_quality = cpi->avg_frame_qindex * 2/3;
}
else
{
if ( cpi->pass == 2 )
{
if (cpi->gfu_boost > 600)
cpi->active_best_quality = kf_low_motion_minq[Q];
else
cpi->active_best_quality = kf_high_motion_minq[Q];
}
// One pass more conservative
else
if (cpi->gfu_boost > 600)
cpi->active_best_quality = kf_low_motion_minq[Q];
else
cpi->active_best_quality = kf_high_motion_minq[Q];
// Special case for key frames forced because we have reached
// the maximum key frame interval. Here force the Q to a range
// based on the ambient Q to reduce the risk of popping
if ( cpi->this_key_frame_forced )
{
if ( cpi->active_best_quality > cpi->avg_frame_qindex * 7/8)
cpi->active_best_quality = cpi->avg_frame_qindex * 7/8;
else if ( cpi->active_best_quality < cpi->avg_frame_qindex >> 2 )
cpi->active_best_quality = cpi->avg_frame_qindex >> 2;
}
}
}
// One pass more conservative
else
cpi->active_best_quality = kf_high_motion_minq[Q];
}
else if (cm->refresh_golden_frame || cpi->common.refresh_alt_ref_frame)
{
@ -4153,9 +4156,44 @@ static void encode_frame_to_data_rate
active_worst_qchanged = FALSE;
#if !(CONFIG_REALTIME_ONLY)
// Special case handling for forced key frames
if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced )
{
int last_q = Q;
int kf_err = vp8_calc_ss_err(cpi->Source,
&cm->yv12_fb[cm->new_fb_idx],
IF_RTCD(&cpi->rtcd.variance));
// The key frame is not good enough
if ( kf_err > ((cpi->ambient_err * 3) >> 2) )
{
// Lower q_high
q_high = (Q > q_low) ? (Q - 1) : q_low;
// Adjust Q
Q = (q_high + q_low) >> 1;
}
// The key frame is much better than the previous frame
else if ( kf_err < (cpi->ambient_err >> 1) )
{
// Raise q_low
q_low = (Q < q_high) ? (Q + 1) : q_high;
// Adjust Q
Q = (q_high + q_low + 1) >> 1;
}
// Clamp Q to upper and lower limits:
if (Q > q_high)
Q = q_high;
else if (Q < q_low)
Q = q_low;
Loop = ((Q != last_q)) ? TRUE : FALSE;
}
// Is the projected frame size out of range and are we allowed to attempt to recode.
if ( recode_loop_test( cpi,
else if ( recode_loop_test( cpi,
frame_over_shoot_limit, frame_under_shoot_limit,
Q, top_index, bottom_index ) )
{
@ -4171,7 +4209,7 @@ static void encode_frame_to_data_rate
//if ( cpi->zbin_over_quant == 0 )
q_low = (Q < q_high) ? (Q + 1) : q_high; // Raise Qlow as to at least the current value
if (cpi->zbin_over_quant > 0) // If we are using over quant do the same for zbin_oq_low
if (cpi->zbin_over_quant > 0) // If we are using over quant do the same for zbin_oq_low
zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high;
//if ( undershoot_seen || (Q == MAXQ) )
@ -4314,6 +4352,16 @@ static void encode_frame_to_data_rate
}
#endif
// Special case code to reduce pulsing when key frames are forced at a
// fixed interval. Note the reconstruction error if it is the frame before
// the force key frame
if ( cpi->next_key_frame_forced && (cpi->frames_to_key == 0) )
{
cpi->ambient_err = vp8_calc_ss_err(cpi->Source,
&cm->yv12_fb[cm->new_fb_idx],
IF_RTCD(&cpi->rtcd.variance));
}
// Update the GF useage maps.
// This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
@ -4343,7 +4391,6 @@ static void encode_frame_to_data_rate
}
}
// Update the GF useage maps.
// This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
@ -4374,8 +4421,6 @@ static void encode_frame_to_data_rate
else
cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
//#pragma omp parallel sections
{

View File

@ -320,6 +320,9 @@ typedef struct
unsigned int this_key_frame_forced;
unsigned int next_key_frame_forced;
// Ambient reconstruction err target for force key frames
int ambient_err;
unsigned int mode_check_freq[MAX_MODES];
unsigned int mode_test_hit_counts[MAX_MODES];
unsigned int mode_chosen_counts[MAX_MODES];

View File

@ -310,6 +310,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
oxcf->best_allowed_q = cfg.rc_min_quantizer;
oxcf->worst_allowed_q = cfg.rc_max_quantizer;
oxcf->cq_level = vp8_cfg.cq_level;
oxcf->fixed_q = -1;
oxcf->under_shoot_pct = cfg.rc_undershoot_pct;
@ -346,7 +347,6 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf,
oxcf->arnr_type = vp8_cfg.arnr_type;
oxcf->tuning = vp8_cfg.tuning;
oxcf->cq_level = vp8_cfg.cq_level;
/*
printf("Current VP8 Settings: \n");