Further work to reduce pulsing.
These changes are specifically targeted at fade transitions to static scenes. Here we want to place a GF/ARF immediately after the fade and prevent an ARF just before the fade. Also some code lines and comment lines shortened to 80 chars while I was there. Change-Id: Iefdc09a4fa7b265048fc017246b73e138693950f
This commit is contained in:
parent
419553258d
commit
8064583d26
@ -1337,17 +1337,20 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
double decay_accumulator = 1.0;
|
||||
|
||||
double boost_factor = IIFACTOR;
|
||||
double loop_decay_rate = 1.00; // Starting decay rate
|
||||
double loop_decay_rate = 1.00; // Starting decay rate
|
||||
|
||||
double this_frame_mv_in_out = 0.0;
|
||||
double mv_in_out_accumulator = 0.0;
|
||||
double abs_mv_in_out_accumulator = 0.0;
|
||||
double mod_err_per_mb_accumulator = 0.0;
|
||||
|
||||
int max_bits = frame_max_bits(cpi); // Max for a single frame
|
||||
int max_bits = frame_max_bits(cpi); // Max for a single frame
|
||||
|
||||
unsigned char *fpmm_pos;
|
||||
|
||||
unsigned int allow_alt_ref =
|
||||
cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
|
||||
|
||||
cpi->gf_group_bits = 0;
|
||||
cpi->gf_decay_rate = 0;
|
||||
|
||||
@ -1362,35 +1365,41 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
// Preload the stats for the next frame.
|
||||
mod_frame_err = calculate_modified_err(cpi, this_frame);
|
||||
|
||||
// Note the error of the frame at the start of the group (this will be the GF frame error if we code a normal gf
|
||||
// Note the error of the frame at the start of the group (this will be
|
||||
// the GF frame error if we code a normal gf
|
||||
gf_first_frame_err = mod_frame_err;
|
||||
|
||||
// Special treatment if the current frame is a key frame (which is also a gf).
|
||||
// If it is then its error score (and hence bit allocation) need to be subtracted out
|
||||
// from the calculation for the GF group
|
||||
// Special treatment if the current frame is a key frame (which is also
|
||||
// a gf). If it is then its error score (and hence bit allocation) need
|
||||
// to be subtracted out from the calculation for the GF group
|
||||
if (cpi->common.frame_type == KEY_FRAME)
|
||||
gf_group_err -= gf_first_frame_err;
|
||||
|
||||
// Scan forward to try and work out how many frames the next gf group should contain and
|
||||
// what level of boost is appropriate for the GF or ARF that will be coded with the group
|
||||
// Scan forward to try and work out how many frames the next gf group
|
||||
// should contain and what level of boost is appropriate for the GF
|
||||
// or ARF that will be coded with the group
|
||||
i = 0;
|
||||
|
||||
while (((i < cpi->static_scene_max_gf_interval) || ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) && (i < cpi->frames_to_key))
|
||||
while (((i < cpi->static_scene_max_gf_interval) ||
|
||||
((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) &&
|
||||
(i < cpi->frames_to_key))
|
||||
{
|
||||
double r;
|
||||
double this_frame_mvr_ratio;
|
||||
double this_frame_mvc_ratio;
|
||||
double motion_decay;
|
||||
//double motion_pct = next_frame.pcnt_motion;
|
||||
double motion_pct;
|
||||
|
||||
i++; // Increment the loop counter
|
||||
i++; // Increment the loop counter
|
||||
|
||||
// Accumulate error score of frames in this gf group
|
||||
mod_frame_err = calculate_modified_err(cpi, this_frame);
|
||||
|
||||
gf_group_err += mod_frame_err;
|
||||
|
||||
mod_err_per_mb_accumulator += mod_frame_err / DOUBLE_DIVIDE_CHECK((double)cpi->common.MBs);
|
||||
mod_err_per_mb_accumulator +=
|
||||
mod_frame_err / DOUBLE_DIVIDE_CHECK((double)cpi->common.MBs);
|
||||
|
||||
if (EOF == vp8_input_stats(cpi, &next_frame))
|
||||
break;
|
||||
@ -1401,9 +1410,12 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_pct);
|
||||
|
||||
//Accumulate Motion In/Out of frame stats
|
||||
this_frame_mv_in_out = next_frame.mv_in_out_count * motion_pct;
|
||||
mv_in_out_accumulator += next_frame.mv_in_out_count * motion_pct;
|
||||
abs_mv_in_out_accumulator += fabs(next_frame.mv_in_out_count * motion_pct);
|
||||
this_frame_mv_in_out =
|
||||
next_frame.mv_in_out_count * motion_pct;
|
||||
mv_in_out_accumulator +=
|
||||
next_frame.mv_in_out_count * motion_pct;
|
||||
abs_mv_in_out_accumulator +=
|
||||
fabs(next_frame.mv_in_out_count * motion_pct);
|
||||
|
||||
// If there is a significant amount of motion
|
||||
if (motion_pct > 0.05)
|
||||
@ -1432,7 +1444,9 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
}
|
||||
|
||||
// Underlying boost factor is based on inter intra error ratio
|
||||
r = (boost_factor * (next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error)));
|
||||
r = ( boost_factor *
|
||||
( next_frame.intra_error /
|
||||
DOUBLE_DIVIDE_CHECK(next_frame.coded_error)));
|
||||
|
||||
if (next_frame.intra_error > cpi->gf_intra_err_min)
|
||||
r = (IIKFACTOR2 * next_frame.intra_error /
|
||||
@ -1441,13 +1455,15 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
r = (IIKFACTOR2 * cpi->gf_intra_err_min /
|
||||
DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
|
||||
|
||||
// Increase boost for frames where new data coming into frame (eg zoom out)
|
||||
// Slightly reduce boost if there is a net balance of motion out of the frame (zoom in)
|
||||
// Increase boost for frames where new data coming into frame
|
||||
// (eg zoom out). Slightly reduce boost if there is a net balance
|
||||
// of motion out of the frame (zoom in).
|
||||
// The range for this_frame_mv_in_out is -1.0 to +1.0
|
||||
if (this_frame_mv_in_out > 0.0)
|
||||
r += r * (this_frame_mv_in_out * 2.0);
|
||||
// In extreme case boost is halved
|
||||
else
|
||||
r += r * (this_frame_mv_in_out / 2.0); // In extreme case boost is halved
|
||||
r += r * (this_frame_mv_in_out / 2.0);
|
||||
|
||||
if (r > GF_RMAX)
|
||||
r = GF_RMAX;
|
||||
@ -1485,10 +1501,24 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
|
||||
boost_score += (decay_accumulator * r);
|
||||
|
||||
// Break clause to detect very still sections after motion
|
||||
// For example a staic image after a fade or other transition
|
||||
// instead of a clean key frame.
|
||||
if ( (i > MIN_GF_INTERVAL) &&
|
||||
(loop_decay_rate >= 0.999) &&
|
||||
(decay_accumulator < 0.9) )
|
||||
{
|
||||
// Force GF not alt ref
|
||||
allow_alt_ref = FALSE;
|
||||
|
||||
boost_score = old_boost_score;
|
||||
break;
|
||||
}
|
||||
|
||||
// Break out conditions.
|
||||
if ( /* i>4 || */
|
||||
// Break at cpi->max_gf_interval unless almost totally static
|
||||
(i >= cpi->max_gf_interval && (decay_accumulator < 0.99)) ||
|
||||
(i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) ||
|
||||
(
|
||||
// Dont break out with a very short interval
|
||||
(i > MIN_GF_INTERVAL) &&
|
||||
@ -1510,7 +1540,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
old_boost_score = boost_score;
|
||||
}
|
||||
|
||||
cpi->gf_decay_rate = (i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0;
|
||||
cpi->gf_decay_rate =
|
||||
(i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0;
|
||||
|
||||
// When using CBR apply additional buffer related upper limits
|
||||
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
|
||||
@ -1520,7 +1551,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
// For cbr apply buffer related limits
|
||||
if (cpi->drop_frames_allowed)
|
||||
{
|
||||
int df_buffer_level = cpi->oxcf.drop_frames_water_mark * (cpi->oxcf.optimal_buffer_level / 100);
|
||||
int df_buffer_level = cpi->oxcf.drop_frames_water_mark *
|
||||
(cpi->oxcf.optimal_buffer_level / 100);
|
||||
|
||||
if (cpi->buffer_level > df_buffer_level)
|
||||
max_boost = ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
|
||||
@ -1543,10 +1575,10 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
|
||||
|
||||
// Should we use the alternate refernce frame
|
||||
if (cpi->oxcf.play_alternate &&
|
||||
cpi->oxcf.lag_in_frames &&
|
||||
if (allow_alt_ref &&
|
||||
(i >= MIN_GF_INTERVAL) &&
|
||||
(i <= (cpi->frames_to_key - MIN_GF_INTERVAL)) && // dont use ARF very near next kf
|
||||
// dont use ARF very near next kf
|
||||
(i <= (cpi->frames_to_key - MIN_GF_INTERVAL)) &&
|
||||
(((next_frame.pcnt_inter > 0.75) &&
|
||||
((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) &&
|
||||
//(cpi->gfu_boost>150) &&
|
||||
|
@ -3853,7 +3853,7 @@ static void encode_frame_to_data_rate
|
||||
// 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)
|
||||
{
|
||||
@ -4188,7 +4188,7 @@ static void encode_frame_to_data_rate
|
||||
IF_RTCD(&cpi->rtcd.variance));
|
||||
|
||||
// The key frame is not good enough
|
||||
if ( kf_err > ((cpi->ambient_err * 3) >> 2) )
|
||||
if ( kf_err > ((cpi->ambient_err * 7) >> 3) )
|
||||
{
|
||||
// Lower q_high
|
||||
q_high = (Q > q_low) ? (Q - 1) : q_low;
|
||||
|
Loading…
x
Reference in New Issue
Block a user