encodeframe.c 186 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

26
27
28
29
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/idct.h"
30
#include "av1/common/mv.h"
31
32
33
34
35
36
37
#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
38

39
40
41
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
42
#include "av1/common/warped_motion.h"
43
44
45
46
#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
47
48
49
#if CONFIG_LV_MAP
#include "av1/encoder/encodetxb.h"
#endif
50
51
52
53
54
55
#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"
56
#if CONFIG_HIGHBITDEPTH
57
#define IF_HBD(...) __VA_ARGS__
58
#else
59
#define IF_HBD(...)
60
#endif  // CONFIG_HIGHBITDEPTH
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
};

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

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

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

149
unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xu's avatar
Yaowu Xu committed
150
151
                                           const struct buf_2d *ref,
                                           BLOCK_SIZE bs) {
Jingning Han's avatar
Jingning Han committed
152
  unsigned int sse;
153
  const unsigned int var =
Yaowu Xu's avatar
Yaowu Xu committed
154
      cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Jingning Han's avatar
Jingning Han committed
155
156
157
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}

158
#if CONFIG_HIGHBITDEPTH
159
unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xu's avatar
Yaowu Xu committed
160
161
                                                const struct buf_2d *ref,
                                                BLOCK_SIZE bs, int bd) {
Jingning Han's avatar
Jingning Han committed
162
163
164
  unsigned int var, sse;
  switch (bd) {
    case 10:
Yaowu Xu's avatar
Yaowu Xu committed
165
166
167
      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
168
169
      break;
    case 12:
Yaowu Xu's avatar
Yaowu Xu committed
170
171
172
      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
173
174
175
      break;
    case 8:
    default:
176
177
      var =
          cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xu's avatar
Yaowu Xu committed
178
                             CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Jingning Han's avatar
Jingning Han committed
179
180
181
182
      break;
  }
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
}
183
#endif  // CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
184

185
static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Jingning Han's avatar
Jingning Han committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
                                                   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
200
201
static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
                                                   int mi_row, int mi_col) {
202
203
  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
204
205
206
207
208
209
210
211
212
213
214
215
  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.
216
217
218
219
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
220
221
222
  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;
223
  x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
Jingning Han's avatar
Jingning Han committed
224
225
}

226
static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
227
                                           const TileInfo *const tile,
228
229
                                           MACROBLOCK *const x, int mi_row,
                                           int mi_col, BLOCK_SIZE bsize) {
230
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
231
  MACROBLOCKD *const xd = &x->e_mbd;
232
233
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
Jingning Han's avatar
Jingning Han committed
234

235
  set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
236

237
  set_skip_context(xd, mi_row, mi_col);
238
239
240
241
  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);
242

Jingning Han's avatar
Jingning Han committed
243
  // Set up destination pointers.
244
245
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
246
247
248

  // 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
249
250
251
252
253
  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
254

Jingning Han's avatar
Jingning Han committed
255
  set_plane_n4(xd, mi_width, mi_height);
256

Jingning Han's avatar
Jingning Han committed
257
258
  // 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)));
259
  set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
260
#if CONFIG_DEPENDENT_HORZTILES
261
262
263
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
264
265

  // Set up source buffers.
266
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
Jingning Han's avatar
Jingning Han committed
267
268
269
270

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

Yaowu Xu's avatar
Yaowu Xu committed
271
  // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
272
273
274
  xd->tile = *tile;
}

275
static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
276
277
                        MACROBLOCK *const x, int mi_row, int mi_col,
                        BLOCK_SIZE bsize) {
278
  const AV1_COMMON *const cm = &cpi->common;
279
280
281
282
283
284
285
  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;
286
287
288
289
#if CONFIG_CFL
  xd->cfl->mi_row = mi_row;
  xd->cfl->mi_col = mi_col;
#endif
290

Jingning Han's avatar
Jingning Han committed
291
292
  // Setup segment ID.
  if (seg->enabled) {
Geza Lore's avatar
Geza Lore committed
293
    if (!cpi->vaq_refresh) {
294
295
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
Jingning Han's avatar
Jingning Han committed
296
297
      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
    }
Yaowu Xu's avatar
Yaowu Xu committed
298
    av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
299
300
301
  } else {
    mbmi->segment_id = 0;
  }
302
303
}

