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; |
+ } |
+ } |
} |
} |