Some further QIndex issues with extended Q
Resolved or factored out some further issues with Q index. Put in a 3rd order polynomial instead of less accurate power function as the best fit on gf and kf boost adjustment. Added avg_q value to use instead of ni_av_qi. Compute segment delta Q values based on avg_q. Fixed bug in adjust_maxq_qrange(). The extended range Q on the derf set, using standard data rates (which do not extend high enough to get big benefits) still show a shortfall of between 0.5 and 1% though so there would appear to be further issues that need to be tracked down. Change-Id: Icfd49b9f401906ba487ef1bef7d397048295d959
This commit is contained in:
parent
82d99257f2
commit
b4ad9b5d50
@ -898,7 +898,7 @@ static double calc_correction_factor( double err_per_mb,
|
||||
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
|
||||
@ -919,29 +919,29 @@ static double calc_correction_factor( double err_per_mb,
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1018,7 +1018,7 @@ static int estimate_max_q(VP8_COMP *cpi,
|
||||
|
||||
// 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;
|
||||
@ -1054,7 +1054,7 @@ static int estimate_max_q(VP8_COMP *cpi,
|
||||
((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;
|
||||
@ -1120,7 +1120,7 @@ static int estimate_cq( VP8_COMP *cpi,
|
||||
|
||||
// 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;
|
||||
@ -1181,7 +1181,7 @@ static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_band
|
||||
|
||||
// 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 *
|
||||
@ -2329,6 +2329,46 @@ static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
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;
|
||||
@ -2480,15 +2520,16 @@ void vp8_second_pass(VP8_COMP *cpi)
|
||||
(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
|
||||
@ -2509,14 +2550,9 @@ void vp8_second_pass(VP8_COMP *cpi)
|
||||
(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 --;
|
||||
|
@ -416,13 +416,43 @@ static void segmentation_test_function(VP8_PTR ptr)
|
||||
|
||||
}
|
||||
|
||||
// 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 ||
|
||||
@ -471,7 +501,8 @@ static void init_seg_features(VP8_COMP *cpi)
|
||||
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);
|
||||
@ -495,7 +526,10 @@ static void init_seg_features(VP8_COMP *cpi)
|
||||
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 );
|
||||
@ -2242,6 +2276,8 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
|
||||
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;
|
||||
@ -4601,6 +4637,8 @@ static void encode_frame_to_data_rate
|
||||
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).
|
||||
@ -4732,7 +4770,7 @@ static void encode_frame_to_data_rate
|
||||
|
||||
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,
|
||||
@ -4749,6 +4787,7 @@ static void encode_frame_to_data_rate
|
||||
#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,
|
||||
@ -4763,7 +4802,7 @@ static void encode_frame_to_data_rate
|
||||
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,
|
||||
@ -4780,6 +4819,7 @@ static void encode_frame_to_data_rate
|
||||
#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,
|
||||
|
@ -391,6 +391,8 @@ typedef struct VP8_COMP
|
||||
int ni_tot_qi;
|
||||
int ni_frames;
|
||||
int avg_frame_qindex;
|
||||
double tot_q;
|
||||
double avg_q;
|
||||
|
||||
int zbin_over_quant;
|
||||
int zbin_mode_boost;
|
||||
|
@ -125,12 +125,26 @@ double vp8_convert_qindex_to_q( int qindex )
|
||||
|
||||
int vp8_gfboost_qadjust( int qindex )
|
||||
{
|
||||
return (50.0 * pow(vp8_convert_qindex_to_q(qindex), 0.25) + 0.5);
|
||||
int retval;
|
||||
double q;
|
||||
|
||||
q = vp8_convert_qindex_to_q(qindex);
|
||||
retval = (int)( ( 0.00000828 * q * q * q ) +
|
||||
( -0.0055 * q * q ) +
|
||||
( 1.32 * q ) + 79.3 );
|
||||
return retval;
|
||||
}
|
||||
|
||||
int kfboost_qadjust( int qindex )
|
||||
{
|
||||
return (91.0 * pow(vp8_convert_qindex_to_q(qindex), 0.165) + 0.5);
|
||||
int retval;
|
||||
double q;
|
||||
|
||||
q = vp8_convert_qindex_to_q(qindex);
|
||||
retval = (int)( ( 0.00000973 * q * q * q ) +
|
||||
( -0.00613 * q * q ) +
|
||||
( 1.316 * q ) + 121.2 );
|
||||
return retval;
|
||||
}
|
||||
|
||||
int vp8_bits_per_mb( FRAME_TYPE frame_type, int qindex )
|
||||
|
@ -253,7 +253,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
|
||||
#if CONFIG_EXTEND_QRANGE
|
||||
q = (int)pow(vp8_dc_quant(QIndex,0)>>2, 1.25);
|
||||
q = q << 2;
|
||||
cpi->RDMULT *= 16;
|
||||
cpi->RDMULT = cpi->RDMULT << 4;
|
||||
#else
|
||||
q = (int)pow(vp8_dc_quant(QIndex,0), 1.25);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user