304
#if CONFIG_DUAL_FILTER
305
static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
306
                                    MB_MODE_INFO *mbmi) {
307
308
309
310
311
312
313
314
315
  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));
316
  }
317
  mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
318
319
}

320
321
static void update_filter_type_count(uint8_t allow_update_cdf,
                                     FRAME_COUNTS *counts,
322
323
324
                                     const MACROBLOCKD *xd,
                                     const MB_MODE_INFO *mbmi) {
  int dir;
325
  for (dir = 0; dir < 2; ++dir) {
326
    if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
327
        (mbmi->ref_frame[1] > INTRA_FRAME &&
328
         has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xu's avatar
Yaowu Xu committed
329
      const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
330
331
332
      InterpFilter filter =
          av1_extract_interp_filter(mbmi->interp_filters, dir);
      ++counts->switchable_interp[ctx][filter];
333
334
335
      if (allow_update_cdf)
        update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
                   SWITCHABLE_FILTERS);
336
337
338
339
    }
  }
}
#endif
Debargha Mukherjee's avatar
Debargha Mukherjee committed
340
static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
341
342
                                      const MB_MODE_INFO *mbmi,
                                      RD_COUNTS *rdc) {
Sarah Parker's avatar
Sarah Parker committed
343
  if (mode == GLOBALMV || mode == GLOBAL_GLOBALMV) {
344
345
    const int num_4x4s =
        num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
346
347
    int ref;
    for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
348
      rdc->global_motion_used[mbmi->ref_frame[ref]] += num_4x4s;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
349
    }
350
351
  }
}
352

353
354
355
356
357
358
359
360
361
362
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));
  }
}

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
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;
    }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
#if CONFIG_COMPOUND_SINGLEREF
  } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
    // Special case: SR_NEAR_NEWMV uses 1 + mbmi->ref_mv_idx
    // (like NEARMV) instead
    if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx += 1;

    if (compound_ref0_mode(mbmi->mode) == NEWMV ||
        compound_ref1_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;
    }
#endif  // CONFIG_COMPOUND_SINGLEREF
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  } 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;
      }
    }
  }
}

423
424
425
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
426
  int i, x_idx, y;
427
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
428
429
430
431
432
433
434
435
436
  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;
437
438
  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
439
  const int mis = cm->mi_stride;
440
441
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
442
443
  int8_t rf_type;

Jingning Han's avatar
Jingning Han committed
444
445
446
447
448
  assert(mi->mbmi.sb_type == bsize);

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

449
450
451
452
#if CONFIG_DUAL_FILTER
  reset_intmv_filter_type(cm, xd, mbmi);
#endif

Yaowu Xu's avatar
Yaowu Xu committed
453
  rf_type = av1_ref_frame_type(mbmi->ref_frame);
454
  if (x->mbmi_ext->ref_mv_count[rf_type] > 1) {
455
    set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
David Barker's avatar
David Barker committed
456
  }
457

Jingning Han's avatar
Jingning Han committed
458
459
460
461
  // 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) {
462
463
464
      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);
465
      reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
466
467
468
469
    }
    // 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
470
471
      av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
                                        bsize, ctx->rate, ctx->dist, x->skip);
472
      reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
473
474
475
    }
  }

476
477
478
479
480
  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];
481
482
483
#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
484
  }
485
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
486
487
488
#if CONFIG_MRC_TX
  xd->mrc_mask = ctx->mrc_mask;
#endif  // CONFIG_MRC_TX
Jingning Han's avatar
Jingning Han committed
489
490
491
492
  // 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++)
493
494
      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
495
496
497
        xd->mi[x_idx + y * mis] = mi_addr;
      }

498
#if !CONFIG_EXT_DELTA_Q
499
  if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
500
    av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
501
#else
Jingning Han's avatar
Jingning Han committed
502
  if (cpi->oxcf.aq_mode)
