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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  // 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
274
275
276
277
278
  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
279

Jingning Han's avatar
Jingning Han committed
280
  set_plane_n4(xd, mi_width, mi_height);
281

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

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

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

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

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

316
317
  mbmi->segment_id = 0;

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

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

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

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

399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
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;
      }
    }
  }
}

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

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

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

470
471
472
473
#if CONFIG_DUAL_FILTER
  reset_intmv_filter_type(cm, xd, mbmi);
#endif

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

Jingning Han's avatar
Jingning Han committed
479
480
481
482
  // 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) {
483
484
      const uint8_t *const map =
          seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
Zoe Liu's avatar
Zoe Liu committed
485
486
      mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
      reset_tx_size(xd, mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
487
488
489
490
    }
    // Else for cyclic refresh mode update the segment map, set the segment id
    // and then update the quantizer.
    if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Zoe Liu's avatar
Zoe Liu committed
491
492
493
      av1_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize,
                                        ctx->rate, ctx->dist, x->skip);
      reset_tx_size(xd, mbmi, cm->tx_mode);
Jingning Han's avatar
Jingning Han committed
494
495
496
    }
  }

497
498
499
500
501
  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];
502
503
504
#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
505
  }
506
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Jingning Han's avatar
Jingning Han committed
507
508
509
510
  // 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++)
511
512
      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
513
514
515
        xd->mi[x_idx + y * mis] = mi_addr;
      }

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

  x->skip = ctx->skip;
524

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
589
590
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
                          int mi_row, int mi_col) {
591
592
593
594
595
596
  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
597
598
599
600
601
602
  int i;

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

  for (i = 0; i < MAX_MB_PLANE; i++)
603
604
    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,
605
                     x->e_mbd.plane[i].subsampling_x,
Jingning Han's avatar
Jingning Han committed
606
607
608
                     x->e_mbd.plane[i].subsampling_y);
}

609
static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
610
                              int8_t segment_id) {
Jingning Han's avatar
Jingning Han committed
611
  int segment_qindex;
612
  const AV1_COMMON *const cm = &cpi->common;
Yaowu Xu's avatar
Yaowu Xu committed
613
614
615
616
  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
617
618
}

619
static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
620
                             MACROBLOCK *const x, int mi_row, int mi_col,
Angie Chiang's avatar
Angie Chiang committed
621
                             RD_STATS *rd_cost,
622
623
#if CONFIG_EXT_PARTITION_TYPES
                             PARTITION_TYPE partition,
624
#endif
Jingning Han's avatar
Jingning Han committed
625
626
                             BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
                             int64_t best_rd) {
627
  const AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
628
629
630
631
632
633
634
635
  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
636
  aom_clear_system_state();
Jingning Han's avatar
Jingning Han committed
637
638
639
640

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

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

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

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

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

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

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
679
680
681
  }

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

  // 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)) {
701
702
    av1_rd_pick_intra_mode_sb(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx,
                              best_rd);
Jingning Han's avatar
Jingning Han committed
703
  } else {
704
705
706
    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
707
    } else {
708
709
      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
710
711
712
713
    }
  }

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

  x->rdmult = orig_rdmult;

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

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

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

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

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

753
754
755
      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;
756

757
758
759
760
761
      ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
    }
  }
}

762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
                            const MODE_INFO *mi, const MODE_INFO *above_mi,
                            const MODE_INFO *left_mi, const int intraonly,
                            const int mi_row, const int mi_col,
                            uint8_t allow_update_cdf) {
  FRAME_CONTEXT *fc = xd->tile_ctx;
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
  const PREDICTION_MODE y_mode = mbmi->mode;
  const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
  (void)counts;
  const BLOCK_SIZE bsize = mbmi->sb_type;

  // Update intra tx size cdf
  if (block_signals_txsize(bsize) && !xd->lossless[mbmi->segment_id] &&
      allow_update_cdf) {
    const TX_SIZE tx_size = mbmi->tx_size;
778
    const int tx_size_ctx = get_tx_size_context(xd, 0);
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
    const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize, 0);
    const int depth = tx_size_to_depth(tx_size, bsize, 0);
    const int max_depths = bsize_to_max_depth(bsize, 0);
    update_cdf(fc->tx_size_cdf[tx_size_cat][tx_size_ctx], depth,
               max_depths + 1);
  }

  if (intraonly) {
#if CONFIG_ENTROPY_STATS
    const PREDICTION_MODE above = av1_above_block_mode(above_mi);
    const PREDICTION_MODE left = av1_left_block_mode(left_mi);
#if CONFIG_KF_CTX
    int above_ctx = intra_mode_context[above];
    int left_ctx = intra_mode_context[left];
    ++counts->kf_y_mode[above_ctx][left_ctx][y_mode];
#else
    ++counts->kf_y_mode[above][left][y_mode];
#endif
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf)
      update_cdf(get_y_mode_cdf(fc, above_mi, left_mi), y_mode, INTRA_MODES);
  } else {
#if CONFIG_ENTROPY_STATS
    ++counts->y_mode[size_group_lookup[bsize]][y_mode];
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf)
      update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
  }

