encodeframe.c 176 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
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);
Jingning Han's avatar
Jingning Han committed
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.
Yaowu Xu's avatar
Yaowu Xu committed
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
Jingning Han's avatar
Jingning Han committed
86
87
};

88
#if CONFIG_HIGHBITDEPTH
Yaowu Xu's avatar
Yaowu Xu committed
89
static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
90
91
92
93
94
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
95
#if CONFIG_EXT_PARTITION
96
97
98
99
100
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
101
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
102
103
};

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

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

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

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

187
#if CONFIG_HIGHBITDEPTH
188
unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xu's avatar
Yaowu Xu committed
189
190
                                                const struct buf_2d *ref,
                                                BLOCK_SIZE bs, int bd) {
Jingning Han's avatar
Jingning Han committed
191
192
193
  unsigned int var, sse;
  switch (bd) {
    case 10:
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_10), 0, &sse);
Jingning Han's avatar
Jingning Han committed
197
198
      break;
    case 12:
Yaowu Xu's avatar
Yaowu Xu committed
199
200
201
      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
202
203
204
      break;
    case 8:
    default:
205
206
      var =
          cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xu's avatar
Yaowu Xu committed
207
                             CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Jingning Han's avatar
Jingning Han committed
208
209
210
211
      break;
  }
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}
212
#endif  // CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
213

214
static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Jingning Han's avatar
Jingning Han committed
215
216
217
218
219
220
221
222
223
224
225
226
227
228
                                                   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
229
230
static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
                                                   int mi_row, int mi_col) {
231
232
  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
233
234
235
236
237
238
239
240
241
242
243
244
  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.
245
246
247
248
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
249
250
251
  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;
252
  x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
Jingning Han's avatar
Jingning Han committed
253
254
}

255
static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
256
                                           const TileInfo *const tile,
257
258
                                           MACROBLOCK *const x, int mi_row,
                                           int mi_col, BLOCK_SIZE bsize) {
259
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
260
  MACROBLOCKD *const xd = &x->e_mbd;
261
262
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
Jingning Han's avatar
Jingning Han committed
263

264
  set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
265

266
  set_skip_context(xd, mi_row, mi_col);
267
268
269
270
  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);
271

Jingning Han's avatar
Jingning Han committed
272
  // Set up destination pointers.
273
274
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
275
276
277

  // 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
278
279
280
281
282
  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
283

Jingning Han's avatar
Jingning Han committed
284
  set_plane_n4(xd, mi_width, mi_height);
285

Jingning Han's avatar
Jingning Han committed
286
287
  // 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)));
288
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
289
#if CONFIG_DEPENDENT_HORZTILES
290
291
292
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
293
294

  // Set up source buffers.
295
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
Jingning Han's avatar
Jingning Han committed
296
297
298
299

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

Yaowu Xu's avatar
Yaowu Xu committed
300
  // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
301
302
303
  xd->tile = *tile;
}

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

320
321
  mbmi->segment_id = 0;

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

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

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

382
383
384
385
386
387
388
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));
389
390
391
  } else {
    BLOCK_SIZE bsize = mbmi->sb_type;
    TX_SIZE min_tx_size =
392
        depth_to_tx_size(MAX_TX_DEPTH, bsize, is_inter_block(mbmi));
393
    mbmi->tx_size = (TX_SIZE)TXSIZEMAX(mbmi->tx_size, min_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
437
438
439
440
441
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;
      }
    }
  }
}

442
443
444
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
445
  int i, x_idx, y;
446
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
447
448
449
450
451
452
453
454
455
  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;
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  MODE_INFO *mi_addr = xd->mi[0];
  const struct segmentation *const seg = &cm->seg;
456
457
  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
458
  const int mis = cm->mi_stride;
459
460
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
461
462
  int8_t rf_type;

Jingning Han's avatar
Jingning Han committed
463
464
465
466
467
  assert(mi->mbmi.sb_type == bsize);

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

468
469
470
471
#if CONFIG_DUAL_FILTER
  reset_intmv_filter_type(cm, xd, mbmi);
#endif

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

Jingning Han's avatar
Jingning Han committed
477
478
479
480
  // 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) {
481
482
483
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
      mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
484
      reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
485
486
487
488
    }
    // 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) {
Yaowu Xu's avatar
Yaowu Xu committed
489
490
      av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
                                        bsize, ctx->rate, ctx->dist, x->skip);
491
      reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
492
493
494
    }
  }

495
496
497
498
499
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
500
501
502
#if CONFIG_LV_MAP
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif  // CONFIG_LV_MAP
Jingning Han's avatar
Jingning Han committed
503
  }
