• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
set_offsets_for_motion_search(const AV1_COMP * const cpi,MACROBLOCK * const x,int mi_row,int mi_col,BLOCK_SIZE bsize)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 
init_simple_motion_search_mvs(PC_TREE * pc_tree)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 
is_full_sb(AV1_COMMON * const cm,int mi_row,int mi_col,BLOCK_SIZE sb_size)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 
use_auto_max_partition(AV1_COMP * const cpi,BLOCK_SIZE sb_size,int mi_row,int mi_col)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