From: Paul Wilkins Date: Mon, 14 May 2012 14:13:26 +0000 (+0100) Subject: Two pass refactoring continued. X-Git-Tag: v1.3.0~1217^2~379^2~35^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e237fd7c5ad8c0caf341ca50a4ea65495edce74f;p=libvpx 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 --- diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index d19cba838..32006c72d 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -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