504
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Jingning Han's avatar
Jingning Han committed
505
506
507
508
  // 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++)
509
510
      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
511
512
513
        xd->mi[x_idx + y * mis] = mi_addr;
      }

514
#if !CONFIG_EXT_DELTA_Q
515
  if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
516
    av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
517
#else
Jingning Han's avatar
Jingning Han committed
518
  if (cpi->oxcf.aq_mode)
Yaowu Xu's avatar
Yaowu Xu committed
519
    av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
520
#endif
Jingning Han's avatar
Jingning Han committed
521
522

  x->skip = ctx->skip;
523

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

528
  if (dry_run) return;
Jingning Han's avatar
Jingning Han committed
529
530

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

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

583
584
585
  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
586
587
}

Yaowu Xu's avatar
Yaowu Xu committed
588
589
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
                          int mi_row, int mi_col) {
590
591
592
593
594
595
  uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
  const int widths[3] = { src->y_crop_width, src->uv_crop_width,
                          src->uv_crop_width };
  const int heights[3] = { src->y_crop_height, src->uv_crop_height,
                           src->uv_crop_height };
  const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
Jingning Han's avatar
Jingning Han committed
596
597
598
599
600
601
  int i;

  // Set current frame pointer.
  x->e_mbd.cur_buf = src;

  for (i = 0; i < MAX_MB_PLANE; i++)
602
603
    setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type, buffers[i],
                     widths[i], heights[i], strides[i], mi_row, mi_col, NULL,
604
                     x->e_mbd.plane[i].subsampling_x,
Jingning Han's avatar
Jingning Han committed
605
606
607
                     x->e_mbd.plane[i].subsampling_y);
}

608
static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
609
                              int8_t segment_id) {
Jingning Han's avatar
Jingning Han committed
610
  int segment_qindex;
611
  const AV1_COMMON *const cm = &cpi->common;
Yaowu Xu's avatar
Yaowu Xu committed
612
613
614
615
  av1_init_plane_quantizers(cpi, x, segment_id);
  aom_clear_system_state();
  segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
  return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Jingning Han's avatar
Jingning Han committed
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,
Angie Chiang's avatar
Angie Chiang committed
620
                             RD_STATS *rd_cost,
621
622
#if CONFIG_EXT_PARTITION_TYPES
                             PARTITION_TYPE partition,
623
#endif
Jingning Han's avatar
Jingning Han committed
624
625
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
626
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
627
628
629
630
631
632
633
634
  TileInfo *const tile_info = &tile_data->tile_info;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *mbmi;
  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
635
  aom_clear_system_state();
Jingning Han's avatar
Jingning Han committed
636
637
638
639

  set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
  mbmi = &xd->mi[0]->mbmi;
  mbmi->sb_type = bsize;
640
641
642
643
#if CONFIG_RD_DEBUG
  mbmi->mi_row = mi_row;
  mbmi->mi_col = mi_col;
#endif
644
645
646
#if CONFIG_EXT_PARTITION_TYPES
  mbmi->partition = partition;
#endif
Jingning Han's avatar
Jingning Han committed
647
648

  for (i = 0; i < MAX_MB_PLANE; ++i) {
649
650
651
652
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
653
654
655
#if CONFIG_LV_MAP
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif
Jingning Han's avatar
Jingning Han committed
656
  }
hui su's avatar
hui su committed
657

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

Jingning Han's avatar
Jingning Han committed
660
661
662
663
664
  ctx->skippable = 0;

  // Set to zero to make sure we do not use the previous encoded frame stats
  mbmi->skip = 0;

665
  x->skip_chroma_rd =
666
667
      !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y);
668

669
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
670
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
671
    x->source_variance = av1_high_get_sby_perpixel_variance(
672
        cpi, &x->plane[0].src, bsize, xd->bd);
Jingning Han's avatar
Jingning Han committed
673
674
  } else {
    x->source_variance =
Yaowu Xu's avatar
Yaowu Xu committed
675
        av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Jingning Han's avatar
Jingning Han committed
676
677
678
  }
#else
  x->source_variance =
Yaowu Xu's avatar
Yaowu Xu committed
679
      av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
680
#endif  // CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
681
682
683
684
685

  // 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
686
    if (cpi->vaq_refresh) {
Yaowu Xu's avatar
Yaowu Xu committed
687
688
689
      const int energy =
          bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
      mbmi->segment_id = av1_vaq_segment_id(energy);
690
      // Re-initialise quantiser
Yaowu Xu's avatar
Yaowu Xu committed
691
      av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
692
693
694
695
696
697
    }
    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
698
    if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xu's avatar
Yaowu Xu committed
699
      x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
