Home | History | Annotate | Download | only in encoder
      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