encodeframe.c 193 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
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.
Jingning Han's avatar
Jingning Han committed
10 11 12 13 14 15
 */

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

Yaowu Xu's avatar
Yaowu Xu committed
16 17 18
#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_config.h"
Jingning Han's avatar
Jingning Han committed
19

Yaowu Xu's avatar
Yaowu Xu committed
20
#include "aom_dsp/aom_dsp_common.h"
21
#include "aom_dsp/binary_codes_writer.h"
22
#include "aom_ports/mem.h"
Yaowu Xu's avatar
Yaowu Xu committed
23
#include "aom_ports/aom_timer.h"
24
#include "aom_ports/system_state.h"
Jingning Han's avatar
Jingning Han committed
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"
Jingning Han's avatar
Jingning Han committed
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"
Angie Chiang's avatar
Angie Chiang committed
54
#include "av1/encoder/encodetxb.h"
55 56 57 58 59 60
#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"
61

62 63 64 65
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);
Jingning Han's avatar
Jingning Han committed
66 67 68 69 70

// 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.
Yaowu Xu's avatar
Yaowu Xu committed
71
static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
72 73 74 75 76
  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,
77
#if CONFIG_EXT_PARTITION
78 79 80 81 82
  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
83
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
84 85
};

Yaowu Xu's avatar
Yaowu Xu committed
86
static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
87 88 89 90 91
  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,
92
#if CONFIG_EXT_PARTITION
93 94 95 96 97
  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
98
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
99 100
};

Yaowu Xu's avatar
Yaowu Xu committed
101
static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
102 103 104 105 106 107 108 109
  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,
110
#if CONFIG_EXT_PARTITION
111 112 113 114 115 116 117 118
  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
119
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
120 121
};

Yaowu Xu's avatar
Yaowu Xu committed
122
static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
123 124 125 126 127 128 129 130 131 132
  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,
133
#if CONFIG_EXT_PARTITION
134 135 136 137 138 139 140 141 142 143
  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
144
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
145 146
};

147 148
#if CONFIG_FP_MB_STATS
static const uint8_t num_16x16_blocks_wide_lookup[BLOCK_SIZES_ALL] = {
149 150 151 152 153 154 155 156 157 158
  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)
159 160
};
static const uint8_t num_16x16_blocks_high_lookup[BLOCK_SIZES_ALL] = {
161 162 163 164 165 166 167 168 169 170
  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)
171 172 173
};
#endif  // CONFIG_FP_MB_STATS

174
unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xu's avatar
Yaowu Xu committed
175 176
                                           const struct buf_2d *ref,
                                           BLOCK_SIZE bs) {
Jingning Han's avatar
Jingning Han committed
177
  unsigned int sse;
178
  const unsigned int var =
Yaowu Xu's avatar
Yaowu Xu committed
179
      cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Jingning Han's avatar
Jingning Han committed
180 181 182
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

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

208
static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Jingning Han's avatar
Jingning Han committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222
                                                   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]);
}

Yaowu Xu's avatar
Yaowu Xu committed
223 224
static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
                                                   int mi_row, int mi_col) {
225 226
  unsigned int var = get_sby_perpixel_diff_variance(
      cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
Jingning Han's avatar
Jingning Han committed
227 228 229 230 231 232 233 234 235 236 237 238
  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.
239 240 241 242
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;
Jingning Han's avatar
Jingning Han committed
243 244 245
  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;
246
  x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
Jingning Han's avatar
Jingning Han committed
247 248
}

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

259
  set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
260

261
  set_skip_context(xd, mi_row, mi_col, num_planes);
262 263 264 265
  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);
266

Jingning Han's avatar
Jingning Han committed
267
  // Set up destination pointers.
268
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
269
                       mi_col, num_planes);
Jingning Han's avatar
Jingning Han committed
270 271 272

  // 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
273 274 275 276 277
  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;
Jingning Han's avatar
Jingning Han committed
278

279
  set_plane_n4(xd, mi_width, mi_height, num_planes);
280

Jingning Han's avatar
Jingning Han committed
281 282
  // 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)));