Yaowu Xu's avatar
Yaowu Xu committed
503
    av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
504
#endif
Jingning Han's avatar
Jingning Han committed
505
506

  x->skip = ctx->skip;
507

508
  for (i = 0; i < 1; ++i)
509
510
    memcpy(x->blk_skip[i], ctx->blk_skip[i],
           sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Han's avatar
Jingning Han committed
511

512
  if (dry_run) return;
Jingning Han's avatar
Jingning Han committed
513
514

#if CONFIG_INTERNAL_STATS
515
516
517
518
519
  {
    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[] = {
520
521
522
523
524
525
526
527
528
529
        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*/,
        THR_SMOOTH, /*SMOOTH_PRED*/
Urvang Joshi's avatar
Urvang Joshi committed
530
531
532
533
#if CONFIG_SMOOTH_HV
        THR_SMOOTH_V, /*SMOOTH_V_PRED*/
        THR_SMOOTH_H, /*SMOOTH_H_PRED*/
#endif                // CONFIG_SMOOTH_HV
Urvang Joshi's avatar
Urvang Joshi committed
534
        THR_PAETH /*PAETH_PRED*/,
535
536
537
538
539
540
      };
      ++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
541
542
543
544
  }
#endif
  if (!frame_is_intra_only(cm)) {
    if (is_inter_block(mbmi)) {
Yaowu Xu's avatar
Yaowu Xu committed
545
      av1_update_mv_count(td);
546
      if (bsize >= BLOCK_8X8) {
547
548
        // TODO(sarahparker): global motion stats need to be handled per-tile
        // to be compatible with tile-based threading.
549
        update_global_motion_used(mbmi->mode, bsize, mbmi, rdc);
550
551
552
553
554
555
556
      } else {
        const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
        const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
        int idx, idy;
        for (idy = 0; idy < 2; idy += num_4x4_h) {
          for (idx = 0; idx < 2; idx += num_4x4_w) {
            const int j = idy * 2 + idx;
557
            update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi, rdc);
558
559
560
          }
        }
      }
561
562
563
      if (cm->interp_filter == SWITCHABLE &&
          mbmi->motion_mode != WARPED_CAUSAL &&
          !is_nontrans_global_motion(xd)) {
564
#if CONFIG_DUAL_FILTER
565
566
        update_filter_type_count(tile_data->allow_update_cdf, td->counts, xd,
                                 mbmi);
567
#else
568
        (void)tile_data;
569
        const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
570
571
572
        const InterpFilter filter =
            av1_extract_interp_filter(mbmi->interp_filters, 0);
        ++td->counts->switchable_interp[switchable_ctx][filter];
573
#endif
Jingning Han's avatar
Jingning Han committed
574
575
576
577
578
579
580
581
      }
    }

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

582
583
584
  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);
585
586
587
588
589
590
591

#if CONFIG_JNT_COMP
  if (has_second_ref(mbmi)) {
    const int comp_index_ctx = get_comp_index_context(cm, xd);
    ++td->counts->compound_index[comp_index_ctx][mbmi->compound_idx];
  }
#endif  // CONFIG_JNT_COMP
Jingning Han's avatar
Jingning Han committed
592
593
}

594
#if NC_MODE_INFO
595
596
597
598
static void set_mode_info_b(const AV1_COMP *const cpi, TileDataEnc *tile_data,
                            ThreadData *td, int mi_row, int mi_col,
                            BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
  const TileInfo *const tile = &tile_data->tile_info;
599
  MACROBLOCK *const x = &td->mb;
600
  set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
601
  update_state(cpi, tile_data, td, ctx, mi_row, mi_col, bsize, 1);
602
603
}

604
static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
605
                             TileDataEnc *tile_data, TOKENEXTRA **tp,
