• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, 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_NONRD_OPT_H_
13 #define AOM_AV1_ENCODER_NONRD_OPT_H_
14 
15 #include "av1/encoder/rdopt_utils.h"
16 
17 #define RTC_INTER_MODES (4)
18 #define RTC_INTRA_MODES (4)
19 #define RTC_MODES (AOMMAX(RTC_INTER_MODES, RTC_INTRA_MODES))
20 
21 static const PREDICTION_MODE intra_mode_list[] = { DC_PRED, V_PRED, H_PRED,
22                                                    SMOOTH_PRED };
23 
24 static const PREDICTION_MODE inter_mode_list[] = { NEARESTMV, NEARMV, GLOBALMV,
25                                                    NEWMV };
26 
27 static const THR_MODES mode_idx[REF_FRAMES][RTC_MODES] = {
28   { THR_DC, THR_V_PRED, THR_H_PRED, THR_SMOOTH },
29   { THR_NEARESTMV, THR_NEARMV, THR_GLOBALMV, THR_NEWMV },
30   { THR_NEARESTL2, THR_NEARL2, THR_GLOBALL2, THR_NEWL2 },
31   { THR_NEARESTL3, THR_NEARL3, THR_GLOBALL3, THR_NEWL3 },
32   { THR_NEARESTG, THR_NEARG, THR_GLOBALG, THR_NEWG },
33   { THR_NEARESTB, THR_NEARB, THR_GLOBALB, THR_NEWB },
34   { THR_NEARESTA2, THR_NEARA2, THR_GLOBALA2, THR_NEWA2 },
35   { THR_NEARESTA, THR_NEARA, THR_GLOBALA, THR_NEWA },
36 };
37 
38 // Indicates the blocks for which RD model should be based on special logic
get_model_rd_flag(const AV1_COMP * cpi,const MACROBLOCKD * xd,BLOCK_SIZE bsize)39 static INLINE int get_model_rd_flag(const AV1_COMP *cpi, const MACROBLOCKD *xd,
40                                     BLOCK_SIZE bsize) {
41   const int large_block = bsize >= BLOCK_32X32;
42   const AV1_COMMON *const cm = &cpi->common;
43   return cpi->oxcf.rc_cfg.mode == AOM_CBR && large_block &&
44          !cyclic_refresh_segment_id_boosted(xd->mi[0]->segment_id) &&
45          cm->quant_params.base_qindex &&
46          cm->seq_params->bit_depth == AOM_BITS_8;
47 }
48 /*!\brief Finds predicted motion vectors for a block.
49  *
50  * \ingroup nonrd_mode_search
51  * \callgraph
52  * \callergraph
53  * Finds predicted motion vectors for a block from a certain reference frame.
54  * First, it fills reference MV stack, then picks the test from the stack and
55  * predicts the final MV for a block for each mode.
56  * \param[in]    cpi                      Top-level encoder structure
57  * \param[in]    x                        Pointer to structure holding all the
58  *                                        data for the current macroblock
59  * \param[in]    ref_frame                Reference frame for which to find
60  *                                        ref MVs
61  * \param[in]    frame_mv                 Predicted MVs for a block
62  * \param[in]    tile_data                Pointer to struct holding adaptive
63  *                                        data/contexts/models for the tile
64  *                                        during encoding
65  * \param[in]    yv12_mb                  Buffer to hold predicted block
66  * \param[in]    bsize                    Current block size
67  * \param[in]    force_skip_low_temp_var  Flag indicating possible mode search
68  *                                        prune for low temporal variance block
69  * \param[in]    skip_pred_mv             Flag indicating to skip av1_mv_pred
70  *
71  * \remark Nothing is returned. Instead, predicted MVs are placed into
72  * \c frame_mv array
73  */
find_predictors(AV1_COMP * cpi,MACROBLOCK * x,MV_REFERENCE_FRAME ref_frame,int_mv frame_mv[MB_MODE_COUNT][REF_FRAMES],TileDataEnc * tile_data,struct buf_2d yv12_mb[8][MAX_MB_PLANE],BLOCK_SIZE bsize,int force_skip_low_temp_var,int skip_pred_mv)74 static INLINE void find_predictors(
75     AV1_COMP *cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
76     int_mv frame_mv[MB_MODE_COUNT][REF_FRAMES], TileDataEnc *tile_data,
77     struct buf_2d yv12_mb[8][MAX_MB_PLANE], BLOCK_SIZE bsize,
78     int force_skip_low_temp_var, int skip_pred_mv) {
79   AV1_COMMON *const cm = &cpi->common;
80   MACROBLOCKD *const xd = &x->e_mbd;
81   MB_MODE_INFO *const mbmi = xd->mi[0];
82   MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
83   const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, ref_frame);
84   const int num_planes = av1_num_planes(cm);
85   (void)tile_data;
86 
87   x->pred_mv_sad[ref_frame] = INT_MAX;
88   x->pred_mv0_sad[ref_frame] = INT_MAX;
89   x->pred_mv1_sad[ref_frame] = INT_MAX;
90   frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
91   // TODO(kyslov) this needs various further optimizations. to be continued..
92   assert(yv12 != NULL);
93   if (yv12 != NULL) {
94     const struct scale_factors *const sf =
95         get_ref_scale_factors_const(cm, ref_frame);
96     av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, sf, sf, num_planes);
97     av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
98                      xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs,
99                      mbmi_ext->mode_context);
100     // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
101     // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
102     av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
103     av1_find_best_ref_mvs_from_stack(
104         cm->features.allow_high_precision_mv, mbmi_ext, ref_frame,
105         &frame_mv[NEARESTMV][ref_frame], &frame_mv[NEARMV][ref_frame], 0);
106     frame_mv[GLOBALMV][ref_frame] = mbmi_ext->global_mvs[ref_frame];
107     // Early exit for non-LAST frame if force_skip_low_temp_var is set.
108     if (!av1_is_scaled(sf) && bsize >= BLOCK_8X8 && !skip_pred_mv &&
109         !(force_skip_low_temp_var && ref_frame != LAST_FRAME)) {
110       av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
111                   bsize);
112     }
113   }
114   if (cm->features.switchable_motion_mode) {
115     av1_count_overlappable_neighbors(cm, xd);
116   }
117   mbmi->num_proj_ref = 1;
118 }
119 
120 #endif  // AOM_AV1_ENCODER_NONRD_OPT_H_
121