encodeframe.c 194 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 11 12 13 14 15
 */

#include <limits.h>
#include <math.h>
#include <stdio.h>

16 17 18
#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_config.h"
19

20
#include "aom_dsp/aom_dsp_common.h"
21
#include "aom_dsp/binary_codes_writer.h"
22
#include "aom_ports/mem.h"
23
#include "aom_ports/aom_timer.h"
24
#include "aom_ports/system_state.h"
25

Angie Chiang's avatar
Angie Chiang committed
26 27 28 29
#if CONFIG_MISMATCH_DEBUG
#include "aom_util/debug_util.h"
#endif  // CONFIG_MISMATCH_DEBUG

Luc Trudeau's avatar
Luc Trudeau committed
30 31 32
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif
33 34 35 36
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/idct.h"
37
#include "av1/common/mv.h"
38 39 40 41 42 43 44
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconintra.h"
#include "av1/common/reconinter.h"
#include "av1/common/seg_common.h"
#include "av1/common/tile_common.h"
45

46 47 48
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
49
#include "av1/common/warped_motion.h"
50 51 52 53
#include "av1/encoder/global_motion.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodemb.h"
#include "av1/encoder/encodemv.h"
54 55 56
#if CONFIG_LV_MAP
#include "av1/encoder/encodetxb.h"
#endif
57 58 59 60 61 62
#include "av1/encoder/ethread.h"
#include "av1/encoder/extend.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/rdopt.h"
#include "av1/encoder/segmentation.h"
#include "av1/encoder/tokenize.h"
63

64 65 66 67
static void encode_superblock(const AV1_COMP *const cpi, TileDataEnc *tile_data,
                              ThreadData *td, TOKENEXTRA **t, RUN_TYPE dry_run,
                              int mi_row, int mi_col, BLOCK_SIZE bsize,
                              int *rate);
68 69 70 71 72

// This is used as a reference when computing the source variance for the
//  purposes of activity masking.
// Eventually this should be replaced by custom no-reference routines,
//  which will be faster.
73
static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
74 75 76 77 78
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
79
#if CONFIG_EXT_PARTITION
80 81 82 83 84
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
85
#endif  // CONFIG_EXT_PARTITION
86 87
};

88
static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
89 90 91 92 93
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
94
#if CONFIG_EXT_PARTITION
95 96 97 98 99
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
100
#endif  // CONFIG_EXT_PARTITION
101 102
};

103
static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
104 105 106 107 108 109 110 111
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
112
#if CONFIG_EXT_PARTITION
113 114 115 116 117 118 119 120
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
121
#endif  // CONFIG_EXT_PARTITION
122 123
};

124
static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
125 126 127 128 129 130 131 132 133 134
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16,
135
#if CONFIG_EXT_PARTITION
136 137 138 139 140 141 142 143 144 145
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
  128 * 16
146
#endif  // CONFIG_EXT_PARTITION
147 148
};

149 150
#if CONFIG_FP_MB_STATS
static const uint8_t num_16x16_blocks_wide_lookup[BLOCK_SIZES_ALL] = {
151 152 153 154 155 156 157 158 159 160
  1, 1,
  1, 1,
  1, 1,
  1, 1,
  2, 2,
  2, 4,
  4, IF_EXT_PARTITION(4, 8, 8) 1,
  1, 1,
  2, 2,
  4, IF_EXT_PARTITION(2, 8)
161 162
};
static const uint8_t num_16x16_blocks_high_lookup[BLOCK_SIZES_ALL] = {
163 164 165 166 167 168 169 170 171 172
  1, 1,
  1, 1,
  1, 1,
  1, 2,
  1, 2,
  4, 2,
  4, IF_EXT_PARTITION(8, 4, 8) 1,
  1, 2,
  1, 4,
  2, IF_EXT_PARTITION(8, 2)
173 174 175
};
#endif  // CONFIG_FP_MB_STATS

176
unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
177 178
                                           const struct buf_2d *ref,
                                           BLOCK_SIZE bs) {
179
  unsigned int sse;
180
  const unsigned int var =
181
      cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
182 183 184
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

185
unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
186 187
                                                const struct buf_2d *ref,
                                                BLOCK_SIZE bs, int bd) {
188 189 190
  unsigned int var, sse;
  switch (bd) {
    case 10:
191 192 193
      var =
          cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                             CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
194 195
      break;
    case 12:
196 197 198
      var =
          cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
                             CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
199 200 201
      break;
    case 8:
    default:
202 203
      var =
          cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
204
                             CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
205 206 207 208 209
      break;
  }
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

210
static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
211 212 213 214 215 216 217 218 219 220 221 222 223 224
                                                   const struct buf_2d *ref,
                                                   int mi_row, int mi_col,
                                                   BLOCK_SIZE bs) {
  unsigned int sse, var;
  uint8_t *last_y;
  const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);

  assert(last != NULL);
  last_y =
      &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
  var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

