tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rd.h (14053B)


      1 /*
      2 * Copyright (c) 2016, 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_RD_H_
     13 #define AOM_AV1_ENCODER_RD_H_
     14 
     15 #include <limits.h>
     16 
     17 #include "aom/aomcx.h"
     18 #include "av1/common/blockd.h"
     19 #include "av1/encoder/block.h"
     20 #include "av1/encoder/context_tree.h"
     21 #include "av1/encoder/cost.h"
     22 #include "av1/encoder/ratectrl.h"
     23 #include "config/aom_config.h"
     24 
     25 #ifdef __cplusplus
     26 extern "C" {
     27 #endif
     28 
     29 #define RDDIV_BITS 7
     30 #define RD_EPB_SHIFT 6
     31 
     32 #define RDCOST(RM, R, D)                                            \
     33  (ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), AV1_PROB_COST_SHIFT) + \
     34   ((D) * (1 << RDDIV_BITS)))
     35 
     36 #define RDCOST_NEG_R(RM, R, D) \
     37  (((D) * (1 << RDDIV_BITS)) - \
     38   ROUND_POWER_OF_TWO(((int64_t)(R)) * (RM), AV1_PROB_COST_SHIFT))
     39 
     40 #define RDCOST_DBL_WITH_NATIVE_BD_DIST(RM, R, D, BD)               \
     41  (((((double)(R)) * (RM)) / (double)(1 << AV1_PROB_COST_SHIFT)) + \
     42   ((double)((D) >> (2 * (BD - 8))) * (1 << RDDIV_BITS)))
     43 
     44 #define QIDX_SKIP_THRESH 115
     45 
     46 #define MV_COST_WEIGHT 108
     47 #define MV_COST_WEIGHT_SUB 120
     48 
     49 // The fractional part of rd_thresh factor is stored with 5 bits. The maximum
     50 // factor that we allow is two, which is stored as 2 ** (5+1) = 64
     51 #define RD_THRESH_FAC_FRAC_BITS (5)
     52 #define RD_THRESH_FAC_FRAC_VAL (1 << (RD_THRESH_FAC_FRAC_BITS))
     53 #define RD_THRESH_MAX_FACT ((RD_THRESH_FAC_FRAC_VAL) << 1)
     54 #define RD_THRESH_LOG_DEC_FACTOR (4)
     55 #define RD_THRESH_INC (1)
     56 
     57 // Factor to weigh the rate for switchable interp filters.
     58 #define SWITCHABLE_INTERP_RATE_FACTOR 1
     59 
     60 // Macros for common video resolutions: width x height
     61 // For example, 720p represents video resolution of 1280x720 pixels.
     62 #define RESOLUTION_288P 352 * 288
     63 #define RESOLUTION_360P 640 * 360
     64 #define RESOLUTION_480P 640 * 480
     65 #define RESOLUTION_720P 1280 * 720
     66 #define RESOLUTION_1080P 1920 * 1080
     67 #define RESOLUTION_1440P 2560 * 1440
     68 #define RESOLUTION_4K 3840 * 2160
     69 
     70 #define RTC_REFS 4
     71 static const MV_REFERENCE_FRAME real_time_ref_combos[RTC_REFS][2] = {
     72  { LAST_FRAME, NONE_FRAME },
     73  { ALTREF_FRAME, NONE_FRAME },
     74  { GOLDEN_FRAME, NONE_FRAME },
     75  { INTRA_FRAME, NONE_FRAME }
     76 };
     77 
     78 static inline int mode_offset(const PREDICTION_MODE mode) {
     79  if (mode >= NEARESTMV) {
     80    return INTER_OFFSET(mode);
     81  } else {
     82    switch (mode) {
     83      case DC_PRED: return 0;
     84      case V_PRED: return 1;
     85      case H_PRED: return 2;
     86      case SMOOTH_PRED: return 3;
     87      default: assert(0); return -1;
     88    }
     89  }
     90 }
     91 
     92 enum {
     93  // Default initialization when we are not using winner mode framework. e.g.
     94  // intrabc
     95  DEFAULT_EVAL = 0,
     96  // Initialization for selecting winner mode
     97  MODE_EVAL,
     98  // Initialization for winner mode evaluation
     99  WINNER_MODE_EVAL,
    100  // All mode evaluation types
    101  MODE_EVAL_TYPES,
    102 } UENUM1BYTE(MODE_EVAL_TYPE);
    103 
    104 typedef struct RD_OPT {
    105  // Thresh_mult is used to set a threshold for the rd score. A higher value
    106  // means that we will accept the best mode so far more often. This number
    107  // is used in combination with the current block size, and thresh_freq_fact
    108  // to pick a threshold.
    109  int thresh_mult[MAX_MODES];
    110 
    111  int threshes[MAX_SEGMENTS][BLOCK_SIZES_ALL][MAX_MODES];
    112 
    113  int RDMULT;
    114 
    115  double r0;
    116 } RD_OPT;
    117 
    118 static inline void av1_init_rd_stats(RD_STATS *rd_stats) {
    119 #if CONFIG_RD_DEBUG
    120  int plane;
    121 #endif
    122  rd_stats->rate = 0;
    123  rd_stats->dist = 0;
    124  rd_stats->rdcost = 0;
    125  rd_stats->sse = 0;
    126  rd_stats->skip_txfm = 1;
    127  rd_stats->zero_rate = 0;
    128 #if CONFIG_RD_DEBUG
    129  // This may run into problems when monochrome video is
    130  // encoded, as there will only be 1 plane
    131  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    132    rd_stats->txb_coeff_cost[plane] = 0;
    133  }
    134 #endif
    135 }
    136 
    137 static inline void av1_invalid_rd_stats(RD_STATS *rd_stats) {
    138 #if CONFIG_RD_DEBUG
    139  int plane;
    140 #endif
    141  rd_stats->rate = INT_MAX;
    142  rd_stats->dist = INT64_MAX;
    143  rd_stats->rdcost = INT64_MAX;
    144  rd_stats->sse = INT64_MAX;
    145  rd_stats->skip_txfm = 0;
    146  rd_stats->zero_rate = 0;
    147 #if CONFIG_RD_DEBUG
    148  // This may run into problems when monochrome video is
    149  // encoded, as there will only be 1 plane
    150  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
    151    rd_stats->txb_coeff_cost[plane] = INT_MAX;
    152  }
    153 #endif
    154 }
    155 
    156 static inline void av1_merge_rd_stats(RD_STATS *rd_stats_dst,
    157                                      const RD_STATS *rd_stats_src) {
    158  if (rd_stats_dst->rate == INT_MAX || rd_stats_src->rate == INT_MAX) {
    159    // If rd_stats_dst or rd_stats_src has invalid rate, we will make
    160    // rd_stats_dst invalid.
    161    av1_invalid_rd_stats(rd_stats_dst);
    162    return;
    163  }
    164  rd_stats_dst->rate = (int)AOMMIN(
    165      ((int64_t)rd_stats_dst->rate + (int64_t)rd_stats_src->rate), INT_MAX);
    166  if (!rd_stats_dst->zero_rate)
    167    rd_stats_dst->zero_rate = rd_stats_src->zero_rate;
    168  rd_stats_dst->dist += rd_stats_src->dist;
    169  if (rd_stats_dst->sse < INT64_MAX && rd_stats_src->sse < INT64_MAX) {
    170    rd_stats_dst->sse += rd_stats_src->sse;
    171  }
    172  rd_stats_dst->skip_txfm &= rd_stats_src->skip_txfm;
    173 #if CONFIG_RD_DEBUG
    174  // This may run into problems when monochrome video is
    175  // encoded, as there will only be 1 plane
    176  for (int plane = 0; plane < MAX_MB_PLANE; ++plane) {
    177    rd_stats_dst->txb_coeff_cost[plane] += rd_stats_src->txb_coeff_cost[plane];
    178  }
    179 #endif
    180 }
    181 
    182 static inline void av1_accumulate_rd_stats(RD_STATS *rd_stats, int64_t dist,
    183                                           int rate, int skip_txfm, int64_t sse,
    184                                           int zero_rate) {
    185  assert(rd_stats->rate != INT_MAX && rate != INT_MAX);
    186  rd_stats->rate += rate;
    187  if (!rd_stats->zero_rate) rd_stats->zero_rate = zero_rate;
    188  rd_stats->dist += dist;
    189  rd_stats->skip_txfm &= skip_txfm;
    190  rd_stats->sse += sse;
    191 }
    192 
    193 static inline int64_t av1_calculate_rd_cost(int mult, int rate, int64_t dist) {
    194  assert(mult >= 0);
    195  if (rate >= 0) {
    196    return RDCOST(mult, rate, dist);
    197  }
    198  return RDCOST_NEG_R(mult, -rate, dist);
    199 }
    200 
    201 static inline void av1_rd_cost_update(int mult, RD_STATS *rd_cost) {
    202  if (rd_cost->rate < INT_MAX && rd_cost->dist < INT64_MAX &&
    203      rd_cost->rdcost < INT64_MAX) {
    204    rd_cost->rdcost = av1_calculate_rd_cost(mult, rd_cost->rate, rd_cost->dist);
    205  } else {
    206    av1_invalid_rd_stats(rd_cost);
    207  }
    208 }
    209 
    210 static inline void av1_rd_stats_subtraction(int mult,
    211                                            const RD_STATS *const left,
    212                                            const RD_STATS *const right,
    213                                            RD_STATS *result) {
    214  if (left->rate == INT_MAX || right->rate == INT_MAX ||
    215      left->dist == INT64_MAX || right->dist == INT64_MAX ||
    216      left->rdcost == INT64_MAX || right->rdcost == INT64_MAX) {
    217    av1_invalid_rd_stats(result);
    218  } else {
    219    result->rate = left->rate - right->rate;
    220    result->dist = left->dist - right->dist;
    221    result->rdcost = av1_calculate_rd_cost(mult, result->rate, result->dist);
    222  }
    223 }
    224 
    225 struct TileInfo;
    226 struct TileDataEnc;
    227 struct AV1_COMP;
    228 struct macroblock;
    229 
    230 /*!\brief Compute rdmult based on q index and frame update type
    231 *
    232 * \param[in]       bit_depth       bit depth
    233 * \param[in]       update_type     frame update type
    234 * \param[in]       qindex          q index
    235 * \param[in]       tuning          visual tuning metric
    236 *
    237 * \return rdmult
    238 */
    239 int av1_compute_rd_mult_based_on_qindex(aom_bit_depth_t bit_depth,
    240                                        FRAME_UPDATE_TYPE update_type,
    241                                        int qindex, aom_tune_metric tuning);
    242 
    243 int av1_compute_rd_mult(const int qindex, const aom_bit_depth_t bit_depth,
    244                        const FRAME_UPDATE_TYPE update_type,
    245                        const int layer_depth, const int boost_index,
    246                        const FRAME_TYPE frame_type,
    247                        const int use_fixed_qp_offsets,
    248                        const int is_stat_consumption_stage,
    249                        const aom_tune_metric tuning);
    250 
    251 void av1_initialize_rd_consts(struct AV1_COMP *cpi);
    252 
    253 // Sets the multiplier to convert mv cost to l1 error during motion search.
    254 void av1_set_sad_per_bit(const struct AV1_COMP *cpi, int *sadperbit,
    255                         int qindex);
    256 
    257 void av1_model_rd_from_var_lapndz(int64_t var, unsigned int n,
    258                                  unsigned int qstep, int *rate, int64_t *dist);
    259 
    260 void av1_model_rd_curvfit(BLOCK_SIZE bsize, double sse_norm, double xqr,
    261                          double *rate_f, double *distbysse_f);
    262 
    263 int av1_get_switchable_rate(const MACROBLOCK *x, const MACROBLOCKD *xd,
    264                            InterpFilter interp_filter, int dual_filter);
    265 
    266 YV12_BUFFER_CONFIG *av1_get_scaled_ref_frame(const struct AV1_COMP *cpi,
    267                                             int ref_frame);
    268 
    269 void av1_init_me_luts(void);
    270 
    271 void av1_set_mvcost(MACROBLOCK *x, int ref, int ref_mv_idx);
    272 
    273 void av1_get_entropy_contexts(BLOCK_SIZE plane_bsize,
    274                              const struct macroblockd_plane *pd,
    275                              ENTROPY_CONTEXT t_above[MAX_MIB_SIZE],
    276                              ENTROPY_CONTEXT t_left[MAX_MIB_SIZE]);
    277 
    278 void av1_set_rd_speed_thresholds(struct AV1_COMP *cpi);
    279 
    280 void av1_update_rd_thresh_fact(const AV1_COMMON *const cm,
    281                               int (*fact)[MAX_MODES], int rd_thresh,
    282                               BLOCK_SIZE bsize, THR_MODES best_mode_index,
    283                               THR_MODES inter_mode_start,
    284                               THR_MODES inter_mode_end,
    285                               THR_MODES intra_mode_start,
    286                               THR_MODES intra_mode_end);
    287 
    288 static inline void reset_thresh_freq_fact(MACROBLOCK *const x) {
    289  for (int i = 0; i < BLOCK_SIZES_ALL; ++i) {
    290    for (int j = 0; j < MAX_MODES; ++j) {
    291      x->thresh_freq_fact[i][j] = RD_THRESH_FAC_FRAC_VAL;
    292    }
    293  }
    294 }
    295 
    296 static inline int rd_less_than_thresh(int64_t best_rd, int64_t thresh,
    297                                      int thresh_fact) {
    298  return best_rd < (thresh * thresh_fact >> 5) || thresh == INT_MAX;
    299 }
    300 
    301 void av1_mv_pred(const struct AV1_COMP *cpi, MACROBLOCK *x,
    302                 uint8_t *ref_y_buffer, int ref_y_stride, int ref_frame,
    303                 BLOCK_SIZE block_size);
    304 
    305 // Sets the multiplier to convert mv cost to l2 error during motion search.
    306 static inline void av1_set_error_per_bit(int *errorperbit, int rdmult) {
    307  *errorperbit = AOMMAX(rdmult >> RD_EPB_SHIFT, 1);
    308 }
    309 
    310 // Get the threshold for R-D optimization of coefficients depending upon mode
    311 // decision/winner mode processing
    312 static inline void get_rd_opt_coeff_thresh(
    313    const uint32_t (*const coeff_opt_threshold)[2],
    314    TxfmSearchParams *txfm_params, int enable_winner_mode_for_coeff_opt,
    315    int is_winner_mode) {
    316  if (!enable_winner_mode_for_coeff_opt) {
    317    // Default initialization of threshold
    318    txfm_params->coeff_opt_thresholds[0] = coeff_opt_threshold[DEFAULT_EVAL][0];
    319    txfm_params->coeff_opt_thresholds[1] = coeff_opt_threshold[DEFAULT_EVAL][1];
    320    return;
    321  }
    322  // TODO(any): Experiment with coeff_opt_dist_threshold values when
    323  // enable_winner_mode_for_coeff_opt is ON
    324  // TODO(any): Skip the winner mode processing for blocks with lower residual
    325  // energy as R-D optimization of coefficients would have been enabled during
    326  // mode decision
    327 
    328  // Use conservative threshold during mode decision and perform R-D
    329  // optimization of coeffs always for winner modes
    330  if (is_winner_mode) {
    331    txfm_params->coeff_opt_thresholds[0] =
    332        coeff_opt_threshold[WINNER_MODE_EVAL][0];
    333    txfm_params->coeff_opt_thresholds[1] =
    334        coeff_opt_threshold[WINNER_MODE_EVAL][1];
    335  } else {
    336    txfm_params->coeff_opt_thresholds[0] = coeff_opt_threshold[MODE_EVAL][0];
    337    txfm_params->coeff_opt_thresholds[1] = coeff_opt_threshold[MODE_EVAL][1];
    338  }
    339 }
    340 
    341 // Used to reset the state of mb rd hash information
    342 static inline void reset_mb_rd_record(MB_RD_RECORD *const mb_rd_record) {
    343  if (!mb_rd_record) return;
    344 
    345  // Reset the state for use_mb_rd_hash
    346  mb_rd_record->num = mb_rd_record->index_start = 0;
    347 }
    348 
    349 void av1_setup_pred_block(const MACROBLOCKD *xd,
    350                          struct buf_2d dst[MAX_MB_PLANE],
    351                          const YV12_BUFFER_CONFIG *src,
    352                          const struct scale_factors *scale,
    353                          const struct scale_factors *scale_uv,
    354                          const int num_planes);
    355 
    356 int av1_get_intra_cost_penalty(int qindex, int qdelta,
    357                               aom_bit_depth_t bit_depth);
    358 
    359 void av1_fill_mode_rates(AV1_COMMON *const cm, ModeCosts *mode_costs,
    360                         FRAME_CONTEXT *fc);
    361 
    362 #if !CONFIG_REALTIME_ONLY
    363 void av1_fill_lr_rates(ModeCosts *mode_costs, FRAME_CONTEXT *fc);
    364 #endif
    365 
    366 void av1_fill_coeff_costs(CoeffCosts *coeff_costs, FRAME_CONTEXT *fc,
    367                          const int num_planes);
    368 
    369 void av1_fill_mv_costs(const nmv_context *nmvc, int integer_mv, int usehp,
    370                       MvCosts *mv_costs);
    371 
    372 void av1_fill_dv_costs(const nmv_context *ndvc, IntraBCMVCosts *dv_costs);
    373 
    374 #if !CONFIG_REALTIME_ONLY
    375 int av1_get_adaptive_rdmult(const struct AV1_COMP *cpi, double beta);
    376 #endif
    377 
    378 int av1_get_deltaq_offset(aom_bit_depth_t bit_depth, int qindex, double beta);
    379 
    380 /*!\brief Adjust current superblock's q_index based on delta q resolution
    381 *
    382 * \param[in]       delta_q_res       delta q resolution
    383 * \param[in]       prev_qindex       previous superblock's q index
    384 * \param[in]       curr_qindex       current superblock's q index
    385 *
    386 * \return the current superblock's adjusted q_index
    387 */
    388 int av1_adjust_q_from_delta_q_res(int delta_q_res, int prev_qindex,
    389                                  int curr_qindex);
    390 
    391 #ifdef __cplusplus
    392 }  // extern "C"
    393 #endif
    394 
    395 #endif  // AOM_AV1_ENCODER_RD_H_