diff options
Diffstat (limited to 'vp9/encoder')
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 91 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 13 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 28 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 22 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 70 |
5 files changed, 137 insertions, 87 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 45758e7cb..6a70e8e9d 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1547,7 +1547,7 @@ static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO * mi, // Look at neighboring blocks and set a min and max partition size based on // what they chose. -static void rd_auto_partition_range(VP9_COMP *cpi, +static void rd_auto_partition_range(VP9_COMP *cpi, int row, int col, BLOCK_SIZE *min_block_size, BLOCK_SIZE *max_block_size) { MACROBLOCKD *const xd = &cpi->mb.e_mbd; @@ -1565,38 +1565,48 @@ static void rd_auto_partition_range(VP9_COMP *cpi, cpi->sf.auto_min_max_partition_interval; *min_block_size = BLOCK_4X4; *max_block_size = BLOCK_64X64; - return; } else { --cpi->sf.auto_min_max_partition_count; - } - // Set default values if not left or above neighbour - if (!left_in_image && !above_in_image) { - *min_block_size = BLOCK_4X4; - *max_block_size = BLOCK_64X64; - } else { - // Default "min to max" and "max to min" - *min_block_size = BLOCK_64X64; - *max_block_size = BLOCK_4X4; - - // Find the min and max partition sizes used in the left SB64 - if (left_in_image) { - left_sb64_mi = &mi[-MI_BLOCK_SIZE]; - get_sb_partition_size_range(cpi, left_sb64_mi, - min_block_size, max_block_size); - } + // Set default values if no left or above neighbour + if (!left_in_image && !above_in_image) { + *min_block_size = BLOCK_4X4; + *max_block_size = BLOCK_64X64; + } else { + VP9_COMMON *const cm = &cpi->common; + int row8x8_remaining = cm->cur_tile_mi_row_end - row; + int col8x8_remaining = cm->cur_tile_mi_col_end - col; + int bh, bw; + + // Default "min to max" and "max to min" + *min_block_size = BLOCK_64X64; + *max_block_size = BLOCK_4X4; + + // Find the min and max partition sizes used in the left SB64 + if (left_in_image) { + left_sb64_mi = &mi[-MI_BLOCK_SIZE]; + get_sb_partition_size_range(cpi, left_sb64_mi, + min_block_size, max_block_size); + } - // Find the min and max partition sizes used in the above SB64 taking - // the values found for left as a starting point. - if (above_in_image) { - above_sb64_mi = &mi[-xd->mode_info_stride * MI_BLOCK_SIZE]; - get_sb_partition_size_range(cpi, above_sb64_mi, - min_block_size, max_block_size); - } + // Find the min and max partition sizes used in the above SB64 taking + // the values found for left as a starting point. + if (above_in_image) { + above_sb64_mi = &mi[-xd->mode_info_stride * MI_BLOCK_SIZE]; + get_sb_partition_size_range(cpi, above_sb64_mi, + min_block_size, max_block_size); + } + + // Give a bit of leaway either side of the observed min and max + *min_block_size = min_partition_size[*min_block_size]; + *max_block_size = max_partition_size[*max_block_size]; - // give a bit of leaway either side of the observed min and max - *min_block_size = min_partition_size[*min_block_size]; - *max_block_size = max_partition_size[*max_block_size]; + // Check border cases where max and min from neighbours may not be legal. + *max_block_size = find_partition_size(*max_block_size, + row8x8_remaining, col8x8_remaining, + &bh, &bw); + *min_block_size = MIN(*min_block_size, *max_block_size); + } } } @@ -1780,11 +1790,24 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, } sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); if (sum_rd < best_rd) { + int64_t stop_thresh = 2048; + best_rate = this_rate; best_dist = this_dist; best_rd = sum_rd; if (bsize >= BLOCK_8X8) *(get_sb_partitioning(x, bsize)) = bsize; + + // Adjust threshold according to partition size. + stop_thresh >>= 8 - (b_width_log2_lookup[bsize] + + b_height_log2_lookup[bsize]); + + // If obtained distortion is very small, choose current partition + // and stop splitting. + if (this_dist < stop_thresh) { + do_split = 0; + do_rect = 0; + } } } restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); @@ -1989,13 +2012,6 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, int dummy_rate; int64_t dummy_dist; - // Initialize a mask of modes that we will not consider; - // cpi->unused_mode_skip_mask = 0x0000000AAE17F800 (test no golden) - if (cpi->common.frame_type == KEY_FRAME) - cpi->unused_mode_skip_mask = 0; - else - cpi->unused_mode_skip_mask = 0xFFFFFFFFFFFFFE00; - if (cpi->sf.reference_masking) rd_pick_reference_frame(cpi, mi_row, mi_col); @@ -2025,7 +2041,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, // If required set upper and lower partition size limits if (cpi->sf.auto_min_max_partition_size) { set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); - rd_auto_partition_range(cpi, + rd_auto_partition_range(cpi, mi_row, mi_col, &cpi->sf.min_partition_size, &cpi->sf.max_partition_size); } @@ -2041,7 +2057,8 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, // If required set upper and lower partition size limits if (cpi->sf.auto_min_max_partition_size) { set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); - rd_auto_partition_range(cpi, &cpi->sf.min_partition_size, + rd_auto_partition_range(cpi, mi_row, mi_col, + &cpi->sf.min_partition_size, &cpi->sf.max_partition_size); } diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 0cbe3abb8..c5b348582 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1717,6 +1717,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { old_boost_score = boost_score; } + cpi->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); + // Don't allow a gf too near the next kf if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) { while (i < cpi->twopass.frames_to_key) { @@ -2162,6 +2164,8 @@ void vp9_second_pass(VP9_COMP *cpi) { // Define next gf group and assign bits to it this_frame_copy = this_frame; + cpi->gf_zeromotion_pct = 0; + #if CONFIG_MULTIPLE_ARF if (cpi->multi_arf_enabled) { define_fixed_arf_period(cpi); @@ -2172,6 +2176,15 @@ void vp9_second_pass(VP9_COMP *cpi) { } #endif + if (cpi->gf_zeromotion_pct > 995) { + // As long as max_thresh for encode breakout is small enough, it is ok + // to enable it for no-show frame, i.e. set enable_encode_breakout to 2. + if (!cpi->common.show_frame) + cpi->enable_encode_breakout = 0; + else + cpi->enable_encode_breakout = 2; + } + // If we are going to code an altref frame at the end of the group // and the current frame is not a key frame.... // If the previous group used an arf this frame has already benefited diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 1484bbb54..f47025325 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -743,9 +743,8 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->use_fast_lpf_pick = 0; sf->use_fast_coef_updates = 0; sf->using_small_partition_info = 0; - // Skip any mode not chosen at size < X for all sizes > X - // Hence BLOCK_64X64 (skip is off) - sf->unused_mode_skip_lvl = BLOCK_64X64; + sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set + #if CONFIG_MULTIPLE_ARF // Switch segmentation off. @@ -782,7 +781,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) { cpi->common.show_frame == 0); sf->disable_splitmv = (MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0; - sf->unused_mode_skip_lvl = BLOCK_32X32; sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA | @@ -804,6 +802,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->intra_y_mode_mask = INTRA_DC_TM_H_V; sf->intra_uv_mode_mask = INTRA_DC_TM_H_V; sf->use_fast_coef_updates = 1; + sf->mode_skip_start = 9; } if (speed == 2) { sf->adjust_thresholds_by_speed = 1; @@ -813,7 +812,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->use_lastframe_partitioning = 1; sf->adjust_partitioning_from_last_frame = 1; sf->last_partitioning_redo_frequency = 3; - sf->unused_mode_skip_lvl = BLOCK_32X32; sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME || cpi->common.intra_only || cpi->common.show_frame == 0) ? @@ -843,6 +841,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->disable_split_var_thresh = 32; sf->disable_filter_search_var_thresh = 32; sf->use_fast_coef_updates = 2; + sf->mode_skip_start = 9; } if (speed == 3) { sf->comp_inter_joint_search_thresh = BLOCK_SIZES; @@ -870,6 +869,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->intra_y_mode_mask = INTRA_DC_ONLY; sf->intra_uv_mode_mask = INTRA_DC_ONLY; sf->use_fast_coef_updates = 2; + sf->mode_skip_start = 9; } if (speed == 4) { sf->comp_inter_joint_search_thresh = BLOCK_SIZES; @@ -901,20 +901,8 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->intra_y_mode_mask = INTRA_DC_ONLY; sf->intra_uv_mode_mask = INTRA_DC_ONLY; sf->use_fast_coef_updates = 2; + sf->mode_skip_start = 9; } - /* - if (speed == 2) { - sf->first_step = 0; - sf->comp_inter_joint_search_thresh = BLOCK_8X8; - sf->max_partition_size = BLOCK_16X16; - } - if (speed == 3) { - sf->first_step = 0; - sf->comp_inter_joint_search_thresh = BLOCK_B8X8; - sf->min_partition_size = BLOCK_8X8; - } - */ - break; }; /* switch */ @@ -1602,6 +1590,8 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->output_pkt_list = oxcf->output_pkt_list; + cpi->enable_encode_breakout = 1; + if (cpi->pass == 1) { vp9_init_first_pass(cpi); } else if (cpi->pass == 2) { @@ -3615,6 +3605,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) { + cpi->enable_encode_breakout = 1; + if (!cpi->refresh_alt_ref_frame) vp9_second_pass(cpi); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 2dbd7a01a..d83c3f7e0 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -147,18 +147,19 @@ typedef struct { // const MODE_DEFINITION vp9_mode_order[MAX_MODES] used in the rd code. typedef enum { THR_NEARESTMV, - THR_DC, - THR_NEARESTA, THR_NEARESTG, - THR_NEWMV, - THR_COMP_NEARESTLA, - THR_NEARMV, - THR_COMP_NEARESTGA, - THR_NEWG, + THR_DC, + + THR_NEWMV, THR_NEWA, + THR_NEWG, + + THR_NEARMV, THR_NEARA, + THR_COMP_NEARESTLA, + THR_COMP_NEARESTGA, THR_TM, @@ -273,7 +274,7 @@ typedef struct { int use_one_partition_size_always; int less_rectangular_check; int use_square_partition_only; - int unused_mode_skip_lvl; + int mode_skip_start; int reference_masking; BLOCK_SIZE always_this_block_size; int auto_min_max_partition_size; @@ -384,7 +385,7 @@ typedef struct VP9_COMP { unsigned int mode_check_freq[MAX_MODES]; unsigned int mode_test_hit_counts[MAX_MODES]; unsigned int mode_chosen_counts[MAX_MODES]; - int64_t unused_mode_skip_mask; + int64_t mode_skip_mask; int ref_frame_mask; int set_ref_frame_mask; @@ -494,6 +495,7 @@ typedef struct VP9_COMP { int last_boost; int kf_boost; int kf_zeromotion_pct; + int gf_zeromotion_pct; int64_t target_bandwidth; struct vpx_codec_pkt_list *output_pkt_list; @@ -655,6 +657,8 @@ typedef struct VP9_COMP { int initial_height; int number_spatial_layers; + int enable_encode_breakout; // Default value is 1. From first pass stats, + // encode_breakout may be disabled. #if CONFIG_MULTIPLE_ARF // ARF tracking variables. diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 41e43fe50..07850d4f6 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -51,20 +51,25 @@ DECLARE_ALIGNED(16, extern const uint8_t, #define I4X4_PRED 0x8000 #define SPLITMV 0x10000 +#define LAST_FRAME_MODE_MASK 0xFFDADCD60 +#define GOLDEN_FRAME_MODE_MASK 0xFFB5A3BB0 +#define ALT_REF_MODE_MASK 0xFF8C648D0 + const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { {NEARESTMV, LAST_FRAME, NONE}, - {DC_PRED, INTRA_FRAME, NONE}, - {NEARESTMV, ALTREF_FRAME, NONE}, {NEARESTMV, GOLDEN_FRAME, NONE}, - {NEWMV, LAST_FRAME, NONE}, - {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, - {NEARMV, LAST_FRAME, NONE}, - {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, - {NEWMV, GOLDEN_FRAME, NONE}, + {DC_PRED, INTRA_FRAME, NONE}, + + {NEWMV, LAST_FRAME, NONE}, {NEWMV, ALTREF_FRAME, NONE}, + {NEWMV, GOLDEN_FRAME, NONE}, + + {NEARMV, LAST_FRAME, NONE}, {NEARMV, ALTREF_FRAME, NONE}, + {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, + {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, {TM_PRED, INTRA_FRAME, NONE}, @@ -2856,7 +2861,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (cpi->common.mcomp_filter_type == SWITCHABLE) *rate2 += get_switchable_rate(x); - if (!is_comp_pred) { + if (!is_comp_pred && cpi->enable_encode_breakout) { if (cpi->active_map_enabled && x->active_ptr[0] == 0) x->skip = 1; else if (x->encode_breakout) { @@ -2867,18 +2872,23 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, unsigned int thresh_ac; // The encode_breakout input unsigned int encode_breakout = x->encode_breakout << 4; + int max_thresh = 36000; + + // Use extreme low threshold for static frames to limit skipping. + if (cpi->enable_encode_breakout == 2) + max_thresh = 128; // Calculate threshold according to dequant value. thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9; - // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. - if (thresh_ac > 36000) - thresh_ac = 36000; - // Use encode_breakout input if it is bigger than internal threshold. if (thresh_ac < encode_breakout) thresh_ac = encode_breakout; + // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. + if (thresh_ac > max_thresh) + thresh_ac = max_thresh; + var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf, xd->plane[0].dst.stride, &sse); @@ -3187,10 +3197,31 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, ref_frame = vp9_mode_order[mode_index].ref_frame; second_ref_frame = vp9_mode_order[mode_index].second_ref_frame; - // Skip modes that have been masked off but always consider first mode. - if (mode_index && (bsize > cpi->sf.unused_mode_skip_lvl) && - (cpi->unused_mode_skip_mask & (1 << mode_index)) ) - continue; + // Look at the reference frame of the best mode so far and set the + // skip mask to look at a subset of the remaining modes. + if (mode_index > cpi->sf.mode_skip_start) { + if (mode_index == (cpi->sf.mode_skip_start + 1)) { + switch (vp9_mode_order[best_mode_index].ref_frame) { + case INTRA_FRAME: + cpi->mode_skip_mask = 0; + break; + case LAST_FRAME: + cpi->mode_skip_mask = LAST_FRAME_MODE_MASK; + break; + case GOLDEN_FRAME: + cpi->mode_skip_mask = GOLDEN_FRAME_MODE_MASK; + break; + case ALTREF_FRAME: + cpi->mode_skip_mask = ALT_REF_MODE_MASK; + break; + case NONE: + case MAX_REF_FRAMES: + assert(!"Invalid Reference frame"); + } + } + if (cpi->mode_skip_mask & (1 << mode_index)) + continue; + } // Skip if the current reference frame has been masked off if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask && @@ -3859,13 +3890,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - // If indicated then mark the index of the chosen mode to be inspected at - // other block sizes. - if (bsize <= cpi->sf.unused_mode_skip_lvl) { - cpi->unused_mode_skip_mask = cpi->unused_mode_skip_mask & - (~((int64_t)1 << best_mode_index)); - } - // If we are using reference masking and the set mask flag is set then // create the reference frame mask. if (cpi->sf.reference_masking && cpi->set_ref_frame_mask) |