#if CONFIG_FILTER_INTRA
  if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0 &&
      av1_filter_intra_allowed_txsize(mbmi->tx_size)) {
    const int use_filter_intra_mode =
        mbmi->filter_intra_mode_info.use_filter_intra;
#if CONFIG_ENTROPY_STATS
    ++counts->filter_intra_tx[mbmi->tx_size][use_filter_intra_mode];
    if (use_filter_intra_mode) {
      ++counts
            ->filter_intra_mode[mbmi->filter_intra_mode_info.filter_intra_mode];
    }
#endif  // CONFIG_ENTROPY_STATS
    if (allow_update_cdf) {
      if (use_filter_intra_mode)
        update_cdf(fc->filter_intra_mode_cdf,
                   mbmi->filter_intra_mode_info.filter_intra_mode,
                   FILTER_INTRA_MODES);
      update_cdf(fc->filter_intra_cdfs[mbmi->tx_size], use_filter_intra_mode,
                 2);
    }
  }
#endif  // CONFIG_FILTER_INTRA
#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
  if (av1_is_directional_mode(mbmi->mode, bsize) &&
      av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
    ++counts->angle_delta[mbmi->mode - V_PRED]
                         [mbmi->angle_delta[0] + MAX_ANGLE_DELTA];
#endif
    if (allow_update_cdf)
      update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
                 mbmi->angle_delta[0] + MAX_ANGLE_DELTA,
                 2 * MAX_ANGLE_DELTA + 1);
  }
#endif  // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD

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

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

  if (mbmi->mode == DC_PRED) {
    const int n = pmi->palette_size[0];
    int palette_y_mode_ctx = 0;
    if (above_mi) {
      palette_y_mode_ctx +=
          (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    }
    if (left_mi) {
      palette_y_mode_ctx +=
          (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    }
    update_cdf(fc->palette_y_mode_cdf[bsize_ctx][palette_y_mode_ctx], n > 0, 2);
  }

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

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

922
  // delta quant applies to both intra and inter
923
924
  const int super_block_upper_left = ((mi_row & (cm->mib_size - 1)) == 0) &&
                                     ((mi_col & (cm->mib_size - 1)) == 0);
925

926
927
928
  const int seg_ref_active =
      segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);

Zoe Liu's avatar
Zoe Liu committed
929
930
931
932
933
934
#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);
935
936
  }

Zoe Liu's avatar
Zoe Liu committed
937
938
939
940
941
942
943
944
945
946
947
  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

948
  if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
949
950
951
952
      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;
953
    for (i = 0; i < AOMMIN(absdq, DELTA_Q_SMALL); ++i) {
954
955
956
957
      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
958
#if CONFIG_EXT_DELTA_Q
959
960
#if CONFIG_LOOPFILTER_LEVEL
    if (cm->delta_lf_present_flag) {
961
962
963
964
965
966
967
968
969
970
971
972
973
974
      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 {
975
        const int delta_lf =
976
            (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
977
978
979
            cm->delta_lf_res;
        const int abs_delta_lf = abs(delta_lf);
        for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
980
          td->counts->delta_lf[i][1]++;
981
982
        }
        if (abs_delta_lf < DELTA_LF_SMALL)
983
984
          td->counts->delta_lf[abs_delta_lf][0]++;
        xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
985
986
987
      }
    }
#else
Fangwen Fu's avatar
Fangwen Fu committed
988
989
990
991
992
993
994
995
996
997
998
    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;
    }
999
#endif  // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu's avatar
Fangwen Fu committed
1000
#endif
For faster browsing, not all history is shown. View entire blame