225 226
static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
                                                   int mi_row, int mi_col) {
227 228
  unsigned int var = get_sby_perpixel_diff_variance(
      cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
229 230 231 232 233 234 235 236 237 238 239 240
  if (var < 8)
    return BLOCK_64X64;
  else if (var < 128)
    return BLOCK_32X32;
  else if (var < 2048)
    return BLOCK_16X16;
  else
    return BLOCK_8X8;
}

// Lighter version of set_offsets that only sets the mode info
// pointers.
241 242 243 244
static void set_mode_info_offsets(const AV1_COMP *const cpi,
                                  MACROBLOCK *const x, MACROBLOCKD *const xd,
                                  int mi_row, int mi_col) {
  const AV1_COMMON *const cm = &cpi->common;
245 246 247
  const int idx_str = xd->mi_stride * mi_row + mi_col;
  xd->mi = cm->mi_grid_visible + idx_str;
  xd->mi[0] = cm->mi + idx_str;
248
  x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
249 250
}

251
static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
252
                                           const TileInfo *const tile,
253 254
                                           MACROBLOCK *const x, int mi_row,
                                           int mi_col, BLOCK_SIZE bsize) {
255
  const AV1_COMMON *const cm = &cpi->common;
256
  const int num_planes = av1_num_planes(cm);
257
  MACROBLOCKD *const xd = &x->e_mbd;
258 259
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
260

261
  set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
262

263
  set_skip_context(xd, mi_row, mi_col, num_planes);
264 265 266 267
  xd->above_txfm_context =
      cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
  xd->left_txfm_context = xd->left_txfm_context_buffer +
                          ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
268

269
  // Set up destination pointers.
270
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
271
                       mi_col, num_planes);
272 273 274

  // Set up limit values for MV components.
  // Mv beyond the range do not produce new/different prediction block.
Alex Converse's avatar
Alex Converse committed
275 276 277 278 279
  x->mv_limits.row_min =
      -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
  x->mv_limits.col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
  x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
  x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
280

281
  set_plane_n4(xd, mi_width, mi_height, num_planes);
282

283 284
  // Set up distance of MB to edge of frame in 1/8th pel units.
  assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
285
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
286
#if CONFIG_DEPENDENT_HORZTILES
287 288 289
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
290 291

  // Set up source buffers.
292
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes);
293 294 295 296

  // R/D setup.
  x->rdmult = cpi->rd.RDMULT;

297
  // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
298 299 300
  xd->tile = *tile;
}

301
static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
302 303
                        MACROBLOCK *const x, int mi_row, int mi_col,
                        BLOCK_SIZE bsize) {
304
  const AV1_COMMON *const cm = &cpi->common;
305 306 307 308 309 310 311
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *mbmi;
  const struct segmentation *const seg = &cm->seg;

  set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);

  mbmi = &xd->mi[0]->mbmi;
312
#if CONFIG_CFL
313 314
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
315
#endif
316

317 318
  mbmi->segment_id = 0;

319
  // Setup segment ID.
320
  if (seg->enabled) {
321
    if (seg->enabled && !cpi->vaq_refresh) {
322 323
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
324 325
      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
    }
326
    av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
327
  }
328 329
}

330
#if CONFIG_DUAL_FILTER
331
static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
332
                                    MB_MODE_INFO *mbmi) {
333 334 335 336 337 338 339 340 341
  InterpFilter filters[2];
  InterpFilter default_filter = av1_unswitchable_filter(cm->interp_filter);

  for (int dir = 0; dir < 2; ++dir) {
    filters[dir] = ((!has_subpel_mv_component(xd->mi[0], xd, dir) &&
                     (mbmi->ref_frame[1] == NONE_FRAME ||
                      !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
                        ? default_filter
                        : av1_extract_interp_filter(mbmi->interp_filters, dir));
342
  }
343
  mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
344 345
}

346 347
static void update_filter_type_count(uint8_t allow_update_cdf,
                                     FRAME_COUNTS *counts,
348 349 350
                                     const MACROBLOCKD *xd,
                                     const MB_MODE_INFO *mbmi) {
  int dir;
351
  for (dir = 0; dir < 2; ++dir) {
352
    if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
353
        (mbmi->ref_frame[1] > INTRA_FRAME &&
354
         has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
355
      const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
356 357 358
      InterpFilter filter =
          av1_extract_interp_filter(mbmi->interp_filters, dir);
      ++counts->switchable_interp[ctx][filter];
359 360 361
      if (allow_update_cdf)
        update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
                   SWITCHABLE_FILTERS);
362 363 364 365
    }
  }
}
#endif
366
static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
367 368
                                      const MB_MODE_INFO *mbmi,
                                      RD_COUNTS *rdc) {
Sarah Parker's avatar
Sarah Parker committed
369
  if (mode == GLOBALMV || mode == GLOBAL_GLOBALMV) {
370 371
    const int num_4x4s =
        num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
372 373
    int ref;
    for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
374
      rdc->global_motion_used[mbmi->ref_frame[ref]] += num_4x4s;
375
    }
376 377
  }
}
378

