1 /* 2 * Copyright (c) 2019, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AV1_ENCODER_PARTITION_STRATEGY_H_ 13 #define AOM_AV1_ENCODER_PARTITION_STRATEGY_H_ 14 15 #include "av1/encoder/encodeframe.h" 16 #include "av1/encoder/encodemb.h" 17 #include "av1/encoder/encoder.h" 18 19 #define FEATURE_SIZE_SMS_PRUNE_PART 25 20 #define FEATURE_SIZE_SMS_TERM_NONE 28 21 #define FEATURE_SIZE_FP_SMS_TERM_NONE 20 22 #define FEATURE_SIZE_MAX_MIN_PART_PRED 13 23 #define MAX_NUM_CLASSES_MAX_MIN_PART_PRED 4 24 25 // Performs a simple_motion_search with a single reference frame and extract 26 // the variance of residues. Then use the features to determine whether we want 27 // to go straight to splitting without trying PARTITION_NONE 28 void av1_simple_motion_search_based_split( 29 AV1_COMP *const cpi, MACROBLOCK *x, int mi_row, int mi_col, 30 BLOCK_SIZE bsize, int *partition_none_allowed, int *partition_horz_allowed, 31 int *partition_vert_allowed, int *do_rectangular_split, 32 int *do_square_split); 33 34 // Performs a simple_motion_search with two reference frames and extract 35 // the variance of residues. Then use the features to determine whether we want 36 // to prune some partitions. 37 void av1_simple_motion_search_prune_part( 38 AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row, 39 int mi_col, BLOCK_SIZE bsize, int *partition_none_allowed, 40 int *partition_horz_allowed, int *partition_vert_allowed, 41 int *do_square_split, int *do_rectangular_split, int *prune_horz, 42 int *prune_vert, float *features, int *valid); 43 44 // Early terminates PARTITION_NONE using simple_motion_search features and the 45 // rate, distortion, and rdcost of PARTITION_NONE. This is only called when: 46 // - The frame is a show frame 47 // - The frame is not intra only 48 // - The current bsize is > BLOCK_8X8 49 // - blk_row + blk_height/2 < total_rows and blk_col + blk_width/2 < total_cols 50 void av1_simple_motion_search_early_term_none( 51 AV1_COMP *const cpi, MACROBLOCK *x, PC_TREE *pc_tree, int mi_row, 52 int mi_col, BLOCK_SIZE bsize, const RD_STATS *none_rdc, 53 int *early_terminate, float *simple_motion_features, 54 int *simple_motion_features_are_valid); 55 56 // Early terminates after PARTITION_NONE in firstpass of two pass partition 57 // search. 58 void av1_firstpass_simple_motion_search_early_term(AV1_COMP *const cpi, 59 MACROBLOCK *x, 60 PC_TREE *pc_tree, int mi_row, 61 int mi_col, BLOCK_SIZE bsize, 62 const RD_STATS *none_rdc, 63 int *do_square_split); 64 65 // Get the features for selecting the max and min partition size. Currently this 66 // performs simple_motion_search on 16X16 subblocks of the currnet superblock, 67 // and then extract the statistics of sse and motion vectors as features. 68 void av1_get_max_min_partition_features(AV1_COMP *const cpi, MACROBLOCK *x, 69 int mi_row, int mi_col, 70 float *features); 71 72 // Predict the maximum BLOCK_SIZE to be used to encoder the current superblock. 73 BLOCK_SIZE av1_predict_max_partition(AV1_COMP *const cpi, MACROBLOCK *const x, 74 const float *features); 75 76 // A simplified version of set_offsets meant to be used for 77 // simple_motion_search. 78 static INLINE void set_offsets_for_motion_search(const AV1_COMP *const cpi, 79 MACROBLOCK *const x, 80 int mi_row, int mi_col, 81 BLOCK_SIZE bsize) { 82 const AV1_COMMON *const cm = &cpi->common; 83 const int num_planes = av1_num_planes(cm); 84 MACROBLOCKD *const xd = &x->e_mbd; 85 const int mi_width = mi_size_wide[bsize]; 86 const int mi_height = mi_size_high[bsize]; 87 88 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col); 89 90 // Set up destination pointers. 91 av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row, mi_col, 0, 92 num_planes); 93 94 // Set up limit values for MV components. 95 // Mv beyond the range do not produce new/different prediction block. 96 x->mv_limits.row_min = 97 -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND); 98 x->mv_limits.col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND); 99 x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND; 100 x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND; 101 102 set_plane_n4(xd, mi_width, mi_height, num_planes); 103 104 // Set up distance of MB to edge of frame in 1/8th pel units. 105 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); 106 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); 107 xd->mb_to_bottom_edge = ((cm->mi_rows - mi_height - mi_row) * MI_SIZE) * 8; 108 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); 109 xd->mb_to_right_edge = ((cm->mi_cols - mi_width - mi_col) * MI_SIZE) * 8; 110 111 // Set up source buffers. 112 av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, bsize); 113 114 // R/D setup. 115 x->rdmult = cpi->rd.RDMULT; 116 } 117 118 static INLINE void init_simple_motion_search_mvs(PC_TREE *pc_tree) { 119 for (int idx = 0; idx < REF_FRAMES; idx++) { 120 pc_tree->mv_ref_fulls[idx].row = 0; 121 pc_tree->mv_ref_fulls[idx].col = 0; 122 } 123 if (pc_tree->block_size >= BLOCK_8X8) { 124 init_simple_motion_search_mvs(pc_tree->split[0]); 125 init_simple_motion_search_mvs(pc_tree->split[1]); 126 init_simple_motion_search_mvs(pc_tree->split[2]); 127 init_simple_motion_search_mvs(pc_tree->split[3]); 128 } 129 } 130 131 static INLINE int is_full_sb(AV1_COMMON *const cm, int mi_row, int mi_col, 132 BLOCK_SIZE sb_size) { 133 const int sb_mi_wide = mi_size_wide[sb_size]; 134 const int sb_mi_high = mi_size_high[sb_size]; 135 136 return (mi_row + sb_mi_high) <= cm->mi_rows && 137 (mi_col + sb_mi_wide) <= cm->mi_cols; 138 } 139 140 static INLINE int use_auto_max_partition(AV1_COMP *const cpi, 141 BLOCK_SIZE sb_size, int mi_row, 142 int mi_col) { 143 AV1_COMMON *const cm = &cpi->common; 144 145 return !frame_is_intra_only(cm) && 146 cpi->sf.auto_max_partition_based_on_simple_motion != NOT_IN_USE && 147 sb_size == BLOCK_128X128 && is_full_sb(cm, mi_row, mi_col, sb_size) && 148 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index] != 149 OVERLAY_UPDATE && 150 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index] != 151 INTNL_OVERLAY_UPDATE; 152 } 153 154 #endif // AOM_AV1_ENCODER_PARTITION_STRATEGY_H_ 155