283
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
284
#if CONFIG_DEPENDENT_HORZTILES
285 286 287
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
288 289

  // Set up source buffers.
290
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes);
Jingning Han's avatar
Jingning Han committed
291 292 293 294

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

Yaowu Xu's avatar
Yaowu Xu committed
295
  // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
296 297 298
  xd->tile = *tile;
}

299
static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
300 301
                        MACROBLOCK *const x, int mi_row, int mi_col,
                        BLOCK_SIZE bsize) {
302
  const AV1_COMMON *const cm = &cpi->common;
303 304 305 306 307 308 309
  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;
310
#if CONFIG_CFL
311 312
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
313
#endif
314

315 316
  mbmi->segment_id = 0;

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

328
#if CONFIG_DUAL_FILTER
329
static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
330
                                    MB_MODE_INFO *mbmi) {
331 332 333 334 335 336 337 338 339
  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));
340
  }
341
  mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
342 343
}

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

378 379 380 381 382 383 384
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));
385 386 387
  } else {
    BLOCK_SIZE bsize = mbmi->sb_type;
    TX_SIZE min_tx_size =
388
        depth_to_tx_size(MAX_TX_DEPTH, bsize, is_inter_block(mbmi));
389
    mbmi->tx_size = (TX_SIZE)TXSIZEMAX(mbmi->tx_size, min_tx_size);
390
  }
391
  if (is_inter_block(mbmi)) {
392
    memset(mbmi->inter_tx_size, mbmi->tx_size, sizeof(mbmi->inter_tx_size));
393
    mbmi->min_tx_size = mbmi->tx_size;
394
  }
395 396
}

397 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
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;

  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;
      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;
      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;
        mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
        mbmi->pred_mv[i] = this_mv;
        mi_pred_mv[i] = this_mv;
      }
    }
  }
}

437 438 439
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) {
Jingning Han's avatar
Jingning Han committed
440
  int i, x_idx, y;
441
  const AV1_COMMON *const cm = &cpi->common;
442
  const int num_planes = av1_num_planes(cm);
Jingning Han's avatar
Jingning Han committed
443 444 445 446 447 448 449
  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];
Zoe Liu's avatar
Zoe Liu committed
450
  MB_MODE_INFO *const mbmi = &mi_addr->mbmi;
Jingning Han's avatar
Jingning Han committed
451
  const struct segmentation *const seg = &cm->seg;
452 453
  const int bw = mi_size_wide[mi->mbmi.sb_type];
  const int bh = mi_size_high[mi->mbmi.sb_type];
Jingning Han's avatar
Jingning Han committed
454
  const int mis = cm->mi_stride;
455 456
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
457 458
  int8_t rf_type;

Jingning Han's avatar
Jingning Han committed
459 460 461 462 463
  assert(mi->mbmi.sb_type == bsize);

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

464 465 466 467
#if CONFIG_DUAL_FILTER
  reset_intmv_filter_type(cm, xd, mbmi);
#endif

Yaowu Xu's avatar
Yaowu Xu committed
468
  rf_type = av1_ref_frame_type(mbmi->ref_frame);
469
  if (x->mbmi_ext->ref_mv_count[rf_type] > 1) {
470
    set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
David Barker's avatar
David Barker committed
471
  }
472

Jingning Han's avatar
Jingning Han committed
473 474 475 476
  // 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) {
477 478
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
Zoe Liu's avatar
Zoe Liu committed
479 480
      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
      reset_tx_size(xd, mbmi, cm->tx_mode);
481 482 483 484 485
#if CONFIG_TXK_SEL
      memset(mbmi->txk_type, DCT_DCT,
             sizeof(mbmi->txk_type[0]) *
                 (MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)));
#endif
Jingning Han's avatar
Jingning Han committed
486 487 488 489
    }
    // 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) {
Zoe Liu's avatar
Zoe Liu committed
490 491 492
      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);
493 494 495 496 497
#if CONFIG_TXK_SEL
      memset(mbmi->txk_type, DCT_DCT,
             sizeof(mbmi->txk_type[0]) *
                 (MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)));