379 380 381 382 383 384 385
static void reset_tx_size(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
                          const TX_MODE tx_mode) {
  if (xd->lossless[mbmi->segment_id]) {
    mbmi->tx_size = TX_4X4;
  } else if (tx_mode != TX_MODE_SELECT) {
    mbmi->tx_size =
        tx_size_from_tx_mode(mbmi->sb_type, tx_mode, is_inter_block(mbmi));
386 387 388
  } else {
    BLOCK_SIZE bsize = mbmi->sb_type;
    TX_SIZE min_tx_size =
389
        depth_to_tx_size(MAX_TX_DEPTH, bsize, is_inter_block(mbmi));
390
    mbmi->tx_size = (TX_SIZE)TXSIZEMAX(mbmi->tx_size, min_tx_size);
391
  }
392
  if (is_inter_block(mbmi)) {
393 394 395 396
    for (int idy = 0; idy < xd->n8_h; ++idy) {
      for (int idx = 0; idx < xd->n8_w; ++idx)
        mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
    }
397
    mbmi->min_tx_size = mbmi->tx_size;
398
  }
399 400
}

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
                                 int8_t rf_type) {
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;

  const int bw = xd->n8_w << MI_SIZE_LOG2;
  const int bh = xd->n8_h << MI_SIZE_LOG2;
  int ref_mv_idx = mbmi->ref_mv_idx;
  MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
  CANDIDATE_MV *const curr_ref_mv_stack = mbmi_ext->ref_mv_stack[rf_type];

  if (has_second_ref(mbmi)) {
    // Special case: NEAR_NEWMV and NEW_NEARMV modes use 1 + mbmi->ref_mv_idx
    // (like NEARMV) instead
    if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV) ref_mv_idx += 1;

    if (compound_ref0_mode(mbmi->mode) == NEWMV) {
      int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
      clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
      mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
      mbmi->pred_mv[0] = this_mv;
      mi_pred_mv[0] = this_mv;
    }
    if (compound_ref1_mode(mbmi->mode) == NEWMV) {
      int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
      clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
      mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
      mbmi->pred_mv[1] = this_mv;
      mi_pred_mv[1] = this_mv;
    }
  } else {
    if (mbmi->mode == NEWMV) {
      int i;
      for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
        int_mv this_mv = (i == 0) ? curr_ref_mv_stack[ref_mv_idx].this_mv
                                  : curr_ref_mv_stack[ref_mv_idx].comp_mv;
        clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
        mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
        mbmi->pred_mv[i] = this_mv;
        mi_pred_mv[i] = this_mv;
      }
    }
  }
}

446 447 448
static void update_state(const AV1_COMP *const cpi, TileDataEnc *tile_data,
                         ThreadData *td, PICK_MODE_CONTEXT *ctx, int mi_row,
                         int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run) {
449
  int i, x_idx, y;
450
  const AV1_COMMON *const cm = &cpi->common;
451
  const int num_planes = av1_num_planes(cm);
452 453 454 455 456 457 458
  RD_COUNTS *const rdc = &td->rd_counts;
  MACROBLOCK *const x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  MODE_INFO *mi = &ctx->mic;
  MODE_INFO *mi_addr = xd->mi[0];
459
  MB_MODE_INFO *const mbmi = &mi_addr->mbmi;
460
  const struct segmentation *const seg = &cm->seg;
461 462
  const int bw = mi_size_wide[mi->mbmi.sb_type];
  const int bh = mi_size_high[mi->mbmi.sb_type];
463
  const int mis = cm->mi_stride;
464 465
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
466 467
  int8_t rf_type;

468 469 470 471 472
  assert(mi->mbmi.sb_type == bsize);

  *mi_addr = *mi;
  *x->mbmi_ext = ctx->mbmi_ext;

473 474 475 476
#if CONFIG_DUAL_FILTER
  reset_intmv_filter_type(cm, xd, mbmi);
#endif

477
  rf_type = av1_ref_frame_type(mbmi->ref_frame);
478
  if (x->mbmi_ext->ref_mv_count[rf_type] > 1) {
479
    set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
480
  }
481

482 483 484 485
  // If segmentation in use
  if (seg->enabled) {
    // For in frame complexity AQ copy the segment id from the segment map.
    if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
486 487
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
488 489
      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
      reset_tx_size(xd, mbmi, cm->tx_mode);
490 491 492 493
    }
    // Else for cyclic refresh mode update the segment map, set the segment id
    // and then update the quantizer.
    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
494 495 496
      av1_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize,
                                        ctx->rate, ctx->dist, x->skip);
      reset_tx_size(xd, mbmi, cm->tx_mode);
497 498 499
    }
  }

500
  for (i = 0; i < num_planes; ++i) {
501 502 503 504
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
505 506 507
#if CONFIG_LV_MAP
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif  // CONFIG_LV_MAP
508
  }
509
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
510 511 512 513
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
  for (y = 0; y < mi_height; y++)
    for (x_idx = 0; x_idx < mi_width; x_idx++)
514 515
      if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
          (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
516 517 518
        xd->mi[x_idx + y * mis] = mi_addr;
      }

519
#if !CONFIG_EXT_DELTA_Q
520
  if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
521
    av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
522
#else
523
  if (cpi->oxcf.aq_mode) av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
524
#endif
525 526

  x->skip = ctx->skip;
527

528
  for (i = 0; i < 1; ++i)
529 530
    memcpy(x->blk_skip[i], ctx->blk_skip[i],
           sizeof(uint8_t) * ctx->num_4x4_blk);
531

532
  if (dry_run) return;
533 534

#if CONFIG_INTERNAL_STATS
535 536 537 538 539
  {
    unsigned int *const mode_chosen_counts =
        (unsigned int *)cpi->mode_chosen_counts;  // Cast const away.
    if (frame_is_intra_only(cm)) {
      static const int kf_mode_index[] = {
540 541 542 543 544 545 546 547 548
        THR_DC /*DC_PRED*/,
        THR_V_PRED /*V_PRED*/,
        THR_H_PRED /*H_PRED*/,
        THR_D45_PRED /*D45_PRED*/,
        THR_D135_PRED /*D135_PRED*/,
        THR_D117_PRED /*D117_PRED*/,
        THR_D153_PRED /*D153_PRED*/,
        THR_D207_PRED /*D207_PRED*/,
        THR_D63_PRED /*D63_PRED*/,
549
        THR_SMOOTH,   /*SMOOTH_PRED*/
550 551
        THR_SMOOTH_V, /*SMOOTH_V_PRED*/
        THR_SMOOTH_H, /*SMOOTH_H_PRED*/
552
        THR_PAETH /*PAETH_PRED*/,
553 554 555 556 557 558
      };
      ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
    } else {
      // Note how often each mode chosen as best
      ++mode_chosen_counts[ctx->best_mode_index];
    }
559 560 561 562
  }
