| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_firstpass.c b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| index 9752668b15df0bba9cb9c6b08b524dcef71a1ec4..856a6655c7a37a561eb6b0ea22aa40bed3c2fce3 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_firstpass.c
|
| @@ -12,9 +12,11 @@
|
| #include <math.h>
|
| #include <stdio.h>
|
|
|
| +#include "./vpx_dsp_rtcd.h"
|
| #include "./vpx_scale_rtcd.h"
|
|
|
| #include "vpx_mem/vpx_mem.h"
|
| +#include "vpx_ports/mem.h"
|
| #include "vpx_scale/vpx_scale.h"
|
| #include "vpx_scale/yv12config.h"
|
|
|
| @@ -266,13 +268,13 @@ void vp9_end_first_pass(VP9_COMP *cpi) {
|
| static vp9_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
|
| switch (bsize) {
|
| case BLOCK_8X8:
|
| - return vp9_mse8x8;
|
| + return vpx_mse8x8;
|
| case BLOCK_16X8:
|
| - return vp9_mse16x8;
|
| + return vpx_mse16x8;
|
| case BLOCK_8X16:
|
| - return vp9_mse8x16;
|
| + return vpx_mse8x16;
|
| default:
|
| - return vp9_mse16x16;
|
| + return vpx_mse16x16;
|
| }
|
| }
|
|
|
| @@ -292,37 +294,37 @@ static vp9_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
|
| default:
|
| switch (bsize) {
|
| case BLOCK_8X8:
|
| - return vp9_highbd_mse8x8;
|
| + return vpx_highbd_8_mse8x8;
|
| case BLOCK_16X8:
|
| - return vp9_highbd_mse16x8;
|
| + return vpx_highbd_8_mse16x8;
|
| case BLOCK_8X16:
|
| - return vp9_highbd_mse8x16;
|
| + return vpx_highbd_8_mse8x16;
|
| default:
|
| - return vp9_highbd_mse16x16;
|
| + return vpx_highbd_8_mse16x16;
|
| }
|
| break;
|
| case 10:
|
| switch (bsize) {
|
| case BLOCK_8X8:
|
| - return vp9_highbd_10_mse8x8;
|
| + return vpx_highbd_10_mse8x8;
|
| case BLOCK_16X8:
|
| - return vp9_highbd_10_mse16x8;
|
| + return vpx_highbd_10_mse16x8;
|
| case BLOCK_8X16:
|
| - return vp9_highbd_10_mse8x16;
|
| + return vpx_highbd_10_mse8x16;
|
| default:
|
| - return vp9_highbd_10_mse16x16;
|
| + return vpx_highbd_10_mse16x16;
|
| }
|
| break;
|
| case 12:
|
| switch (bsize) {
|
| case BLOCK_8X8:
|
| - return vp9_highbd_12_mse8x8;
|
| + return vpx_highbd_12_mse8x8;
|
| case BLOCK_16X8:
|
| - return vp9_highbd_12_mse16x8;
|
| + return vpx_highbd_12_mse16x8;
|
| case BLOCK_8X16:
|
| - return vp9_highbd_12_mse8x16;
|
| + return vpx_highbd_12_mse8x16;
|
| default:
|
| - return vp9_highbd_12_mse16x16;
|
| + return vpx_highbd_12_mse16x16;
|
| }
|
| break;
|
| }
|
| @@ -633,7 +635,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
| xd->mi[0]->mbmi.tx_size = use_dc_pred ?
|
| (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
|
| vp9_encode_intra_block_plane(x, bsize, 0);
|
| - this_error = vp9_get_mb_ss(x->plane[0].src_diff);
|
| + this_error = vpx_get_mb_ss(x->plane[0].src_diff);
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| if (cm->use_highbitdepth) {
|
| switch (cm->bit_depth) {
|
| @@ -1246,8 +1248,9 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
|
| twopass->modified_error_left = modified_error_total;
|
| }
|
|
|
| - // Reset the vbr bits off target counter
|
| + // Reset the vbr bits off target counters
|
| cpi->rc.vbr_bits_off_target = 0;
|
| + cpi->rc.vbr_bits_off_target_fast = 0;
|
|
|
| cpi->rc.rate_error_estimate = 0;
|
|
|
| @@ -1695,7 +1698,7 @@ static void allocate_gf_group_bits(VP9_COMP *cpi, int64_t gf_group_bits,
|
| mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
|
|
|
| // Allocate bits to the other frames in the group.
|
| - for (i = 0; i < rc->baseline_gf_interval - 1; ++i) {
|
| + for (i = 0; i < rc->baseline_gf_interval - rc->source_alt_ref_pending; ++i) {
|
| int arf_idx = 0;
|
| if (EOF == input_stats(twopass, &frame_stats))
|
| break;
|
| @@ -1933,8 +1936,26 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| // Was the group length constrained by the requirement for a new KF?
|
| rc->constrained_gf_group = (i >= rc->frames_to_key) ? 1 : 0;
|
|
|
| + // Should we use the alternate reference frame.
|
| + if (allow_alt_ref &&
|
| + (i < cpi->oxcf.lag_in_frames) &&
|
| + (i >= rc->min_gf_interval)) {
|
| + // Calculate the boost for alt ref.
|
| + rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
|
| + &b_boost);
|
| + rc->source_alt_ref_pending = 1;
|
| +
|
| + // Test to see if multi arf is appropriate.
|
| + cpi->multi_arf_enabled =
|
| + (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
|
| + (zero_motion_accumulator < 0.995)) ? 1 : 0;
|
| + } else {
|
| + rc->gfu_boost = MAX((int)boost_score, MIN_ARF_GF_BOOST);
|
| + rc->source_alt_ref_pending = 0;
|
| + }
|
| +
|
| // Set the interval until the next gf.
|
| - if (is_key_frame || rc->source_alt_ref_active)
|
| + if (is_key_frame || rc->source_alt_ref_pending)
|
| rc->baseline_gf_interval = i - 1;
|
| else
|
| rc->baseline_gf_interval = i;
|
| @@ -1959,24 +1980,6 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
|
|
| rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
|
|
| - // Should we use the alternate reference frame.
|
| - if (allow_alt_ref &&
|
| - (i < cpi->oxcf.lag_in_frames) &&
|
| - (i >= rc->min_gf_interval)) {
|
| - // Calculate the boost for alt ref.
|
| - rc->gfu_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost,
|
| - &b_boost);
|
| - rc->source_alt_ref_pending = 1;
|
| -
|
| - // Test to see if multi arf is appropriate.
|
| - cpi->multi_arf_enabled =
|
| - (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
|
| - (zero_motion_accumulator < 0.995)) ? 1 : 0;
|
| - } else {
|
| - rc->gfu_boost = MAX((int)boost_score, MIN_ARF_GF_BOOST);
|
| - rc->source_alt_ref_pending = 0;
|
| - }
|
| -
|
| // Reset the file position.
|
| reset_fpf_position(twopass, start_pos);
|
|
|
| @@ -2413,7 +2416,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
|
| }
|
|
|
| // Define the reference buffers that will be updated post encode.
|
| -void configure_buffer_updates(VP9_COMP *cpi) {
|
| +static void configure_buffer_updates(VP9_COMP *cpi) {
|
| TWO_PASS *const twopass = &cpi->twopass;
|
|
|
| cpi->rc.is_src_frame_alt_ref = 0;
|
| @@ -2460,7 +2463,7 @@ void configure_buffer_updates(VP9_COMP *cpi) {
|
| }
|
| }
|
|
|
| -int is_skippable_frame(const VP9_COMP *cpi) {
|
| +static int is_skippable_frame(const VP9_COMP *cpi) {
|
| // If the current frame does not have non-zero motion vector detected in the
|
| // first pass, and so do its previous and forward frames, then this frame
|
| // can be skipped for partition check, and the partition size is assigned
|
| @@ -2580,9 +2583,8 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
| cpi->ref_frame_flags &=
|
| (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
|
| lc->frames_from_key_frame = 0;
|
| - // Reset the empty frame resolution since we have a key frame.
|
| - cpi->svc.empty_frame_width = cm->width;
|
| - cpi->svc.empty_frame_height = cm->height;
|
| + // Encode an intra only empty frame since we have a key frame.
|
| + cpi->svc.encode_intra_empty_frame = 1;
|
| }
|
| } else {
|
| cm->frame_type = INTER_FRAME;
|
| @@ -2649,6 +2651,7 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|
|
| #define MINQ_ADJ_LIMIT 48
|
| #define MINQ_ADJ_LIMIT_CQ 20
|
| +#define HIGH_UNDERSHOOT_RATIO 2
|
| void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| TWO_PASS *const twopass = &cpi->twopass;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| @@ -2715,5 +2718,32 @@ void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
|
|
| twopass->extend_minq = clamp(twopass->extend_minq, 0, minq_adj_limit);
|
| twopass->extend_maxq = clamp(twopass->extend_maxq, 0, maxq_adj_limit);
|
| +
|
| + // If there is a big and undexpected undershoot then feed the extra
|
| + // bits back in quickly. One situation where this may happen is if a
|
| + // frame is unexpectedly almost perfectly predicted by the ARF or GF
|
| + // but not very well predcited by the previous frame.
|
| + if (!frame_is_kf_gf_arf(cpi) && !cpi->rc.is_src_frame_alt_ref) {
|
| + int fast_extra_thresh = rc->base_frame_target / HIGH_UNDERSHOOT_RATIO;
|
| + if (rc->projected_frame_size < fast_extra_thresh) {
|
| + rc->vbr_bits_off_target_fast +=
|
| + fast_extra_thresh - rc->projected_frame_size;
|
| + rc->vbr_bits_off_target_fast =
|
| + MIN(rc->vbr_bits_off_target_fast, (4 * rc->avg_frame_bandwidth));
|
| +
|
| + // Fast adaptation of minQ if necessary to use up the extra bits.
|
| + if (rc->avg_frame_bandwidth) {
|
| + twopass->extend_minq_fast =
|
| + (int)(rc->vbr_bits_off_target_fast * 8 / rc->avg_frame_bandwidth);
|
| + }
|
| + twopass->extend_minq_fast = MIN(twopass->extend_minq_fast,
|
| + minq_adj_limit - twopass->extend_minq);
|
| + } else if (rc->vbr_bits_off_target_fast) {
|
| + twopass->extend_minq_fast = MIN(twopass->extend_minq_fast,
|
| + minq_adj_limit - twopass->extend_minq);
|
| + } else {
|
| + twopass->extend_minq_fast = 0;
|
| + }
|
| + }
|
| }
|
| }
|
|
|