#endif
Jingning Han's avatar
Jingning Han committed
498 499 500
    }
  }

501
  for (i = 0; i < num_planes; ++i) {
502 503 504 505
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
506
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
Jingning Han's avatar
Jingning Han committed
507
  }
508
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Jingning Han's avatar
Jingning Han committed
509 510 511 512
  // 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++)
513 514
      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) {
Jingning Han's avatar
Jingning Han committed
515 516 517
        xd->mi[x_idx + y * mis] = mi_addr;
      }

518
#if !CONFIG_EXT_DELTA_Q
519
  if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Zoe Liu's avatar
Zoe Liu committed
520
    av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
521
#else
Zoe Liu's avatar
Zoe Liu committed
522
  if (cpi->oxcf.aq_mode) av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
523
#endif
Jingning Han's avatar
Jingning Han committed
524 525

  x->skip = ctx->skip;
526

527
  for (i = 0; i < 1; ++i)
528 529
    memcpy(x->blk_skip[i], ctx->blk_skip[i],
           sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Han's avatar
Jingning Han committed
530

531
  if (dry_run) return;
Jingning Han's avatar
Jingning Han committed
532 533

#if CONFIG_INTERNAL_STATS
534 535 536 537 538
  {
    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[] = {
539 540 541 542 543 544 545 546 547
        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*/,
548
        THR_SMOOTH,   /*SMOOTH_PRED*/
Urvang Joshi's avatar
Urvang Joshi committed
549 550
        THR_SMOOTH_V, /*SMOOTH_V_PRED*/
        THR_SMOOTH_H, /*SMOOTH_H_PRED*/
Urvang Joshi's avatar
Urvang Joshi committed
551
        THR_PAETH /*PAETH_PRED*/,
552 553 554 555 556 557
      };
      ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
    } else {
      // Note how often each mode chosen as best
      ++mode_chosen_counts[ctx->best_mode_index];
    }
Jingning Han's avatar
Jingning Han committed
558 559 560 561
  }
#endif
  if (!frame_is_intra_only(cm)) {
    if (is_inter_block(mbmi)) {
562 563 564 565 566 567 568
      // 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)) {
569
#if CONFIG_DUAL_FILTER
570 571
      update_filter_type_count(tile_data->allow_update_cdf, td->counts, xd,
                               mbmi);
572
#else
573 574 575 576 577
      (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];
578
#endif
Jingning Han's avatar
Jingning Han committed
579 580 581 582 583 584 585
    }

    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;
  }

586 587 588
  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);
Jingning Han's avatar
Jingning Han committed
589 590
}

Yaowu Xu's avatar
Yaowu Xu committed
591
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
592
                          int mi_row, int mi_col, const int num_planes) {
Jingning Han's avatar
Jingning Han committed
593 594 595
  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

596 597 598 599 600 601 602 603
  // 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,
Jingning Han's avatar
Jingning Han committed
604
                     x->e_mbd.plane[i].subsampling_y);
605
  }
Jingning Han's avatar
Jingning Han committed
606 607
}

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

617
static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
618
                             MACROBLOCK *const x, int mi_row, int mi_col,
Angie Chiang's avatar
Angie Chiang committed
619
                             RD_STATS *rd_cost,
620 621
#if CONFIG_EXT_PARTITION_TYPES
                             PARTITION_TYPE partition,
622
#endif
Jingning Han's avatar
Jingning Han committed
623 624
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
625
  const AV1_COMMON *const cm = &cpi->common;
626
  const int num_planes = av1_num_planes(cm);
Jingning Han's avatar
Jingning Han committed
627 628 629
  TileInfo *const tile_info = &tile_data->tile_info;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *mbmi;
630
  MB_MODE_INFO *ctx_mbmi = &ctx->mic.mbmi;
Jingning Han's avatar
Jingning Han committed
631 632 633 634 635
  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;

Yaowu Xu's avatar
Yaowu Xu committed
636
  aom_clear_system_state();