#endif
  if (!frame_is_intra_only(cm)) {
    if (is_inter_block(mbmi)) {
563 564 565 566 567 568 569
      // TODO(sarahparker): global motion stats need to be handled per-tile
      // to be compatible with tile-based threading.
      update_global_motion_used(mbmi->mode, bsize, mbmi, rdc);
    }

    if (cm->interp_filter == SWITCHABLE && mbmi->motion_mode != WARPED_CAUSAL &&
        !is_nontrans_global_motion(xd)) {
570
#if CONFIG_DUAL_FILTER
571 572
      update_filter_type_count(tile_data->allow_update_cdf, td->counts, xd,
                               mbmi);
573
#else
574 575 576 577 578
      (void)tile_data;
      const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
      const InterpFilter filter =
          av1_extract_interp_filter(mbmi->interp_filters, 0);
      ++td->counts->switchable_interp[switchable_ctx][filter];
579
#endif
580 581 582 583 584 585 586
    }

    rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
    rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
    rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
  }

587 588 589
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
  av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
590 591
}

592
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
593
                          int mi_row, int mi_col, const int num_planes) {
594 595 596
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

597 598 599 600 601 602 603 604
  // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
  // the static analysis warnings.
  for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); i++) {
    const int is_uv = i > 0;
    setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type,
                     src->buffers[i], src->crop_widths[is_uv],
                     src->crop_heights[is_uv], src->strides[is_uv], mi_row,
                     mi_col, NULL, x->e_mbd.plane[i].subsampling_x,
605
                     x->e_mbd.plane[i].subsampling_y);
606
  }
607 608
}

609
static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
610
                              int8_t segment_id) {
611
  const AV1_COMMON *const cm = &cpi->common;
612 613
  av1_init_plane_quantizers(cpi, x, segment_id);
  aom_clear_system_state();
614
  int segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
615
  return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
616 617
}

618
static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
619
                             MACROBLOCK *const x, int mi_row, int mi_col,
620
                             RD_STATS *rd_cost,
621 622
#if CONFIG_EXT_PARTITION_TYPES
                             PARTITION_TYPE partition,
623
#endif
624 625
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
626
  const AV1_COMMON *const cm = &cpi->common;
627
  const int num_planes = av1_num_planes(cm);
628 629 630
  TileInfo *const tile_info = &tile_data->tile_info;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *mbmi;
631
  MB_MODE_INFO *ctx_mbmi = &ctx->mic.mbmi;
632 633 634 635 636
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
  int i, orig_rdmult;

637
  aom_clear_system_state();
638 639

  set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
640

641
  mbmi = &xd->mi[0]->mbmi;
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658

  if (ctx->rd_mode_is_ready) {
    assert(ctx_mbmi->sb_type == bsize);
#if CONFIG_EXT_PARTITION_TYPES
    assert(ctx_mbmi->partition == partition);
#endif  // CONFIG_EXT_PARTITION_TYPES
    *mbmi = *ctx_mbmi;
    rd_cost->rate = ctx->rate;
    rd_cost->dist = ctx->dist;
    rd_cost->rdcost = ctx->rdcost;
  } else {
    mbmi->sb_type = bsize;
#if CONFIG_EXT_PARTITION_TYPES
    mbmi->partition = partition;
#endif  // CONFIG_EXT_PARTITION_TYPES
  }

659 660 661 662
#if CONFIG_RD_DEBUG
  mbmi->mi_row = mi_row;
  mbmi->mi_col = mi_col;
#endif
663

664
  for (i = 0; i < num_planes; ++i) {
665 666 667 668
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
669 670 671
#if CONFIG_LV_MAP
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif
672
  }
hui su's avatar
hui su committed
673

674
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
hui su's avatar
hui su committed
675

676 677
  if (!ctx->rd_mode_is_ready) {
    ctx->skippable = 0;
678

679 680
    // Set to zero to make sure we do not use the previous encoded frame stats
    mbmi->skip = 0;
681 682 683 684 685

#if CONFIG_EXT_SKIP
    // Reset skip mode flag.
    mbmi->skip_mode = 0;
#endif
686
  }
687

688
  x->skip_chroma_rd =
689 690
      !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y);
691

692 693 694 695 696 697
  if (ctx->rd_mode_is_ready) {
    x->skip = ctx->skip;
    *x->mbmi_ext = ctx->mbmi_ext;
    return;
  }

698
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
699
    x->source_variance = av1_high_get_sby_perpixel_variance(
700
        cpi, &x->plane[0].src, bsize, xd->bd);