700
701
702
703
704
  }

  // 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)) {
Yaowu Xu's avatar
Yaowu Xu committed
705
    av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Jingning Han's avatar
Jingning Han committed
706
  } else {
707
708
709
    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
710
    } else {
711
712
      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
713
714
715
716
    }
  }

  // Examine the resulting rate and for AQ mode 2 make a segment choice.
717
718
719
  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
720
       cpi->refresh_alt2_ref_frame ||
Jingning Han's avatar
Jingning Han committed
721
       (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xu's avatar
Yaowu Xu committed
722
    av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Jingning Han's avatar
Jingning Han committed
723
724
725
726
727
728
  }

  x->rdmult = orig_rdmult;

  // TODO(jingning) The rate-distortion optimization flow needs to be
  // refactored to provide proper exit/return handle.
729
  if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
Jingning Han's avatar
Jingning Han committed
730
731
732
733
734

  ctx->rate = rd_cost->rate;
  ctx->dist = rd_cost->dist;
}

735
static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
736
737
                                    int16_t mode_context) {
  int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
738
739
740
741
742
  if (mode == NEWMV) {
    ++counts->newmv_mode[mode_ctx][0];
    return;
  } else {
    ++counts->newmv_mode[mode_ctx][1];
743
744
745
746
747

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

Sarah Parker's avatar
Sarah Parker committed
748
749
    mode_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
    if (mode == GLOBALMV) {
750
751
752
753
      ++counts->zeromv_mode[mode_ctx][0];
      return;
    } else {
      ++counts->zeromv_mode[mode_ctx][1];
754
      mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
755

756
757
758
      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;
759

760
761
762
763
764
      ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
    }
  }
}

765
766
static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
                         ThreadData *td, int mi_row, int mi_col) {
767
768
  MACROBLOCK *x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han's avatar
Jingning Han committed
769
770
771
772
  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;
773
  FRAME_CONTEXT *fc = xd->tile_ctx;
774
  const uint8_t allow_update_cdf = tile_data->allow_update_cdf;
Jingning Han's avatar
Jingning Han committed
775

776
  // delta quant applies to both intra and inter
777
778
  const int super_block_upper_left = ((mi_row & (cm->mib_size - 1)) == 0) &&
                                     ((mi_col & (cm->mib_size - 1)) == 0);
779

780
781
782
  const int seg_ref_active =
      segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);

Zoe Liu's avatar
Zoe Liu committed
783
784
785
786
787
788
#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);
789
790
  }

Zoe Liu's avatar
Zoe Liu committed
791
792
793
794
795
796
797
798
799
800
801
  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

802
  if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
803
804
805
806
      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;
807
    for (i = 0; i < AOMMIN(absdq, DELTA_Q_SMALL); ++i) {
808
809
810
811
      td->counts->delta_q[i][1]++;
    }
    if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
    xd->prev_qindex = mbmi->current_q_index;
Fangwen Fu's avatar
Fangwen Fu committed
812
#if CONFIG_EXT_DELTA_Q
813
814
#if CONFIG_LOOPFILTER_LEVEL
    if (cm->delta_lf_present_flag) {
815
816
817
818
819
820
821
822
823
824
825
826
827
828
      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 {
829
        const int delta_lf =
830
            (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
831
832
833
            cm->delta_lf_res;
        const int abs_delta_lf = abs(delta_lf);
        for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
834
          td->counts->delta_lf[i][1]++;
835
836
        }
        if (abs_delta_lf < DELTA_LF_SMALL)
837
838
          td->counts->delta_lf[abs_delta_lf][0]++;
        xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
839
840
841
      }
    }
#else
Fangwen Fu's avatar
Fangwen Fu committed
842
843
844
845
846
847
848
849
850
851
852
    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;
    }
853
#endif  // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu's avatar
Fangwen Fu committed
854
#endif
855
  }
Zoe Liu's avatar
Zoe Liu committed
856