Jingning Han's avatar
Jingning Han committed
637 638

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

Jingning Han's avatar
Jingning Han committed
640
  mbmi = &xd->mi[0]->mbmi;
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657

  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
  }

658 659 660 661
#if CONFIG_RD_DEBUG
  mbmi->mi_row = mi_row;
  mbmi->mi_col = mi_col;
#endif
Jingning Han's avatar
Jingning Han committed
662

663
  for (i = 0; i < num_planes; ++i) {
664 665 666 667
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
668
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
Jingning Han's avatar
Jingning Han committed
669
  }
hui su's avatar
hui su committed
670

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

673 674
  if (!ctx->rd_mode_is_ready) {
    ctx->skippable = 0;
Jingning Han's avatar
Jingning Han committed
675

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

#if CONFIG_EXT_SKIP
    // Reset skip mode flag.
    mbmi->skip_mode = 0;
#endif
683
  }
Jingning Han's avatar
Jingning Han committed
684

685
  x->skip_chroma_rd =
686 687
      !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y);
688

689 690 691 692 693 694
  if (ctx->rd_mode_is_ready) {
    x->skip = ctx->skip;
    *x->mbmi_ext = ctx->mbmi_ext;
    return;
  }

Jingning Han's avatar
Jingning Han committed
695
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
696
    x->source_variance = av1_high_get_sby_perpixel_variance(
697
        cpi, &x->plane[0].src, bsize, xd->bd);
Jingning Han's avatar
Jingning Han committed
698 699
  } else {
    x->source_variance =
Yaowu Xu's avatar
Yaowu Xu committed
700
        av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Jingning Han's avatar
Jingning Han committed
701 702 703 704 705 706
  }

  // 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
707
    if (cpi->vaq_refresh) {
Yaowu Xu's avatar
Yaowu Xu committed
708 709 710
      const int energy =
          bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
      mbmi->segment_id = av1_vaq_segment_id(energy);
Jingning Han's avatar
Jingning Han committed
711 712 713 714 715 716
    }
    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
717
    if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xu's avatar
Yaowu Xu committed
718
      x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
719 720 721 722 723
  }

  // 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)) {
724 725
    av1_rd_pick_intra_mode_sb(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx,
                              best_rd);
Jingning Han's avatar
Jingning Han committed
726
  } else {
727 728 729
    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);
Jingning Han's avatar
Jingning Han committed
730
    } else {
731 732
      av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
                                bsize, ctx, best_rd);
Jingning Han's avatar
Jingning Han committed
733 734 735 736
    }
  }

  // Examine the resulting rate and for AQ mode 2 make a segment choice.
737 738 739
  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
740
       cpi->refresh_alt2_ref_frame ||
Jingning Han's avatar
Jingning Han committed
741
       (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xu's avatar
Yaowu Xu committed
742
    av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Jingning Han's avatar
Jingning Han committed
743 744 745 746 747 748
  }

  x->rdmult = orig_rdmult;

  // TODO(jingning) The rate-distortion optimization flow needs to be
  // refactored to provide proper exit/return handle.
749
  if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
Jingning Han's avatar
Jingning Han committed
750 751 752

  ctx->rate = rd_cost->rate;
  ctx->dist = rd_cost->dist;
753
  ctx->rdcost = rd_cost->rdcost;
Jingning Han's avatar
Jingning Han committed
754 755
}

756
static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
757 758
                                    int16_t mode_context) {
  int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
759 760 761 762 763
  if (mode == NEWMV) {
    ++counts->newmv_mode[mode_ctx][0];
    return;
  } else {
    ++counts->newmv_mode[mode_ctx][1];
764

Sarah Parker's avatar
Sarah Parker committed
765 766
    mode_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
    if (mode == GLOBALMV) {
767 768 769 770
      ++counts->zeromv_mode[mode_ctx][0];
      return;
    } else {
      ++counts->zeromv_mode[mode_ctx][1];
771
      mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
772 773 774 775 776
      ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
    }
  }
}

777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
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;
793
    const int tx_size_ctx = get_tx_size_context(xd, 0);
