Two pass refactoring continued.

Remove testing of whether we estimate that it will be possible
to code an arf at a lower Q than the ambient Q.  This adds quite
a bit of extra code and complexity for marginal gain.

Factored out some code relating to ARNR selection to a separate
function as this is likely to be changed / simplified soon.

Change-Id: Ia1cf060405637ef5bbf7018355437be21d12375f
This commit is contained in:
Paul Wilkins 2012-05-14 15:13:26 +01:00
parent 59a5c7d550
commit e237fd7c5a

View File

@ -807,6 +807,9 @@ void vp8_first_pass(VP8_COMP *cpi)
{
vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
}
{
vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
}
// swap frame pointers so last frame refers to the frame we just compressed
vp8_swap_yv12_buffer(lst_yv12, new_yv12);
@ -1148,50 +1151,6 @@ static int estimate_cq( VP8_COMP *cpi,
return Q;
}
static int estimate_q(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 err_correction_factor;
double corr_high;
double speed_correction = 1.0;
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 == 1)
{
if (cpi->oxcf.cpu_used <= 5)
speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
else
speed_correction = 1.25;
}
// 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, ERR_DIVISOR, 0.36, 0.90, Q);
bits_per_mb_at_this_q =
(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;
}
return Q;
}
// Estimate a worst case Q for a KF group
static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, double group_iiratio)
{
@ -1677,6 +1636,59 @@ static int calc_arf_boost(
return (*f_boost + *b_boost);
}
static void configure_arnr_filter( VP8_COMP *cpi, FIRSTPASS_STATS *this_frame )
{
int half_gf_int;
int frames_after_arf;
int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
// Define the arnr filter width for this group of frames:
// We only filter frames that lie within a distance of half
// the GF interval from the ARF frame. We also have to trap
// cases where the filter extends beyond the end of clip.
// Note: this_frame->frame has been updated in the loop
// so it now points at the ARF frame.
half_gf_int = cpi->baseline_gf_interval >> 1;
frames_after_arf = cpi->twopass.total_stats->count -
this_frame->frame - 1;
switch (cpi->oxcf.arnr_type)
{
case 1: // Backward filter
frames_fwd = 0;
if (frames_bwd > half_gf_int)
frames_bwd = half_gf_int;
break;
case 2: // Forward filter
if (frames_fwd > half_gf_int)
frames_fwd = half_gf_int;
if (frames_fwd > frames_after_arf)
frames_fwd = frames_after_arf;
frames_bwd = 0;
break;
case 3: // Centered filter
default:
frames_fwd >>= 1;
if (frames_fwd > frames_after_arf)
frames_fwd = frames_after_arf;
if (frames_fwd > half_gf_int)
frames_fwd = half_gf_int;
frames_bwd = frames_fwd;
// For even length filter there is one more frame backward
// than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
if (frames_bwd < half_gf_int)
frames_bwd += (cpi->oxcf.arnr_max_frames+1) & 0x1;
break;
}
cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
}
// Analyse and define a gf/arf group .
static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
{
@ -1834,6 +1846,9 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Alterrnative boost calculation for alt ref
alt_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost );
// Set the interval till the next gf or arf.
cpi->baseline_gf_interval = i;
// Should we use the alternate refernce frame
if (allow_alt_ref &&
(i < cpi->oxcf.lag_in_frames ) &&
@ -1846,139 +1861,16 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
(mv_in_out_accumulator > -2.0)) &&
(b_boost > 100) &&
(f_boost > 100) )
{
int Boost;
int allocation_chunks;
int Q = (cpi->oxcf.fixed_q < 0)
? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
int tmp_q;
int arf_frame_bits = 0;
int group_bits;
cpi->gfu_boost = alt_boost;
cpi->source_alt_ref_pending = TRUE;
// Estimate the bits to be allocated to the group as a whole
if ((cpi->twopass.kf_group_bits > 0) &&
(cpi->twopass.kf_group_error_left > 0))
{
group_bits = (int)((double)cpi->twopass.kf_group_bits *
(gf_group_err / (double)cpi->twopass.kf_group_error_left));
}
else
group_bits = 0;
// Boost for arf frame
Boost = (alt_boost * vp8_gfboost_qadjust(Q)) / 100;
Boost += (i * 50);
// Set max and minimum boost and hence minimum allocation
if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
Boost = ((cpi->baseline_gf_interval + 1) * 200);
else if (Boost < 125)
Boost = 125;
allocation_chunks = (i * 100) + Boost;
// Prevent overflow
if ( Boost > 1028 )
{
int divisor = Boost >> 10;
Boost /= divisor;
allocation_chunks /= divisor;
}
// Calculate the number of bits to be spent on the arf based on the
// boost number
arf_frame_bits = (int)((double)Boost * (group_bits /
(double)allocation_chunks));
// Estimate if there are enough bits available to make worthwhile use
// of an arf.
tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits);
// Only use an arf if it is likely we will be able to code
// it at a lower Q than the surrounding frames.
if (tmp_q < cpi->worst_quality)
{
int half_gf_int;
int frames_after_arf;
int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
cpi->source_alt_ref_pending = TRUE;
// For alt ref frames the error score for the end frame of the
// group (the alt ref frame) should not contribute to the group
// total and hence the number of bit allocated to the group.
// Rather it forms part of the next group (it is the GF at the
// start of the next group)
// gf_group_err -= mod_frame_err;
// For alt ref frames alt ref frame is technically part of the
// GF frame for the next group but we always base the error
// calculation and bit allocation on the current group of frames.
// Set the interval till the next gf or arf.
// For ARFs this is the number of frames to be coded before the
// future frame that is coded as an ARF.
// The future frame itself is part of the next group
cpi->baseline_gf_interval = i;
// Define the arnr filter width for this group of frames:
// We only filter frames that lie within a distance of half
// the GF interval from the ARF frame. We also have to trap
// cases where the filter extends beyond the end of clip.
// Note: this_frame->frame has been updated in the loop
// so it now points at the ARF frame.
half_gf_int = cpi->baseline_gf_interval >> 1;
frames_after_arf = cpi->twopass.total_stats->count -
this_frame->frame - 1;
switch (cpi->oxcf.arnr_type)
{
case 1: // Backward filter
frames_fwd = 0;
if (frames_bwd > half_gf_int)
frames_bwd = half_gf_int;
break;
case 2: // Forward filter
if (frames_fwd > half_gf_int)
frames_fwd = half_gf_int;
if (frames_fwd > frames_after_arf)
frames_fwd = frames_after_arf;
frames_bwd = 0;
break;
case 3: // Centered filter
default:
frames_fwd >>= 1;
if (frames_fwd > frames_after_arf)
frames_fwd = frames_after_arf;
if (frames_fwd > half_gf_int)
frames_fwd = half_gf_int;
frames_bwd = frames_fwd;
// For even length filter there is one more frame backward
// than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
if (frames_bwd < half_gf_int)
frames_bwd += (cpi->oxcf.arnr_max_frames+1) & 0x1;
break;
}
cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
}
else
{
cpi->source_alt_ref_pending = FALSE;
cpi->baseline_gf_interval = i;
}
configure_arnr_filter( cpi, this_frame );
}
else
{
cpi->source_alt_ref_pending = FALSE;
cpi->baseline_gf_interval = i;
}
// Now decide how many bits should be allocated to the GF group as a