701 702
  } else {
    x->source_variance =
703
        av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
704 705 706 707 708 709
  }

  // Save rdmult before it might be changed, so it can be restored later.
  orig_rdmult = x->rdmult;

  if (aq_mode == VARIANCE_AQ) {
Geza Lore's avatar
Geza Lore committed
710
    if (cpi->vaq_refresh) {
711 712 713
      const int energy =
          bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
      mbmi->segment_id = av1_vaq_segment_id(energy);
714
      // Re-initialise quantiser
715
      av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
716 717 718 719 720 721
    }
    x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
  } else if (aq_mode == COMPLEXITY_AQ) {
    x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
  } else if (aq_mode == CYCLIC_REFRESH_AQ) {
    // If segment is boosted, use rdmult for that segment.
Geza Lore's avatar
Geza Lore committed
722
    if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
723
      x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
724 725 726 727 728
  }

  // Find best coding mode & reconstruct the MB so it is available
  // as a predictor for MBs that follow in the SB
  if (frame_is_intra_only(cm)) {
729 730
    av1_rd_pick_intra_mode_sb(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx,
                              best_rd);
731
  } else {
732 733 734
    if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
      av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, mi_row, mi_col,
                                         rd_cost, bsize, ctx, best_rd);
735
    } else {
736 737
      av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
                                bsize, ctx, best_rd);
738 739 740 741
    }
  }

  // Examine the resulting rate and for AQ mode 2 make a segment choice.
742 743 744
  if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
      (bsize >= BLOCK_16X16) &&
      (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
Zoe Liu's avatar
Zoe Liu committed
745
       cpi->refresh_alt2_ref_frame ||
746
       (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
747
    av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
748 749 750 751 752 753
  }

  x->rdmult = orig_rdmult;

  // TODO(jingning) The rate-distortion optimization flow needs to be
  // refactored to provide proper exit/return handle.
754
  if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
755 756 757

  ctx->rate = rd_cost->rate;
  ctx->dist = rd_cost->dist;
758
  ctx->rdcost = rd_cost->rdcost;
759 760
}

761
static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
762 763
                                    int16_t mode_context) {
  int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
764 765 766 767 768
  if (mode == NEWMV) {
    ++counts->newmv_mode[mode_ctx][0];
    return;
  } else {
    ++counts->newmv_mode[mode_ctx][1];
769 770 771 772 773

    if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
      return;
    }

Sarah Parker's avatar
Sarah Parker committed
774 775
    mode_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
    if (mode == GLOBALMV) {
776 777 778 779
      ++counts->zeromv_mode[mode_ctx][0];
      return;
    } else {
      ++counts->zeromv_mode[mode_ctx][1];
780
      mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
781

782 783 784
      if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
      if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
      if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
785

786 787 788 789 790
      ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
    }
  }
}

791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
                            const MODE_INFO *mi, const MODE_INFO *above_mi,
                            const MODE_INFO *left_mi, const int intraonly,
                            const int mi_row, const int mi_col,
                            uint8_t allow_update_cdf) {
  FRAME_CONTEXT *fc = xd->tile_ctx;
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const PREDICTION_MODE y_mode = mbmi->mode;
  const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
  (void)counts;
  const BLOCK_SIZE bsize = mbmi->sb_type;

  // Update intra tx size cdf
  if (block_signals_txsize(bsize) && !xd->lossless[mbmi->segment_id] &&
      allow_update_cdf) {
    const TX_SIZE tx_size = mbmi->tx_size;
807
    const int tx_size_ctx = get_tx_size_context(xd, 0);
808 809 810 811 812 813 814 815 816 817 818
    const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize, 0);
    const int depth = tx_size_to_depth(tx_size, bsize, 0);
    const int max_depths = bsize_to_max_depth(bsize, 0);
    update_cdf(fc->tx_size_cdf[tx_size_cat][tx_size_ctx], depth,
               max_depths + 1);
  }

  if (intraonly) {
#if CONFIG_ENTROPY_STATS
    const PREDICTION_MODE above = av1_above_block_mode(above_mi);
    const PREDICTION_MODE left = av1_left_block_mode(left_mi);
Hui Su's avatar
Hui Su committed
819 820
    const int above_ctx = intra_mode_context[above];
    const int left_ctx = intra_mode_context[left];
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
    ++counts->kf_y_mode[above_ctx][left_ctx][y_mode];
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf)
      update_cdf(get_y_mode_cdf(fc, above_mi, left_mi), y_mode, INTRA_MODES);
  } else {
#if CONFIG_ENTROPY_STATS
    ++counts->y_mode[size_group_lookup[bsize]][y_mode];
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf)
      update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
  }

#if CONFIG_FILTER_INTRA
  if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0 &&
      av1_filter_intra_allowed_txsize(mbmi->tx_size)) {
    const int use_filter_intra_mode =
        mbmi->filter_intra_mode_info.use_filter_intra;
#if CONFIG_ENTROPY_STATS
    ++counts->filter_intra_tx[mbmi->tx_size][use_filter_intra_mode];
    if (use_filter_intra_mode) {
      ++counts
            ->filter_intra_mode[mbmi->filter_intra_mode_info.filter_intra_mode];
    }
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf) {
      if (use_filter_intra_mode)
        update_cdf(fc->filter_intra_mode_cdf,
                   mbmi->filter_intra_mode_info.filter_intra_mode,
                   FILTER_INTRA_MODES);
      update_cdf(fc->filter_intra_cdfs[mbmi->tx_size], use_filter_intra_mode,
                 2);
    }
  }
#endif  // CONFIG_FILTER_INTRA
855
#if CONFIG_EXT_INTRA_MOD
856 857 858 859 860 861 862 863 864 865 866
  if (av1_is_directional_mode(mbmi->mode, bsize) &&
      av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
    ++counts->angle_delta[mbmi->mode - V_PRED]
                         [mbmi->angle_delta[0] + MAX_ANGLE_DELTA];
#endif
    if (allow_update_cdf)
      update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
                 mbmi->angle_delta[0] + MAX_ANGLE_DELTA,
                 2 * MAX_ANGLE_DELTA + 1);
  }