794 795 796 797 798 799 800 801 802 803 804
    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
805 806
    const int above_ctx = intra_mode_context[above];
    const int left_ctx = intra_mode_context[left];
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
    ++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) {
Hui Su's avatar
Hui Su committed
832
      if (use_filter_intra_mode) {
833 834 835
        update_cdf(fc->filter_intra_mode_cdf,
                   mbmi->filter_intra_mode_info.filter_intra_mode,
                   FILTER_INTRA_MODES);
Hui Su's avatar
Hui Su committed
836
      }
837 838 839 840 841
      update_cdf(fc->filter_intra_cdfs[mbmi->tx_size], use_filter_intra_mode,
                 2);
    }
  }
#endif  // CONFIG_FILTER_INTRA
Hui Su's avatar
Hui Su committed
842
#if CONFIG_EXT_INTRA_MOD
843 844 845 846
  if (av1_is_directional_mode(mbmi->mode, bsize) &&
      av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
    ++counts->angle_delta[mbmi->mode - V_PRED]
847
                         [mbmi->angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA];
848
#endif
Hui Su's avatar
Hui Su committed
849
    if (allow_update_cdf) {
850
      update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
851
                 mbmi->angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA,
852
                 2 * MAX_ANGLE_DELTA + 1);
Hui Su's avatar
Hui Su committed
853
    }
854
  }
Hui Su's avatar
Hui Su committed
855
#endif  // CONFIG_EXT_INTRA_MOD
856

857 858 859
  if (!is_chroma_reference(mi_row, mi_col, bsize,
                           xd->plane[AOM_PLANE_U].subsampling_x,
                           xd->plane[AOM_PLANE_U].subsampling_y))
860
    return;
Hui Su's avatar
Hui Su committed
861
#if CONFIG_EXT_INTRA_MOD
862 863 864 865
  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]
866
                         [mbmi->angle_delta[PLANE_TYPE_UV] + MAX_ANGLE_DELTA];
867
#endif
Hui Su's avatar
Hui Su committed
868
    if (allow_update_cdf) {
869
      update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
870
                 mbmi->angle_delta[PLANE_TYPE_UV] + MAX_ANGLE_DELTA,
871
                 2 * MAX_ANGLE_DELTA + 1);
Hui Su's avatar
Hui Su committed
872
    }
873
  }
Hui Su's avatar
Hui Su committed
874
#endif  // CONFIG_EXT_INTRA_MOD
875
#if CONFIG_ENTROPY_STATS
876 877 878
#if CONFIG_CFL
  ++counts->uv_mode[is_cfl_allowed(mbmi)][y_mode][uv_mode];
#else
879
  ++counts->uv_mode[y_mode][uv_mode];
880
#endif  // CONFIG_CFL
881
#endif  // CONFIG_ENTROPY_STATS
882 883 884 885 886 887 888
#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
889 890
  if (allow_update_cdf)
    update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
891
#endif  // CONFIG_CFL
892 893 894 895 896 897 898 899 900 901 902 903
}

// 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
904 905 906 907
    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);
908 909 910 911 912 913 914 915 916
  }

  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);
  }
}

917 918
static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
                         ThreadData *td, int mi_row, int mi_col) {
919 920
  MACROBLOCK *x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han's avatar
Jingning Han committed
921 922 923 924
  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;
925
  FRAME_CONTEXT *fc = xd->tile_ctx;
926
  const uint8_t allow_update_cdf = tile_data->allow_update_cdf;
Jingning Han's avatar
Jingning Han committed
927

928
  // delta quant applies to both intra and inter
929 930 931
  const int super_block_upper_left =
      ((mi_row & (cm->seq_params.mib_size - 1)) == 0) &&
      ((mi_col & (cm->seq_params.mib_size - 1)) == 0);
932

933 934 935
  const int seg_ref_active =
      segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);

Zoe Liu's avatar
Zoe Liu committed
936 937 938 939 940 941
#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);
942 943
  }

Zoe Liu's avatar
Zoe Liu committed
944 945 946