606
607
                             int mi_row, int mi_col, BLOCK_SIZE bsize,
                             PC_TREE *pc_tree) {
608
  const AV1_COMMON *const cm = &cpi->common;
609
610
611
612
613
614
615
  const int hbs = mi_size_wide[bsize] / 2;
  const PARTITION_TYPE partition = pc_tree->partitioning;
  BLOCK_SIZE subsize = get_subsize(bsize, partition);
#if CONFIG_EXT_PARTITION_TYPES
  const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
  const int quarter_step = mi_size_wide[bsize] / 4;
#endif
616

617
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
618
619
620

  switch (partition) {
    case PARTITION_NONE:
621
622
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
                      &pc_tree->none);
623
624
      break;
    case PARTITION_VERT:
625
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
626
                      &pc_tree->vertical[0]);
627
      if (mi_col + hbs < cm->mi_cols) {
628
        set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, subsize,
629
                        &pc_tree->vertical[1]);
630
631
632
      }
      break;
    case PARTITION_HORZ:
633
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
634
                      &pc_tree->horizontal[0]);
635
      if (mi_row + hbs < cm->mi_rows) {
636
        set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, subsize,
637
                        &pc_tree->horizontal[1]);
638
639
640
      }
      break;
    case PARTITION_SPLIT:
641
      set_mode_info_sb(cpi, td, tile_data, tp, mi_row, mi_col, subsize,
642
                       pc_tree->split[0]);
643
      set_mode_info_sb(cpi, td, tile_data, tp, mi_row, mi_col + hbs, subsize,
644
                       pc_tree->split[1]);
645
      set_mode_info_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col, subsize,
646
                       pc_tree->split[2]);
647
648
      set_mode_info_sb(cpi, td, tile_data, tp, mi_row + hbs, mi_col + hbs,
                       subsize, pc_tree->split[3]);
649
      break;
650
#if CONFIG_EXT_PARTITION_TYPES
651
#if CONFIG_EXT_PARTITION_TYPES_AB
652
#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
653
#endif
654
    case PARTITION_HORZ_A:
655
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, bsize2,
656
                      &pc_tree->horizontala[0]);
657
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, bsize2,
658
                      &pc_tree->horizontala[1]);
659
      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, subsize,
660
                      &pc_tree->horizontala[2]);
661
662
      break;
    case PARTITION_HORZ_B:
663
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
664
                      &pc_tree->horizontalb[0]);
665
      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, bsize2,
666
                      &pc_tree->horizontalb[1]);
667
      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col + hbs, bsize2,
668
                      &pc_tree->horizontalb[2]);
669
670
      break;
    case PARTITION_VERT_A:
671
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, bsize2,
672
                      &pc_tree->verticala[0]);
673
      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col, bsize2,
674
                      &pc_tree->verticala[1]);
675
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, subsize,
676
                      &pc_tree->verticala[2]);
677
678
      break;
    case PARTITION_VERT_B:
679
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col, subsize,
680
                      &pc_tree->verticalb[0]);
681
      set_mode_info_b(cpi, tile_data, td, mi_row, mi_col + hbs, bsize2,
682
                      &pc_tree->verticalb[1]);
683
      set_mode_info_b(cpi, tile_data, td, mi_row + hbs, mi_col + hbs, bsize2,
684
                      &pc_tree->verticalb[2]);
685
      break;
686
687
688
689
    case PARTITION_HORZ_4:
      for (int i = 0; i < 4; ++i) {
        int this_mi_row = mi_row + i * quarter_step;
        if (i > 0 && this_mi_row >= cm->mi_rows) break;
690

691
        set_mode_info_b(cpi, tile_data, td, this_mi_row, mi_col, subsize,
692
693
694
695
696
697
698
                        &pc_tree->horizontal4[i]);
      }
      break;
    case PARTITION_VERT_4:
      for (int i = 0; i < 4; ++i) {
        int this_mi_col = mi_col + i * quarter_step;
        if (i > 0 && this_mi_col >= cm->mi_cols) break;
699

700
        set_mode_info_b(cpi, tile_data, td, mi_row, this_mi_col, subsize,
701
702
703
                        &pc_tree->vertical4[i]);
      }
      break;