867
#endif  // CONFIG_EXT_INTRA_MOD
868 869 870 871

  if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y))
    return;
872
#if CONFIG_EXT_INTRA_MOD
873 874 875 876 877 878 879 880 881 882 883
  if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize) &&
      av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
    ++counts->angle_delta[mbmi->uv_mode - V_PRED]
                         [mbmi->angle_delta[1] + MAX_ANGLE_DELTA];
#endif
    if (allow_update_cdf)
      update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
                 mbmi->angle_delta[1] + MAX_ANGLE_DELTA,
                 2 * MAX_ANGLE_DELTA + 1);
  }
884
#endif  // CONFIG_EXT_INTRA_MOD
885
#if CONFIG_ENTROPY_STATS
886 887 888
#if CONFIG_CFL
  ++counts->uv_mode[is_cfl_allowed(mbmi)][y_mode][uv_mode];
#else
889
  ++counts->uv_mode[y_mode][uv_mode];
890
#endif  // CONFIG_CFL
891
#endif  // CONFIG_ENTROPY_STATS
892 893 894 895 896 897 898
#if CONFIG_CFL
  if (allow_update_cdf) {
    const CFL_ALLOWED_TYPE cfl_allowed = is_cfl_allowed(mbmi);
    update_cdf(fc->uv_mode_cdf[cfl_allowed][y_mode], uv_mode,
               UV_INTRA_MODES - !cfl_allowed);
  }
#else
899 900
  if (allow_update_cdf)
    update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
901
#endif  // CONFIG_CFL
902 903 904 905 906 907 908 909 910 911 912 913
}

// TODO(anybody) We can add stats accumulation here to train entropy models for
// palette modes
static void update_palette_cdf(MACROBLOCKD *xd, const MODE_INFO *mi) {
  FRAME_CONTEXT *fc = xd->tile_ctx;
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

  if (mbmi->mode == DC_PRED) {
    const int n = pmi->palette_size[0];
Hui Su's avatar
Hui Su committed
914 915 916 917
    const int palette_mode_ctx = av1_get_palette_mode_ctx(xd);
    const int palette_bsize_ctx = av1_get_palette_bsize_ctx(bsize);
    update_cdf(fc->palette_y_mode_cdf[palette_bsize_ctx][palette_mode_ctx],
               n > 0, 2);
918 919 920 921 922 923 924 925 926
  }

  if (mbmi->uv_mode == UV_DC_PRED) {
    const int n = pmi->palette_size[1];
    const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0);
    update_cdf(fc->palette_uv_mode_cdf[palette_uv_mode_ctx], n > 0, 2);
  }
}

927 928
static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
                         ThreadData *td, int mi_row, int mi_col) {
929 930
  MACROBLOCK *x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
931 932 933 934
  const MODE_INFO *const mi = xd->mi[0];
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
  const BLOCK_SIZE bsize = mbmi->sb_type;
935
  FRAME_CONTEXT *fc = xd->tile_ctx;
936
  const uint8_t allow_update_cdf = tile_data->allow_update_cdf;
937

938
  // delta quant applies to both intra and inter
939 940
  const int super_block_upper_left = ((mi_row & (cm->mib_size - 1)) == 0) &&
                                     ((mi_col & (cm->mib_size - 1)) == 0);
941

942 943 944
  const int seg_ref_active =
      segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);

945 946 947 948 949 950
#if CONFIG_EXT_SKIP
  if (cm->skip_mode_flag && !seg_ref_active && is_comp_ref_allowed(bsize)) {
    const int skip_mode_ctx = av1_get_skip_mode_context(xd);
    td->counts->skip_mode[skip_mode_ctx][mbmi->skip_mode]++;
    if (allow_update_cdf)
      update_cdf(fc->skip_mode_cdfs[skip_mode_ctx], mbmi->skip_mode, 2);
951 952
  }

953 954 955 956 957 958 959 960 961 962 963
  if (!mbmi->skip_mode) {
#endif  // CONFIG_EXT_SKIP
    if (!seg_ref_active) {
      const int skip_ctx = av1_get_skip_context(xd);
      td->counts->skip[skip_ctx][mbmi->skip]++;
      if (allow_update_cdf) update_cdf(fc->skip_cdfs[skip_ctx], mbmi->skip, 2);
    }
#if CONFIG_EXT_SKIP
  }
#endif  // CONFIG_EXT_SKIP

964
  if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
965 966 967 968
      super_block_upper_left) {
    const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
    const int absdq = abs(dq);
    int i;
969
    for (i = 0; i < AOMMIN(absdq, DELTA_Q_SMALL); ++i) {
970 971 972 973
      td->counts->delta_q[i][1]++;
    }
    if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
    xd->prev_qindex = mbmi->current_q_index;
974
#if CONFIG_EXT_DELTA_Q
975 976
#if CONFIG_LOOPFILTER_LEVEL
    if (cm->delta_lf_present_flag) {
977 978 979 980 981 982 983 984 985 986 987 988 989 990
      if (cm->delta_lf_multi) {
        for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
          const int delta_lf =
              (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
              cm->delta_lf_res;
          const int abs_delta_lf = abs(delta_lf);
          for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
            td->counts->delta_lf_multi[lf_id][i][1]++;
          }
          if (abs_delta_lf < DELTA_LF_SMALL)
            td->counts->delta_lf_multi[lf_id][abs_delta_lf][0]++;
          xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
        }
      } else {
991
        const int delta_lf =
992
            (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
993 994 995
            cm->delta_lf_res;
        const int abs_delta_lf = abs(delta_lf);
        for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
996
          td->counts->delta_lf[i][1]++;
997 998
        }
        if (abs_delta_lf < DELTA_LF_SMALL)
999 1000
          td->counts->delta_lf[abs_delta_lf][0]++;
        xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
1001 1002 1003
      }
    }