Jingning Han's avatar
Jingning Han committed
857
  if (!frame_is_intra_only(cm)) {
858
    RD_COUNTS *rdc = &td->rd_counts;
Zoe Liu's avatar
Zoe Liu committed
859

860
861
    FRAME_COUNTS *const counts = td->counts;

Zoe Liu's avatar
Zoe Liu committed
862
863
#if CONFIG_EXT_SKIP
    if (mbmi->skip_mode) {
864
      rdc->skip_mode_used_flag = 1;
Zoe Liu's avatar
Zoe Liu committed
865
866
867
868
869
870
871
872
873
      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

Jingning Han's avatar
Jingning Han committed
874
    const int inter_block = is_inter_block(mbmi);
Zoe Liu's avatar
Zoe Liu committed
875

Jingning Han's avatar
Jingning Han committed
876
    if (!seg_ref_active) {
877
      counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
878
879
880
      if (allow_update_cdf)
        update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
                   inter_block, 2);
Jingning Han's avatar
Jingning Han committed
881
882
883
884
885
      // 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];
886
        const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
887

888
        if (cm->reference_mode == REFERENCE_MODE_SELECT) {
889
890
891
          if (has_second_ref(mbmi))
            // This flag is also updated for 4x4 blocks
            rdc->compound_ref_used_flag = 1;
Zoe Liu's avatar
Zoe Liu committed
892
#if !CONFIG_REF_ADAPT
893
894
895
          else
            // This flag is also updated for 4x4 blocks
            rdc->single_ref_used_flag = 1;
Zoe Liu's avatar
Zoe Liu committed
896
#endif  // !CONFIG_REF_ADAPT
897
          if (is_comp_ref_allowed(bsize)) {
898
899
            counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
                              [has_second_ref(mbmi)]++;
900
901
902
            if (allow_update_cdf)
              update_cdf(av1_get_reference_mode_cdf(cm, xd),
                         has_second_ref(mbmi), 2);
903
          }
904
        }
Jingning Han's avatar
Jingning Han committed
905
906

        if (has_second_ref(mbmi)) {
Zoe Liu's avatar
Zoe Liu committed
907
908
909
910
#if CONFIG_EXT_COMP_REFS
          const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi)
                                                        ? UNIDIR_COMP_REFERENCE
                                                        : BIDIR_COMP_REFERENCE;
911
          counts->comp_ref_type[av1_get_comp_reference_type_context(xd)]
Zoe Liu's avatar
Zoe Liu committed
912
913
914
915
                               [comp_ref_type]++;

          if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
            const int bit = (ref0 == BWDREF_FRAME);
916
            counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p(xd)][0]
Zoe Liu's avatar
Zoe Liu committed
917
918
                                [bit]++;
            if (!bit) {
919
920
921
922
923
924
925
              const int bit1 = (ref1 == LAST3_FRAME || ref1 == GOLDEN_FRAME);
              counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p1(xd)][1]
                                  [bit1]++;
              if (bit1) {
                counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p2(xd)]
                                    [2][ref1 == GOLDEN_FRAME]++;
              }
Zoe Liu's avatar
Zoe Liu committed
926
927
928
929
            }
          } else {
#endif  // CONFIG_EXT_COMP_REFS
            const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
930

Zoe Liu's avatar
Zoe Liu committed
931
932
933
            counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
            if (!bit) {
              counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
934
                              [ref0 == LAST2_FRAME]++;
Zoe Liu's avatar
Zoe Liu committed
935
936
937
938
            } else {
              counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
                              [ref0 == GOLDEN_FRAME]++;
            }
939

Zoe Liu's avatar
Zoe Liu committed
940
941
            counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
                               [ref1 == ALTREF_FRAME]++;
Zoe Liu's avatar
Zoe Liu committed
942
943
944
            if (ref1 != ALTREF_FRAME)
              counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p1(cm, xd)]
                                 [1][ref1 == ALTREF2_FRAME]++;
Zoe Liu's avatar
Zoe Liu committed
945
946
947
#if CONFIG_EXT_COMP_REFS
          }
#endif  // CONFIG_EXT_COMP_REFS
Jingning Han's avatar
Jingning Han committed
948
        } else {
Zoe Liu's avatar
Zoe Liu committed
949
          const int bit = (ref0 >= BWDREF_FRAME);
950

Yaowu Xu's avatar
Yaowu Xu committed
951
          counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
952
          if (bit) {
Zoe Liu's avatar
Zoe Liu committed
953
            assert(ref0 <= ALTREF_FRAME);
clang-format's avatar
clang-format committed
954
            counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
Zoe Liu's avatar
Zoe Liu committed
955
956
957
958
                              [ref0 == ALTREF_FRAME]++;
            if (ref0 != ALTREF_FRAME)
              counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
                                [ref0 == ALTREF2_FRAME]++;
959
960
          } else {
            const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format's avatar
clang-format committed
961
962
            counts
                ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
963
            if (!bit1) {
clang-format's avatar
clang-format committed
964
965
              counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
                                [ref0 != LAST_FRAME]++;
966
            } else {
clang-format's avatar
clang-format committed
967
968
              counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
                                [ref0 != LAST3_FRAME]++;
969
970
            }
          }
Jingning Han's avatar
Jingning Han committed
971
        }
972

Zoe Liu's avatar