Yue Chen's avatar
Yue Chen committed
704
705
706
707
#endif  // CONFIG_EXT_PARTITION_TYPES
    default: assert(0 && "Invalid partition type."); break;
  }
}
Yue Chen's avatar
Yue Chen committed
708
#endif
Yue Chen's avatar
Yue Chen committed
709

Yaowu Xu's avatar
Yaowu Xu committed
710
711
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
                          int mi_row, int mi_col) {
712
713
714
715
716
717
  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
718
719
720
721
722
723
  int i;

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

  for (i = 0; i < MAX_MB_PLANE; i++)
724
725
    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,
726
                     x->e_mbd.plane[i].subsampling_x,
Jingning Han's avatar
Jingning Han committed
727
728
729
                     x->e_mbd.plane[i].subsampling_y);
}

730
static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
731
                              int8_t segment_id) {
Jingning Han's avatar
Jingning Han committed
732
  int segment_qindex;
733
  const AV1_COMMON *const cm = &cpi->common;
Yaowu Xu's avatar
Yaowu Xu committed
734
735
736
737
  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
738
739
}

740
#if CONFIG_DIST_8X8
Yushin Cho's avatar
Yushin Cho committed
741
742
743
static void dist_8x8_set_sub8x8_dst(MACROBLOCK *const x, uint8_t *dst8x8,
                                    BLOCK_SIZE bsize, int bw, int bh,
                                    int mi_row, int mi_col) {
Yushin Cho's avatar
Yushin Cho committed
744
745
746
747
748
749
750
751
752
  MACROBLOCKD *const xd = &x->e_mbd;
  struct macroblockd_plane *const pd = &xd->plane[0];
  const int dst_stride = pd->dst.stride;
  uint8_t *dst = pd->dst.buf;

  assert(bsize < BLOCK_8X8);

  if (bsize < BLOCK_8X8) {
    int i, j;
753
754
755
756
#if CONFIG_HIGHBITDEPTH
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
      uint16_t *dst8x8_16 = (uint16_t *)dst8x8;
      uint16_t *dst_sub8x8 = &dst8x8_16[((mi_row & 1) * 8 + (mi_col & 1)) << 2];
Yushin Cho's avatar
Yushin Cho committed
757

758
759
760
761
762
763
764
765
766
767
768
769
770
      for (j = 0; j < bh; ++j)
        for (i = 0; i < bw; ++i)
          dst_sub8x8[j * 8 + i] = CONVERT_TO_SHORTPTR(dst)[j * dst_stride + i];
    } else {
#endif
      uint8_t *dst_sub8x8 = &dst8x8[((mi_row & 1) * 8 + (mi_col & 1)) << 2];

      for (j = 0; j < bh; ++j)
        for (i = 0; i < bw; ++i)
          dst_sub8x8[j * 8 + i] = dst[j * dst_stride + i];
#if CONFIG_HIGHBITDEPTH
    }
#endif
Yushin Cho's avatar
Yushin Cho committed
771
772
  }
}
773
#endif  // CONFIG_DIST_8X8
Yushin Cho's avatar
Yushin Cho committed
774

775
static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
776
                             MACROBLOCK *const x, int mi_row, int mi_col,
Angie Chiang's avatar
Angie Chiang committed
777
                             RD_STATS *rd_cost,
778
779
#if CONFIG_EXT_PARTITION_TYPES
                             PARTITION_TYPE partition,
780
#endif
Jingning Han's avatar
Jingning Han committed
781
782
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
783
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
784
785
786
787
788
789
790
791
  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
792
  aom_clear_system_state();
Jingning Han's avatar
Jingning Han committed
793
794
795
796

  set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
  mbmi = &xd->mi[0]->mbmi;
  mbmi->sb_type = bsize;
797
798
799
800
#if CONFIG_RD_DEBUG
  mbmi->mi_row = mi_row;
  mbmi->mi_col = mi_col;
#endif
801
802
803
#if CONFIG_EXT_PARTITION_TYPES
  mbmi->partition = partition;