#else
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
    if (cm->delta_lf_present_flag) {
      const int dlf =
          (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
          cm->delta_lf_res;
      const int absdlf = abs(dlf);
      for (i = 0; i < AOMMIN(absdlf, DELTA_LF_SMALL); ++i) {
        td->counts->delta_lf[i][1]++;
      }
      if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++;
      xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
    }
1015
#endif  // CONFIG_LOOPFILTER_LEVEL
1016
#endif
1017
  }
1018

1019 1020 1021 1022 1023 1024 1025 1026 1027
  if (!is_inter_block(mbmi)) {
    sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
                    frame_is_intra_only(cm), mi_row, mi_col,
                    tile_data->allow_update_cdf);
    if (av1_allow_palette(cm->allow_screen_content_tools, bsize) &&
        tile_data->allow_update_cdf)
      update_palette_cdf(xd, mi);
  }

1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
#if CONFIG_INTRABC
  if (frame_is_intra_only(cm) && av1_allow_intrabc(cm)) {
    if (tile_data->allow_update_cdf)
      update_cdf(fc->intrabc_cdf, is_intrabc_block(mbmi), 2);
#if CONFIG_ENTROPY_STATS
    ++td->counts->intrabc[is_intrabc_block(mbmi)];
#endif  // CONFIG_ENTROPY_STATS
  }
#endif  // CONFIG_INTRABC

1038
  if (!frame_is_intra_only(cm)) {
1039
    RD_COUNTS *rdc = &td->rd_counts;
1040

1041 1042
    FRAME_COUNTS *const counts = td->counts;

1043 1044
#if CONFIG_EXT_SKIP
    if (mbmi->skip_mode) {
1045
      rdc->skip_mode_used_flag = 1;
1046 1047 1048 1049 1050 1051 1052 1053 1054
      if (cm->reference_mode == REFERENCE_MODE_SELECT) {
        assert(has_second_ref(mbmi));
        rdc->compound_ref_used_flag = 1;
      }
      set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
      return;
    }
#endif  // CONFIG_EXT_SKIP

1055
    const int inter_block = is_inter_block(mbmi);
1056

1057
    if (!seg_ref_active) {
1058
      counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
1059 1060 1061
      if (allow_update_cdf)
        update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
                   inter_block, 2);
1062 1063 1064 1065 1066
      // If the segment reference feature is enabled we have only a single
      // reference frame allowed for the segment so exclude it from
      // the reference frame counts used to work out probabilities.
      if (inter_block) {
        const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1067
        const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1068

1069 1070
        av1_collect_neighbors_ref_counts(xd);

1071
        if (cm->reference_mode == REFERENCE_MODE_SELECT) {
1072 1073 1074
          if (has_second_ref(mbmi))
            // This flag is also updated for 4x4 blocks
            rdc->compound_ref_used_flag = 1;
1075
          if (is_comp_ref_allowed(bsize)) {
1076
#if CONFIG_ENTROPY_STATS
1077 1078
            counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
                              [has_second_ref(mbmi)]++;
1079
#endif  // CONFIG_ENTROPY_STATS
1080 1081 1082
            if (allow_update_cdf)
              update_cdf(av1_get_reference_mode_cdf(cm, xd),
                         has_second_ref(mbmi), 2);
1083
          }
1084
        }
1085 1086

        if (has_second_ref(mbmi)) {
1087 1088 1089 1090
#if CONFIG_EXT_COMP_REFS
          const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi)
                                                        ? UNIDIR_COMP_REFERENCE
                                                        : BIDIR_COMP_REFERENCE;
1091 1092 1093 1094 1095
          if (allow_update_cdf) {
            update_cdf(av1_get_comp_reference_type_cdf(xd), comp_ref_type,
                       COMP_REFERENCE_TYPES);
          }
#if CONFIG_ENTROPY_STATS
1096
          counts->comp_ref_type[av1_get_comp_reference_type_context(xd)]
1097
                               [comp_ref_type]++;
1098
#endif  // CONFIG_ENTROPY_STATS
1099 1100 1101

          if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
            const int bit = (ref0 == BWDREF_FRAME);
1102 1103 1104
            if (allow_update_cdf)
              update_cdf(av1_get_pred_cdf_uni_comp_ref_p(xd), bit, 2);
#if CONFIG_ENTROPY_STATS
1105
            counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p(xd)][0]
1106
                                [bit]++;
1107
#endif  // CONFIG_ENTROPY_STATS
1108
            if (!bit) {
1109
              const int bit1 = (ref1 == LAST3_FRAME || ref1 == GOLDEN_FRAME);
1110 1111 1112
              if (allow_update_cdf)
                update_cdf(av1_get_pred_cdf_uni_comp_ref_p1(xd), bit1, 2);
#if CONFIG_ENTROPY_STATS
1113 1114
              counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p1(xd)][1]
                                  [bit1]++;
1115
#endif  // CONFIG_ENTROPY_STATS
1116
              if (bit1) {
1117 1118 1119 1120 1121
                if (allow_update_cdf) {
                  update_cdf(av1_get_pred_cdf_uni_comp_ref_p2(xd),
                             ref1 == GOLDEN_FRAME, 2);
                }
#if CONFIG_ENTROPY_STATS
1122 1123
                counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p2(xd)]
                                    [2][ref1 == GOLDEN_FRAME]++;
1124
#endif  // CONFIG_ENTROPY_STATS
1125
              }