#endif
Jingning Han's avatar
Jingning Han committed
804
805

  for (i = 0; i < MAX_MB_PLANE; ++i) {
806
807
808
809
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    pd[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
810
811
812
#if CONFIG_LV_MAP
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif
Jingning Han's avatar
Jingning Han committed
813
  }
hui su's avatar
hui su committed
814

815
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
816
817
818
#if CONFIG_MRC_TX
  xd->mrc_mask = ctx->mrc_mask;
#endif  // CONFIG_MRC_TX
hui su's avatar
hui su committed
819

Jingning Han's avatar
Jingning Han committed
820
821
822
823
824
  ctx->skippable = 0;

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

825
  x->skip_chroma_rd =
826
827
      !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y);
828

829
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
830
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
831
    x->source_variance = av1_high_get_sby_perpixel_variance(
832
        cpi, &x->plane[0].src, bsize, xd->bd);
Jingning Han's avatar
Jingning Han committed
833
834
  } else {
    x->source_variance =
Yaowu Xu's avatar
Yaowu Xu committed
835
        av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Jingning Han's avatar
Jingning Han committed
836
837
838
  }
#else
  x->source_variance =
Yaowu Xu's avatar
Yaowu Xu committed
839
      av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
840
#endif  // CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
841
842
843
844
845

  // 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
846
    if (cpi->vaq_refresh) {
Yaowu Xu's avatar
Yaowu Xu committed
847
848
849
      const int energy =
          bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
      mbmi->segment_id = av1_vaq_segment_id(energy);
850
      // Re-initialise quantiser
Yaowu Xu's avatar
Yaowu Xu committed
851
      av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Jingning Han's avatar
Jingning Han committed
852
853
854
855
856
857
    }
    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
858
    if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xu's avatar
Yaowu Xu committed
859
      x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
860
861
862
863
864
  }

  // 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
865
    av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Jingning Han's avatar
Jingning Han committed
866
  } else {
867
868
869
    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
870
    } else {
871
872
      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
873
874
875
876
    }
  }

  // Examine the resulting rate and for AQ mode 2 make a segment choice.
877
878
879
  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
880
       cpi->refresh_alt2_ref_frame ||
Jingning Han's avatar
Jingning Han committed
881
       (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xu's avatar
Yaowu Xu committed
882
    av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Jingning Han's avatar
Jingning Han committed
883
884
885
886
887
888
  }

  x->rdmult = orig_rdmult;

  // TODO(jingning) The rate-distortion optimization flow needs to be
  // refactored to provide proper exit/return handle.
889
  if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
Jingning Han's avatar
Jingning Han committed
890
891
892
893
894

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

895
static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
896
897
                                    int16_t mode_context) {
  int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
898
899
900
901
902
  if (mode == NEWMV) {
    ++counts->newmv_mode[mode_ctx][0];
    return;
  } else {
    ++counts->newmv_mode[mode_ctx][1];
903
904
905
906
907

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

Sarah Parker's avatar
Sarah Parker committed
908
909
    mode_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
    if (mode == GLOBALMV) {
910
911
912
913
      ++counts->zeromv_mode[mode_ctx][0];
      return;
    } else {
      ++counts->zeromv_mode[mode_ctx][1];
914
      mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
915

916
917
918
      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;
919

920
921
922
923
924
      ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
    }
  }
}

925
926
static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
                         ThreadData *td, int mi_row, int mi_col) {
927
928
  MACROBLOCK *x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han's avatar
Jingning Han committed
929
930
931
932
  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;
933
  FRAME_CONTEXT *fc = xd->tile_ctx;
934
  const uint8_t allow_update_cdf = tile_data->allow_update_cdf;
Jingning Han's avatar
Jingning Han committed
935

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

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

  if (!seg_ref_active) {
    const int skip_ctx = av1_get_skip_context(xd);
    td->counts->skip[skip_ctx][mbmi->skip]++;
#if CONFIG_NEW_MULTISYMBOL
947
    if (allow_update_cdf) update_cdf(fc->skip_cdfs[skip_ctx], mbmi->skip, 2);
948
949
950
#endif  // CONFIG_NEW_MULTISYMBOL
  }