1126 1127 1128 1129
            }
          } else {
#endif  // CONFIG_EXT_COMP_REFS
            const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1130 1131 1132
            if (allow_update_cdf)
              update_cdf(av1_get_pred_cdf_comp_ref_p(cm, xd), bit, 2);
#if CONFIG_ENTROPY_STATS
1133
            counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
1134
#endif  // CONFIG_ENTROPY_STATS
1135
            if (!bit) {
1136 1137 1138 1139 1140
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_comp_ref_p1(cm, xd),
                           ref0 == LAST2_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
1141
              counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1142
                              [ref0 == LAST2_FRAME]++;
1143
#endif  // CONFIG_ENTROPY_STATS
1144
            } else {
1145 1146 1147 1148 1149
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_comp_ref_p2(cm, xd),
                           ref0 == GOLDEN_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
1150 1151
              counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
                              [ref0 == GOLDEN_FRAME]++;
1152
#endif  // CONFIG_ENTROPY_STATS
1153
            }
1154 1155 1156 1157 1158
            if (allow_update_cdf) {
              update_cdf(av1_get_pred_cdf_comp_bwdref_p(cm, xd),
                         ref1 == ALTREF_FRAME, 2);
            }
#if CONFIG_ENTROPY_STATS
1159 1160
            counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
                               [ref1 == ALTREF_FRAME]++;
1161 1162 1163 1164 1165 1166 1167
#endif  // CONFIG_ENTROPY_STATS
            if (ref1 != ALTREF_FRAME) {
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_comp_bwdref_p1(cm, xd),
                           ref1 == ALTREF2_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
Zoe Liu's avatar
Zoe Liu committed
1168 1169
              counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p1(cm, xd)]
                                 [1][ref1 == ALTREF2_FRAME]++;
1170 1171
#endif  // CONFIG_ENTROPY_STATS
            }
1172 1173 1174
#if CONFIG_EXT_COMP_REFS
          }
#endif  // CONFIG_EXT_COMP_REFS
1175
        } else {
Zoe Liu's avatar
Zoe Liu committed
1176
          const int bit = (ref0 >= BWDREF_FRAME);
1177 1178 1179
          if (allow_update_cdf)
            update_cdf(av1_get_pred_cdf_single_ref_p1(cm, xd), bit, 2);
#if CONFIG_ENTROPY_STATS
1180
          counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
1181
#endif  // CONFIG_ENTROPY_STATS
1182
          if (bit) {
Zoe Liu's avatar
Zoe Liu committed
1183
            assert(ref0 <= ALTREF_FRAME);
1184 1185 1186 1187 1188
            if (allow_update_cdf) {
              update_cdf(av1_get_pred_cdf_single_ref_p2(cm, xd),
                         ref0 == ALTREF_FRAME, 2);
            }
#if CONFIG_ENTROPY_STATS
clang-format's avatar
clang-format committed
1189
            counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
Zoe Liu's avatar
Zoe Liu committed
1190
                              [ref0 == ALTREF_FRAME]++;
1191 1192 1193 1194 1195 1196 1197
#endif  // CONFIG_ENTROPY_STATS
            if (ref0 != ALTREF_FRAME) {
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_single_ref_p6(cm, xd),
                           ref0 == ALTREF2_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
Zoe Liu's avatar
Zoe Liu committed
1198 1199
              counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
                                [ref0 == ALTREF2_FRAME]++;
1200 1201
#endif  // CONFIG_ENTROPY_STATS
            }
1202 1203
          } else {
            const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
1204 1205 1206
            if (allow_update_cdf)
              update_cdf(av1_get_pred_cdf_single_ref_p3(cm, xd), bit1, 2);
#if CONFIG_ENTROPY_STATS
clang-format's avatar
clang-format committed
1207 1208
            counts
                ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
1209
#endif  // CONFIG_ENTROPY_STATS
1210
            if (!bit1) {
1211 1212 1213 1214 1215
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_single_ref_p4(cm, xd),
                           ref0 != LAST_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
clang-format's avatar
clang-format committed
1216 1217
              counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
                                [ref0 != LAST_FRAME]++;
1218
#endif  // CONFIG_ENTROPY_STATS
1219
            } else {
1220 1221 1222 1223 1224
              if (allow_update_cdf) {
                update_cdf(av1_get_pred_cdf_single_ref_p5(cm, xd),
                           ref0 != LAST3_FRAME, 2);
              }
#if CONFIG_ENTROPY_STATS
clang-format's avatar
clang-format committed
1225 1226
              counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
                                [ref0 != LAST3_FRAME]++;
1227
#endif  // CONFIG_ENTROPY_STATS
1228 1229
            }
          }
1230
        }
1231

1232
        if (cm->allow_interintra_compound && is_interintra_allowed(mbmi)) {
1233 1234 1235
          const int bsize_group = size_group_lookup[bsize];
          if (mbmi->ref_frame[1] == INTRA_FRAME) {
            counts->interintra[bsize_group][1]++;
1236 1237
            if (allow_update_cdf)
              update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
1238
            counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;